首页 > 解决方案 > 如何使用 Docker Compose 将子项目复制到多容器 Docker 应用程序中的容器?

问题描述

我想用 docker compose 构建一个多容器 docker 应用程序。我的项目结构如下所示:

docker-compose.yml
...
webapp/
   ...
   Dockerfile
api/
   ...
   Dockerfile

目前,我只是尝试使用正确的构建上下文构建和运行webappvia 。docker compose up直接通过构建webapp容器时docker build,一切运行顺利。

docker-compose.yml但是,根据我在行COPY . /webapp/中的当前规范webapp/Dockerfile(见下文)将整个父项目复制到容器,即包含 的目录docker-compose.yml,而不仅仅是webapp/子目录。由于某种原因,这条线COPY requirements.txt /webapp/按预期工作。

在中指定构建上下文的正确方法是docker compose什么?为什么.Dockerfile 解释中的 是相对于 的docker-compose.yml,而requirements.txt是相对于Dockerfile预期的?我错过了什么?

以下是 的内容docker-compose.yml

version: "3.8"

services:
  frontend:
    container_name: "pc-frontend"
    volumes:
        - .:/webapp
    env_file:
      - ./webapp/.env
    build:
      context: ./webapp
    ports:
      - 5000:5000

webapp/Dockerfile

FROM python:3.9-slim

# set environment variables
ENV PYTHONWRITEBYTECODE 1
ENV PYTHONBUFFERED 1

# set working directory
WORKDIR /webapp

# copy dependencies
COPY requirements.txt /webapp/

# install dependencies
RUN pip install -r requirements.txt

# copy project
COPY . /webapp/  # does not work as intended

# add entrypoint to app
# ENTRYPOINT ["start-gunicorn.sh"]

CMD [ "ls", "-la" ]  # for debugging

# expose port
EXPOSE 5000

标签: dockerdocker-composedockerfile

解决方案


COPY指令(可能)按您期望的方式工作。但是,您volumes:正在用其他内容覆盖图像内容。删除volumes:块。

映像构建顺序完全按照您的预期工作。 build: { context: ./webapp }使用webapp子目录作为构建上下文并将其发送到 Docker 守护进程。例如,当 DockerfileCOPY requirements.txt .来自此目录时。例如,如果您,docker-compose run frontend pip freeze您应该会看到已安装的 Python 包。

镜像构建完成后,Compose 会启动一个容器,并在此时volumes:生效。当你说 时volumes: ['.:/webapp'],这里的.冒号前面是指包含docker-compose.yml文件的目录(而不是webapp子目录),然后它会隐藏容器中/webapp目录中的所有内容。因此,您正在用主机上的当前目录(更高的一个目录)替换图像/webapp(已从webapp子目录构建)。

您通常应该能够成功地结合一个普通的基于主机的开发环境和一个 Docker 部署设置。使用非 Docker Python 虚拟环境构建应用程序并运行其单元测试,然后用于docker-compose up --build运行集成测试和完整的应用程序。通过这样的设置,您无需在开发时处理 Python 运行时在“其他地方”的不便,并且可以安全地删除该volumes:块。


推荐阅读