我希望能够为自己创建的 docker 镜像添加一些额外的要求。我的策略是使用 CMD 命令从 dockerfile 构建镜像,该命令将在运行时使用安装的卷执行“pip install -r”命令。

这是我的 dockerfile:

FROM ubuntu:14.04

RUN apt-get update
RUN apt-get install -y python-pip python-dev build-essential
RUN pip install --upgrade pip

WORKDIR /root

CMD ["pip install -r /root/sourceCode/requirements.txt"]

有了那个 dockerfile 我构建了图像:
sudo docker build -t test .

最后,我尝试使用以下命令附加我的新要求:
sudo docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash

我的本地文件夹“sourceCode”中有一个有效的 requirements.txt 文件(它只包含一个值为“gunicorn”的行)。
当我收到提示时,我可以看到需求文件在那里,但是如果我执行 pip freeze 命令,则不会列出 gunicorn 包。

为什么requirements.txt文件被正确附加但pip命令无法正常工作?

最佳答案

TLDR
pip 命令没有运行,因为你告诉 Docker 运行 /bin/bash 代替。

docker run -v $(pwd)/sourceCode:/root/sourceCode -it test /bin/bash
                                                              ^
                                                             here

更长的解释

容器的默认 ENTRYPOINT/bin/sh -c 。您不会在 Dockerfile 中覆盖它,因此它仍然存在。默认的 CMD 指令可能什么都没有。您确实在 Dockerfile 中覆盖了它。运行时(为了简洁,忽略音量)
docker run -it test

容器内实际执行的是
/bin/sh -c pip install -r /root/sourceCode/requirements.txt

非常简单,当您启动容器时,它看起来会运行 pip

现在让我们看看你用来启动容器的命令(再次忽略卷)
docker run -v -it test /bin/bash

容器内实际执行的是
/bin/sh -c /bin/bash

您在 Dockerfile 中指定的 CMD 参数会被您在命令行中指定的 COMMAND 覆盖。回想一下 docker run command takes this form
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]

进一步阅读
  • This answerCMDENTRYPOINT 指令的作用进行了非常中肯的解释

  • blog post 关于ENTRYPOINTCMD指令的区别,值得一读。
  • 关于python - 在运行时向 docker 镜像添加 pip 要求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40534274/

    10-16 13:53