我有一个本地项目目录结构,例如:
config
test
docker-compose.yaml
DockerFile
pip-requirements.txt
src
app
app.py
我正在尝试使用Docker启动一个容器来运行app.py。概念简单,但是事实证明这非常困难。我打算将Docker文件保存在一个单独的子文件夹中,因为我打算在许多不同的环境中使用,并且我不想在顶层文件夹中堆满Dockerfile.1
,{ {1}},等等。
我的docker-compose.yaml如下:
Dockerfile.2
我的Dockerfile看起来像:
version: '3'
services:
worker:
image: myname:mytag
build:
context: .
dockerfile: ./Dockerfile
volumes:
- ./src/app:/usr/local/myproject/src/app
如果我从项目的顶级目录运行:
FROM python:2.7
# Set the working directory.
WORKDIR /usr/local/myproject/src/app
# Copy the current directory contents into the container.
COPY src/app /usr/local/myproject/src/app
COPY pip-requirements.txt pip-requirements.txt
# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r pip-requirements.txt
# Define environment variable
ENV PYTHONUNBUFFERED 1
CMD ["./app.py"]
它可以成功构建映像,但是在尝试运行带有错误的映像时失败:
docker-compose -f config/test/docker-compose.yaml up
如果我使用以下方法检查图像的文件系统:
ERROR: for worker Cannot start service worker: OCI runtime create failed: container_linux.go:345: starting container process caused "exec: \"./app.py\": stat ./app.py: no such file or directory": unknown
它正确地将我转储到docker run --rm -it --entrypoint=/bin/bash myname:mytag
中。但是,此目录为空,解释了运行时错误。为什么这是空的? /usr/local/myproject/src/app
语句和COPY
是否应该用我的应用程序代码填充图像?
答案 0 :(得分:1)
首先,您要通过在构建阶段添加内容来破坏数据集,然后使用docker-compose在其之上覆盖目录。让我们首先讨论Dockerfile(图像)和Docker-compose(运行时)之间的区别
通常,您将在dockerfile中使用COPY
指令将本地目录的组件复制到映像中,从而使其成为不可变。在大多数应用程序部署中,这意味着我们将整个应用程序捆绑到目录中并准备运行。这意味着它不是动态的(在容器中不可见之后对代码所做的平均更改),但是在安全性方面却有所收获。
Docker-compose是 runtime 规范,其含义是:“一旦有了映像,我就需要以编程方式定义其运行方式”。通过在此处定义卷,您说的是“我希望将本地目录(从撰写文件的角度来看)/src/app
覆盖到/usr/local/myproject/src/app
因此,您内置在图像中的任何内容都没有关系。您将在图像之上添加另一层,它将优先于图像中内置的内容。
也可能与您已经指定Workdir,然后在CMD中指定./引用有关。只需尝试CMD ["app.py"]
如果您会发生什么
docker build -t "test" .
"docker run --rm -it test