泊坞窗:构建映像后没有此类文件或目录

时间:2019-01-04 11:00:51

标签: docker dockerfile

我刚刚开始阅读本教程,并尝试将我的一些代码包装到docker中。这个问题对于您中的许多人来说可能听起来很耳熟,因为我可以看到非常相似的威胁,但是不幸的是我无法理解,所以决定在这里写下。

我使用python创建了一个电报聊天机器人。所有文件都位于/project/下。我在/project/ calledDockerTelegramChatBot下有另一个文件夹,其中有Dockerfile。

DockerTelegramChatbot内,我有两个文件Dockerfilerequirements.txt

Dockerfile的内容如下所示

# Use an official Python runtime as a parent image
FROM python:3.6-stretch

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app
ADD . .

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt --default-timeout=100

# Make port 80 available to the world outside this container
EXPOSE 80

# Run app.py when the container launches
CMD pwd

CMD ls
CMD python /app/main_bot.py

我使用

构建图像
docker build -t simpletelegramchatbot DockerTelegramChatBot/

并使用

运行它
docker run -p 4000:80 simpletelegramchatbot

主要问题是如何解决“构建映像后没有此类文件或目录”的问题。但是,我也想知道解决这种情况的最佳实践是什么,如果我编辑dockerfile,是否每次都要从头开始构建它? “ pip安装要求”需要几分钟,并使整个过程变得很烦人。

2 个答案:

答案 0 :(得分:1)

问::是否每次都要从头开始构建它? “ pip安装要求”需要几分钟,并使整个过程变得很烦人。

A:您可以使用已经预安装的所有python程序构建基础docker image。然后,在实际程序的Dockerfile中,您会说FROM xyz_img,其中xyz_img是您构建的基本映像。从本质上讲,这将避免再次经历耗时的pip install

问::如何解决“构建映像后没有此类文件或目录”的问题

A :可以肯定有很多调试技巧。对我来说,最简单的方法是使您的docker容器保持活动状态并连接到其中以检查其中的目录。

连接,您可以执行:docker exec -it CONTAINER_NAME bash

要使运行中的容器保持活动状态,最适合您的用例的可能是编写永不退出的python程序。例如。睡一分钟醒来,然后再睡一分钟。

答案 1 :(得分:0)

  

主要问题是如何解决“构建映像后没有此类文件或目录”的问题。

已经构建了一个映像,可以直接基于该映像启动一个容器,该容器运行一个交互式shell,而不是Dockerfile中的CMD:

docker run --rm -it simpletelegramchatbot bash

(注意:如果您常规使用ENTRYPOINT而不是CMD,则此命令行不起作用,这是我建议将CMD设置为默认值的两个原因之一。)

在运行docker build时,每一步之后的输出还将包含一个长十六进制数。这些是有效的映像ID,例如,您可以在docker run命令中使用这些ID,例如,通过在COPY步骤之后立即构建的中间映像上获取一个shell,来查看生成中间的情况。

在描述项目布局时,听起来像是:

/project/
+-- main_bot.py
\-- DockerTelegramChatBot/
  +-- Dockerfile
  \-- requirements.txt

因此,当您运行docker build DockerTelegramChatBot时,它仅 会看到该子目录,如果您查看生成的映像,则可能只会看到requirements.txt文件。由于内部构建机制的原因,Docker实际上不可能访问父目录中的文件。解决这个问题非常简单:只需将两个文件移至父目录即可。

  

如果我编辑dockerfile,是否每次都要从头开始构建它? “ pip安装要求”需要几分钟的时间

是;但是,如果先前的docker build从相同的映像开始并运行相同的命令,则Docker将跳过一个步骤。这称为层缓存。至关重要的是,如果其中涉及的任何文件发生更改,则任何COPY或ADD步骤都将中断层缓存。

一种非常常见的模式是复制少量文件,这些文件描述了如何获取需求(requirements.txtpackage.jsonGemfile,...),安装需求,然后安装其余的源代码。如果pip install文件更改,这将导致Docker仅重新运行requirements.txt步骤。您的Dockerfile可能如下所示:

FROM python:3.6-stretch
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt --default-timeout=100
COPY . ./
EXPOSE 80
CMD ["./main_bot.py"]