容器内文件系统的更改未反映在docker卷中的主机上

问题描述 投票:0回答:1

我正在使用TypeScript编写的Express服务器。项目的流程是我有一个npm构建脚本,它将项目文件放在src文件夹中并将它们编译到dist文件夹中。这两个文件夹都位于根目录下。该项目有效,但在尝试将所有内容移动到docker时,虽然我正在安装卷,并且容器中存在构建的文件(dist目录),但更改不会反映在主机上。 (我使用Windows + VirtualBox for Docker)

我提到了thisthis问题。我看到他们的情况是一样的,但他们的解决方案似乎对我不起作用。我确信我使用的答案中提到的类似技术,它们似乎不起作用。

项目目录结构:

├── 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

当服务器启动时,它会在%proj_root%/Backend/dist中创建一个名为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

这是后端服务的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"]

在运行docker-compose up时,应该在容器(/app/dist)中创建一个dist文件夹,并且应该在主机上反映为%proj_root%/Backend/dist

我知道我可以创建一个编译TS然后运行docker-compose的脚本,但这看起来像是一个hacky方法。有更好的解决方案吗?

docker docker-compose
1个回答
2
投票

你展示的docker-compose.yml设置有两个独立的东西。首先,它使用你单独提供的Dockerfile构建一个Docker镜像。其次,它采用该图像,安装卷并应用其他设置,并根据这些设置运行容器。 Docker镜像构建序列忽略所有这些其他设置;您在Dockerfile中所做的任何事情都无法更改主机系统上的文件。

当您运行容器时,传入的volumes:设置中的任何内容都完全取代了该图像的内容。这总是单向“推入容器”:主机的Backend目录中的内容替换容器中的/app;匿名卷的内容替换其node_modules,主机的list目录的内容替换/app/dist

这有一个特殊情况例外。启动容器时,如果卷装入为空,则映像中的内容将复制到卷中。只有在卷树中根本没有任何内容时才会发生这种情况。如果dist主机目录或node_modules匿名卷中已有内容,则会替换图像中的任何内容,即使它在图像中发生了更改(或在卷中更改,Docker也无法分辨)。

作为一次性解决方案,如果你

rm -rf dist

然后在下次启动容器时,Docker会注意到dist目录为空并从图像中重新填充它。

我建议完全删除这些volumes:设置。如果您正在积极开发软件,请在主机上执行:使用典型的操作系统软件包管理器非常容易安装节点,您的IDE不会被您的节点解释器隐藏在容器中而感到困惑,并且您不会遇到这类问题。当您进行部署时,您可以按原样使用Docker镜像,而无需单独分发也在图像中的代码。

© www.soinside.com 2019 - 2024. All rights reserved.