【问题标题】:Files in a bind-mounted folder seem to disappear after Docker container exitsDocker 容器退出后,绑定安装文件夹中的文件似乎消失了
【发布时间】:2020-11-15 15:38:42
【问题描述】:

我正在使用 docker-compose,我正在尝试了解如何配置我的 node_modules 文件夹。我无法理解文件如何与 Docker 中的卷或绑定挂载一起保存。这是我的项目设置:

user@computer:~/myprojects/deleteme$ tree
.
├── docker-compose.yml
└── frontend
    ├── Dockerfile
    └── package.json

docker-compose.yml

version: '3'

services:
  frontend:
    build: ./frontend
    volumes:
      - ./frontend:/app/frontend
    container_name: frontend

Dockerfile

FROM node:12-alpine

WORKDIR /app/frontend

RUN npm install

RUN echo "Node done!"
RUN touch foo
RUN ls

package.json

{
  "name": "deleteme",
  "version": "1.1.0",
  "repository": {
    "type": "git"
  },
  "scripts": {
  },
  "dependencies": {
    "npm-run-all": "4.1.5",
    "react": "16.13.1",
    "react-datetime": "2.16.3",
    "react-dom": "16.13.1",
    "react-router": "5.2.0",
    "react-router-dom": "5.2.0",
    "react-scripts": "3.4.1"
  }
}

当我docker-compose build --no-cache 时,我得到了

Building frontend
Step 1/6 : FROM node:12-alpine
 ---> 057fa4cc38c2
Step 2/6 : WORKDIR /app/frontend
 ---> Running in 81229692051b
Removing intermediate container 81229692051b
 ---> 0ef46ff4472d
Step 3/6 : RUN npm install
 ---> Running in cf7afc9d1f54
npm WARN saveError ENOENT: no such file or directory, open '/app/frontend/package.json'
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN enoent ENOENT: no such file or directory, open '/app/frontend/package.json'
npm WARN frontend No description
npm WARN frontend No repository field.
npm WARN frontend No README data
npm WARN frontend No license field.

up to date in 0.227s
found 0 vulnerabilities

Removing intermediate container cf7afc9d1f54
 ---> af6169ff583b
Step 4/6 : RUN echo "Node done!"
 ---> Running in e037c7bbd127
Node done!
Removing intermediate container e037c7bbd127
 ---> 843945701b93
Step 5/6 : RUN touch foo
 ---> Running in fc0663e95e48
Removing intermediate container fc0663e95e48
 ---> 48460f061742
Step 6/6 : RUN ls
 ---> Running in 594b7843bc8b
foo
package-lock.json
Removing intermediate container 594b7843bc8b
 ---> 6d4e09b0ff64
Successfully built 6d4e09b0ff64
Successfully tagged deleteme_frontend:latest

我不明白为什么package.json 还没有在容器的/app/frontend 中,因为我在docker-compose.yml 中指定了./frontend:/app/frontend。而且我不明白为什么foopackage-lock.json 接缝会在容器存在后消失,因为如果我再次使用tree,我会得到

.
├── docker-compose.yml
└── frontend
    ├── Dockerfile
    └── package.json

【问题讨论】:

    标签: docker docker-compose node-modules


    【解决方案1】:

    您正在将文件挂载到容器运行时,显然一旦容器被删除,它将被删除。您必须在构建时添加这些文件(docker build),以便您的应用程序相关文件与图像一起存在,所以您的 dockerfile 应该是这样的

    FROM node:12-alpine
    
    WORKDIR /app/frontend
    
    COPY ./frontend ./          <<---- here
    
    RUN npm install
    
    RUN echo "Node done!"
    RUN touch foo
    RUN ls
    

    【讨论】:

    • 哦,我不知道挂载是在运行时完成的,而不是在构建时完成的。这就解释了为什么package.jsonDockerfile 不可用。这是否解释了为什么foo 消失了——所以Dockerfile 触及了一个尚未安装的目录,所以./frontend:/app/frontend 实际上覆盖了foo
    【解决方案2】:

    这是因为只有在容器运行时才会安装卷,而不是在构建映像时。您需要在Dockerfile 中使用COPY 命令在构建阶段从./frontend 添加文件。示例:

    FROM node:12-alpine
    
    WORKDIR /app/frontend
    COPY frontend ./
    RUN npm install
    

    【讨论】:

    • 有没有办法只挂载整个目录而不是复制?
    • 在构建Dockerfile 期间无法挂载卷。原因之一——构建镜像时,与构建相关的所有内容都必须持久化到镜像 FS。否则,容器可能在启动后无法使用。参见official Docker Hub of Python,例如COPY . .。也有卷使用,但仅适用于没有外部依赖项的脚本(仅限标准库)。对不起,Python 示例,Node.JS Docker Hub 没有详细解释这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-08
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    相关资源
    最近更新 更多