我想用docker compose构建一个多容器docker应用程序。我的项目结构看起来像这样:
docker-compose.yml
...
webapp/
...
Dockerfile
api/
...
Dockerfile
目前,我只是试图通过docker compose up
与正确的构建上下文构建和运行webapp
。当直接通过docker build
构建webapp
容器时,一切都运行顺利。
然而,在docker-compose.yml
中,webapp/Dockerfile
中的COPY . /webapp/
行(见下文)将整个父项目复制到容器中,即包含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
andwebapp/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
COPY
指令(可能)按您期望的方式工作。但是,您有volumes:
用其他东西覆盖图像内容。删除volumes:
块
映像构建序列完全按照您期望的方式工作。build: { context: ./webapp }
使用webapp
子目录作为构建上下文,并将其发送给Docker守护进程。当Dockerfile(例如COPY 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:
块。