如果我在 docker 图像中包含每个文件,为什么我的 docker-compose 应用程序会在另一台机器上抛出有关丢失文件的错误?

Why on another machine my docker-compose app is throwing error about missing files if I included every file in my docker image?

我想问一下 docker-compose 应用程序中的一些我无法理解的错误。我不确定我是否犯了某种代码错误,或者我误解了 docker compose 的整个概念。

以下是我正在做的事情:

  1. 我在笔记本电脑 A 上构建了 docker-compose - 一切正常

  2. 在docker-compose.yml中我把我的图片改成了mynick/myimage:test

  3. 我使用 docker-compose push

    将我的“自定义”图像推送到 docker 集线器
  4. 我将 docker-compose.yml 文件和 .env 文件复制到笔记本电脑 B

  5. 我做了 docker-compose --env-file env up

  6. 每个图像都已从 docker 中心成功下载,我的应用程序已启动

  7. 启动我的应用程序后,我看到有关从我的主应用程序文件夹中丢失文件和目录的错误(其中也有 docker-compose 和 docker 文件,所以它应该已经包含了所有内容?)

我在第 7 步中看到的错误例如是“缺少 alembic.ini 文件”。当我手动将它复制到笔记本电脑 B(位于 docker-compose.yml 的文件夹)时,我看到错误“失败:路径不存在:'/my_app/alembic”

我觉得这很奇怪,因为我的自定义图像有命令“COPY ./my_app”,据我所知,它应该复制图像中的所有文件,所以它应该包含所有文件,并且准确相同的文件夹结构?

此文件夹结构类似于: 我的文件夹结构如下所示:

->my_app
----alembic.ini
---->alembic
-------->versions
------------.keep
--------various_stuff
----main.py
----Dockerfile
----docker-compose.yml
----various_stuff

我的 Dockerfile:

FROM python:3-slim-buster
ENV PYTHONUNBUFFERED=1
WORKDIR /myapp
COPY requirements.txt requirements.txt
RUN pip3 install --upgrade pip
RUN pip3 install -r requirements.txt
COPY . /myapp
CMD 0.0.0.0:$PORT

我的docker-compose.yml:

version: "3.8"

services:
  database:
    container_name: postgresql_db
    image: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}

  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
    ports:
      - "5050:80"
    depends_on:
      - database

  myapp:
    container_name: myapp
    build: .
    image: myapp:main
    command: bash -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000"
    volumes:
      - .:/myapp
    ports:
      - "8000:8000"
    depends_on:
      - database
    restart: always

  migration:
    image: myapp:main
    command: bash -c "alembic revision --autogenerate -m 'New Migration'"
    volumes:
      - .:/myapp
    depends_on:
      - myapp

  upgrade_head:
    image: myapp:main
    command: bash -c "alembic upgrade head"
    volumes:
      - .:/myapp
    depends_on:
      - migration

还有我的docker-compose.yml在其他电脑上改成运行后:

version: "3.8"

services:
  database:
    container_name: postgresql_db
    image: postgres
    restart: always
    ports:
      - "5432:5432"
    environment:
      - POSTGRES_USER=${DB_USER}
      - POSTGRES_PASSWORD=${DB_PASSWORD}
      - POSTGRES_DB=${DB_NAME}

  pgadmin:
    container_name: pgadmin
    image: dpage/pgadmin4
    environment:
      - PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL}
      - PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD}
    ports:
      - "5050:80"
    depends_on:
      - database

  myapp:
    container_name: myapp
    build: .
    image: dockerhubnick/myappimage:latest
    command: bash -c "alembic upgrade head && uvicorn main:app --host 0.0.0.0 --port 8000"
    volumes:
      - .:/myapp
    ports:
      - "8000:8000"
    depends_on:
      - database
    restart: always

  migration:
    image: dockerhubnick/myappimage:latest
    command: bash -c "alembic revision --autogenerate -m 'New Migration'"
    volumes:
      - .:/myapp
    depends_on:
      - myapp

  upgrade_head:
    image: dockerhubnick/myappimage:latest
    command: bash -c "alembic upgrade head"
    volumes:
      - .:/myapp
    depends_on:
      - migration

目前我不确定我是否正在制作一些与代码相关的程序,或者我误解了 docker-compose 的工作原理?

问题出在第二个 docker-compose.yml 文件中的 volume 指令。它正在用本地目录的内容覆盖您复制到图像中的文件。您没有注意到第一台笔记本电脑上的差异,因为本地目录包含与复制到图像中的相同的文件。但是在第二台笔记本电脑上你会得到一个错误,因为项目文件丢失了。

删除第二台笔记本电脑 docker-compose.yml 文件中的 volume 指令,错误应该会消失。如果没有 volume,您复制到图像中的文件将被用作例外。