如何将本地文件系统复制到Docker容器

时间:2019-05-16 20:28:02

标签: docker docker-compose

我有一个本地项目目录结构,例如:

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是否应该用我的应用程序代码填充图像?

1 个答案:

答案 0 :(得分:1)

首先,您要通过在构建阶段添加内容来破坏数据集,然后使用docker-compose在其之上覆盖目录。让我们首先讨论Dockerfile(图像)和Docker-compose(运行时)之间的区别

通常,您将在dockerfile中使用COPY指令将本地目录的组件复制到映像中,从而使其成为不可变。在大多数应用程序部署中,这意味着我们将整个应用程序捆绑到目录中并准备运行。这意味着它不是动态的(在容器中不可见之后对代码所做的平均更改),但是在安全性方面却有所收获。

Docker-compose是 runtime 规范,其含义是:“一旦有了映像,我就需要以编程方式定义其运行方式”。通过在此处定义卷,您说的是“我希望将本地目录(从撰写文件的角度来看)/src/app覆盖到/usr/local/myproject/src/app

因此,您内置在图像中的任何内容都没有关系。您将在图像之上添加另一层,它将优先于图像中内置的内容。

也可能与您已经指定Workdir,然后在CMD中指定./引用有关。只需尝试CMD ["app.py"]

如果您会发生什么

  1. 构建图像:docker build -t "test" .
  2. 手动运行图像:"docker run --rm -it test