met*_*ord 0 docker docker-compose
我正在使用 TypeScript 编写的 Express 服务器。项目的流程是我有一个 npm 构建脚本,它在 src 文件夹中获取项目文件并将它们编译到 dist 文件夹。这两个文件夹都位于根目录下。该项目有效,但是在尝试将所有内容移动到 docker 时,虽然我正在安装卷并且构建的文件(dist 目录)在容器中,但更改并未反映在主机上。(我正在为 Docker 使用 Windows + VirtualBox)
我已经提到了这个和这个问题。我看到他们的场景是一样的,但他们的解决方案似乎对我不起作用。我确保我使用了这些答案中提到的类似技术,它们似乎不起作用。
项目目录结构:
??? Backend
? ??? src/
? ? ??? controllers/
? ? ??? models/
? ? ??? routes/
? ? ??? services/
? ? ??? index.ts
? ? ??? server.ts
? ??? dist/ (Created upon compilation)
? ? ??? controllers/
? ? ??? data/ (Created upon starting the server)
? ? ??? models/
? ? ??? routes/
? ? ??? services/
? ? ??? index.js
? ? ??? server.js
? ??? Dockerfile
? ??? package.json
? ??? tsconfig.json
? ??? tslint.json
? ??? .env
??? Frontend/ (This part is an independent application)
??? docker-compose.yml
??? README.md
Run Code Online (Sandbox Code Playgroud)
当服务器启动时,它会在%proj_root%/Backend/distnamed 中创建一个目录,data用于通过 txt 文件向应用程序提供输入。从我在 Dockerfile 中放入的 ls 命令可以看出,编译工作正常,但是在容器内部所做的更改(创建 dist 目录)并未反映在主机上。在主机上,dist 目录为空,导致服务器崩溃,因为没有 server.js 文件。
这是我的 docker-compose.yml:
version: "3"
services:
backend:
build:
context: ./Backend/
volumes:
- ./Backend/dist:/app/dist
- /app/node_modules
- ./Backend:/app
frontend:
build:
context: ./Frontend
ports:
- "3001:8080"
volumes:
- /app/node_modules
- ./Frontend:/app
Run Code Online (Sandbox Code Playgroud)
这是后端服务的 Dockerfile:
FROM node:8
WORKDIR /app
COPY ./package.json .
RUN npm install
COPY . . # Copying everything to enable standalone usage
RUN ls # Logging before tsc build
RUN npm run build
RUN ls /app/dist # Logging after tsc build. All the built files are visible.
CMD ["npm", "run", "start"]
Run Code Online (Sandbox Code Playgroud)
运行时docker-compose up,应在容器 ( /app/dist) 中创建一个 dist 文件夹,并应在主机上反映为%proj_root%/Backend/dist
我知道我可以创建一个脚本来编译 TS 然后运行 docker-compose,但这对我来说似乎是一种hacky 方法。有更好的解决方案吗?
docker-compose.yml您展示的设置做了两个独立的事情。首先,它构建一个 Docker 镜像,使用Dockerfile你单独提供的。其次,它获取该映像,安装卷并应用其他设置,并基于这些设置运行容器。Docker 镜像构建序列会忽略所有这些其他设置;您在 Dockerfile 中所做的任何事情都无法更改主机系统上的文件。
当您运行容器时,volumes:您传入的设置中的任何内容都会完全替换该图像中的内容。这始终是一种单向“推入容器”:在容器中Backend替换主机目录/app的内容;匿名卷的内容替换其node_modules,主机list目录的内容替换/app/dist。
对此有一种特殊情况。启动容器时,如果卷挂载为空,则映像中的内容将复制到卷中。仅当卷树中完全没有任何内容时才会发生这种情况。如果dist主机目录或node_modules匿名卷中已经有内容,这将替换映像中的任何内容,即使它在映像中发生了变化(或者在卷中发生了变化,Docker 无法判断)。
作为一次性的解决方法,如果您
rm -rf dist
Run Code Online (Sandbox Code Playgroud)
那么下次启动容器时,Docker 会注意到该dist目录为空并从映像中重新填充它。
我建议完全删除这些volumes:设置。如果您正在积极开发软件,请在主机上进行:使用典型的操作系统包管理器安装 Node 非常容易,您的 IDE 不会被隐藏在容器内的 Node 解释器混淆,并且您不会点击这种问题。当您进行部署时,您可以直接使用 Docker 镜像,而无需单独分发镜像内的代码。
| 归档时间: |
|
| 查看次数: |
3053 次 |
| 最近记录: |