将 python 依赖项添加到 Docker 容器的好方法是什么?

What is a good way to add python dependencies to a Docker container?

我正在尝试将 docker 集成到我的 Django 工作流程中,除了一个非常烦人的问题外,我已经设置了所有内容。如果我想将依赖项添加到我的 requirements.txt 文件中,我基本上只需要重建整个容器映像以使这些依赖项得以保留。

例如,我遵循了 django docker-compose 示例 here。 yaml 文件是这样设置的:

db:
  image: postgres
web:
  build: .
  command: python manage.py runserver 0.0.0.0:8000
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db

和用于构建 Web 容器的 Docker 文件设置如下:

FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/

因此,当为该容器构建映像时,requirements.txt 将安装最初包含的任何依赖项。

如果我将其用作我的开发环境,则很难向该 requirements.txt 文件添加任何新的依赖项,因为我将不得不重建容器以使 requirements.txt 中的更改成为安装。

django 社区是否有某种最佳实践来处理这个问题?如果不是,我会说 docker 看起来非常适合在完成后打包应用程序,但用作开发环境并不是很好。重建容器需要很长时间,因此浪费了很多时间。

感谢任何见解。谢谢。

您可以在使用 docker run 时将 requirements.txt 作为卷装载(未经测试,但您明白要点):

docker run container:tag -v /code/requirements.txt ./requirements.txt

然后您可以将脚本与您的容器捆绑在一起,该脚本将 运行 pip install -r requirements.txt 在启动您的应用程序之前,并将其用作您的 ENTRYPOINT。我喜欢自定义入口点脚本方法,它让我可以做一些额外的工作而无需制作新容器。

就是说,如果您要更改依赖项,那么您可能正在更改您的应用程序,您可能应该制作一个新容器并用更高版本标记它,不是吗? :)

所以我将 yaml 文件更改为:

db:
  image: postgres
web:
  build: .
  command: sh startup.sh
  volumes:
    - .:/code
  ports:
    - "8000:8000"
  links:
    - db

我制作了一个简单的 shell 脚本 startup.sh:

#!/bin/bash

#restart this script as root, if not already root
[ `whoami` = root ] || exec sudo [=11=] $*

pip install -r dev-requirements.txt

python manage.py runserver 0.0.0.0:8000

然后制作了一个 dev-requirements.txt,由上面的 shell 脚本安装,作为一种依赖暂存环境。

当我对 dev-requirements.txt 中的依赖项感到满意时,我会将其移至 requirements.txt 以提交到下一个映像构建。这使我可以在开发时灵活地添加和删除依赖项。

我认为最好的方法是忽略目前最常见的安装 python 依赖项的方法 (pip install -r requirements.txt) 并直接在 Dockerfile 中指定您的要求,有效地摆脱 requirements.txt 文件。此外,您还可以免费获得 docker 层缓存。

FROM python:2.7
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
# make sure you install requirements before the ADD, since everything after ADD is not cached
RUN pip install flask==0.10.1
RUN pip install sqlalchemy==1.0.6
...
ADD . /code/

如果 docker 容器是您的应用程序 运行 唯一的方式,那么我建议您这样做。如果您想支持其他设置代码的方法(例如 virtualenv),那么这当然不适合您,您应该退回到使用需求文件或使用 setup.py 例程。无论哪种方式,我发现这种方式最简单直接,无需处理所有混乱的 python 包分发问题。