你能给我一个Dockerfile的例子吗?我可以在其中安装所有我需要的软件包。锁定和pyproject。toml到我的镜像/容器从Docker?
当前回答
这是最适合我的最小配置:
FROM python:3.7
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
RUN pip install poetry
WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN poetry config virtualenvs.create false
RUN poetry install --no-interaction
COPY . /app
注意,它不像@sobolevn的配置那样安全。
作为一个小问题,我将补充一下pyproject是否可以进行可编辑安装。Toml项目,可以删除一两行:
FROM python:3.7
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN pip install -e .
COPY . /app
其他回答
多阶段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()
这是对@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的图像作为基础,但是,将其调整为基于阿尔卑斯的图像应该是一项微不足道的任务。
这是最适合我的最小配置:
FROM python:3.7
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
RUN pip install poetry
WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN poetry config virtualenvs.create false
RUN poetry install --no-interaction
COPY . /app
注意,它不像@sobolevn的配置那样安全。
作为一个小问题,我将补充一下pyproject是否可以进行可编辑安装。Toml项目,可以删除一两行:
FROM python:3.7
ENV PIP_DISABLE_PIP_VERSION_CHECK=on
WORKDIR /app
COPY poetry.lock pyproject.toml /app/
RUN pip install -e .
COPY . /app
博士TL;
我已经能够使用postgres为Django项目创建诗歌。在做了一些研究后,我最终得到了以下Dockerfile:
FROM python:slim
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1
# Install and setup poetry
RUN pip install -U pip \
&& apt-get update \
&& apt install -y curl netcat \
&& curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
ENV PATH="${PATH}:/root/.poetry/bin"
WORKDIR /usr/src/app
COPY . .
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
这是entrypoint.sh的内容:
#!/bin/sh
if [ "$DATABASE" = "postgres" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
python manage.py migrate
exec "$@"
详细解释
需要注意以下几点:
I have decide to use slim instead of alpine as tag for the python image because even though alpine images are supposed to reduce the size of Docker images and speed up the build, with Python, you can actually end up with a bit larger image and that takes a while to build (read this article for more info). Using this configuration builds containers faster than using the alpine image because I do not need to add some extra packages to install Python packages properly. I am installing poetry directly from the URL provided in the documentation. I am aware of the warnings provided by sobolevn. However, I consider that it is better in the long term to use the lates version of poetry by default than relying on an environment variable that I should update periodically. Updating the environment variable PATH is crucial. Otherwise, you will get an error saying that poetry was not found. Dependencies are installed directly in the python interpreter of the container. It does not create poetry to create a virtual environment before installing the dependencies.
如果你需要这个Dockerfile的alpine版本:
FROM python:alpine
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1
# Install dev dependencies
RUN apk update \
&& apk add curl postgresql-dev gcc python3-dev musl-dev openssl-dev libffi-dev
# Install poetry
RUN pip install -U pip \
&& curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
ENV PATH="${PATH}:/root/.poetry/bin"
WORKDIR /usr/src/app
COPY . .
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
# run entrypoint.sh
ENTRYPOINT ["/usr/src/app/entrypoint.sh"]
注意,alpine版本需要一些依赖关系postgresql-dev gcc python3-dev musl-dev openssl-dev libffi-dev才能正常工作。
下面是一个剥离的例子,其中首先是一个带有依赖关系的层(仅在这些依赖关系发生变化时构建),然后将一个带有完整源代码的层添加到图像中。将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 . ./
推荐文章
- ValueError: numpy。Ndarray大小改变,可能表示二进制不兼容。期望从C头得到88,从PyObject得到80
- 如何用docker-compose更新现有图像?
- 如何在构建docker期间设置环境变量
- Anaconda /conda -安装特定的软件包版本
- 我在哪里调用Keras的BatchNormalization函数?
- 打印测试执行时间并使用py.test锁定缓慢的测试
- 插入一行到熊猫数据框架
- 要列出Pandas DataFrame列
- 在Django模型中存储电话号码的最佳方法是什么?
- 从导入的模块中模拟函数
- 滚动或滑动窗口迭代器?
- python的方法找到最大值和它的索引在一个列表?
- 如何读取文件的前N行?
- 如何删除matplotlib中的顶部和右侧轴?
- 解析.py文件,读取AST,修改它,然后写回修改后的源代码