你能给我一个Dockerfile的例子吗?我可以在其中安装所有我需要的软件包。锁定和pyproject。toml到我的镜像/容器从Docker?
当前回答
我的python应用程序的Dockerfile看起来像这样-
FROM python:3.10-alpine
RUN apk update && apk upgrade
RUN pip install -U pip poetry==1.1.13
WORKDIR /app
COPY . .
RUN poetry export --without-hashes --format=requirements.txt > requirements.txt
RUN pip install -r requirements.txt
EXPOSE 8000
ENTRYPOINT [ "python" ]
CMD ["main.py"]
其他回答
下面是一个剥离的例子,其中首先是一个带有依赖关系的层(仅在这些依赖关系发生变化时构建),然后将一个带有完整源代码的层添加到图像中。将poetry设置为安装到全局站点包中会留下一个配置工件,该配置工件也可以被删除。
FROM python:alpine
WORKDIR /app
COPY poetry.lock pyproject.toml ./
RUN pip install --no-cache-dir --upgrade pip \
&& pip install --no-cache-dir poetry \
\
&& poetry config settings.virtualenvs.create false \
&& poetry install --no-dev \
\
&& pip uninstall --yes poetry \
COPY . ./
我的python应用程序的Dockerfile看起来像这样-
FROM python:3.10-alpine
RUN apk update && apk upgrade
RUN pip install -U pip poetry==1.1.13
WORKDIR /app
COPY . .
RUN poetry export --without-hashes --format=requirements.txt > requirements.txt
RUN pip install -r requirements.txt
EXPOSE 8000
ENTRYPOINT [ "python" ]
CMD ["main.py"]
我使用一个锁包(包依赖于锁文件中的所有版本)创建了一个解决方案。这将导致没有需求文件的纯pip安装。
步骤是:构建包,构建锁包,将两个轮子复制到容器中,使用pip安装两个轮子。
安装是:诗词add——dev诗词锁包
docker构建之外的步骤是:
poetry build
poetry run poetry-lock-package --build
然后你的Dockerfile应该包含:
FROM python:3-slim
COPY dist/*.whl /
RUN pip install --no-cache-dir /*.whl \
&& rm -rf /*.whl
CMD ["python", "-m", "entry_module"]
这是对@Claudio提供的答案的一个小修改,它使用了@sobolevn在他的回答中描述的新的诗歌安装-无根特性。
为了强制poetry将依赖项安装到特定的virtualenv中,首先需要启用它。
. /path/to/virtualenv/bin/activate && poetry install
因此,将这些添加到@Claudio的答案中
FROM python:3.10-slim as base
ENV PYTHONFAULTHANDLER=1 \
PYTHONHASHSEED=random \
PYTHONUNBUFFERED=1
WORKDIR /app
FROM base as builder
ENV PIP_DEFAULT_TIMEOUT=100 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=1 \
POETRY_VERSION=1.3.1
RUN pip install "poetry==$POETRY_VERSION"
COPY pyproject.toml poetry.lock README.md ./
# if your project is stored in src, uncomment line below
# COPY src ./src
# or this if your file is stored in $PROJECT_NAME, assuming `myproject`
# COPY myproject ./myproject
RUN poetry config virtualenvs.in-project true && \
poetry install --only=main --no-root && \
poetry build
FROM base as final
COPY --from=builder /app/.venv ./.venv
COPY --from=builder /app/dist .
COPY docker-entrypoint.sh .
RUN ./.venv/bin/pip install *.whl
CMD ["./docker-entrypoint.sh"]
如果您需要将其用于开发目的,您可以通过替换这一行来添加或删除——no-dev
RUN . /venv/bin/activate && poetry install --no-dev --no-root
就像@sobolevn的回答中显示的那样
RUN . /venv/bin/activate && poetry install --no-root $(test "$YOUR_ENV" == production && echo "--no-dev")
在添加适当的环境变量声明之后。
该示例使用debian-slim的图像作为基础,但是,将其调整为基于阿尔卑斯的图像应该是一项微不足道的任务。
多阶段Docker构建与诗歌和venv
不要禁用virtualenv创建功能。virtualenv在Docker构建中发挥了作用,因为它们提供了一种优雅的方式来利用多阶段构建。简而言之,构建阶段将所有内容安装到virtualenv中,而最后阶段只是将virtualenv复制到一个小映像中。
在复制代码之前,先使用诗歌导出并安装固定的需求。这将允许您使用Docker构建缓存,并且永远不会因为更改代码中的一行而重新安装依赖项。
不要使用诗意安装来安装代码,因为它将执行可编辑的安装。相反,使用诗歌构建来构建一个轮子,然后将其安装到您的virtualenv中。(感谢PEP 517,这整个过程也可以通过简单的pip install .来执行,但由于构建隔离,您最终将安装另一个Poetry副本。)
下面是一个Dockerfile安装Flask应用到Alpine镜像的例子,它依赖于Postgres。本例使用入口点脚本激活virtualenv。但一般来说,没有入口点脚本也没问题,因为您可以在CMD指令中简单地引用/venv/bin/ Python的Python二进制文件。
Dockerfile
FROM python:3.7.6-alpine3.11 as base
ENV PYTHONFAULTHANDLER=1 \
PYTHONHASHSEED=random \
PYTHONUNBUFFERED=1
WORKDIR /app
FROM base as builder
ENV PIP_DEFAULT_TIMEOUT=100 \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=1 \
POETRY_VERSION=1.0.5
RUN apk add --no-cache gcc libffi-dev musl-dev postgresql-dev
RUN pip install "poetry==$POETRY_VERSION"
RUN python -m venv /venv
COPY pyproject.toml poetry.lock ./
RUN poetry export -f requirements.txt | /venv/bin/pip install -r /dev/stdin
COPY . .
RUN poetry build && /venv/bin/pip install dist/*.whl
FROM base as final
RUN apk add --no-cache libffi libpq
COPY --from=builder /venv /venv
COPY docker-entrypoint.sh wsgi.py ./
CMD ["./docker-entrypoint.sh"]
docker-entrypoint.sh
#!/bin/sh
set -e
. /venv/bin/activate
while ! flask db upgrade
do
echo "Retry..."
sleep 1
done
exec gunicorn --bind 0.0.0.0:5000 --forwarded-allow-ips='*' wsgi:app
wsgi.py
import your_app
app = your_app.create_app()
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 安装tzdata非交互式
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if