我正在尝试dockerize一个简单的脚本(命令行实用程序)。这是一个工作的Dockerfile:
FROM python:3.9-slim
ARG user=tweaker project=tex-tweak src=tex_tweak
# Non-root user.
RUN useradd -ms /bin/bash "$user"
USER $user
WORKDIR /home/$user
ENV PATH=/home/$user/.local/bin:$PATH
# Source and project files.
RUN mkdir /home/$user/$project
WORKDIR /home/$user/$project
COPY $src ./$src/
COPY pyproject.toml ./
#COPY poetry.lock ./
# Build.
RUN pip install poetry --user &&
poetry config virtualenvs.create false &&
poetry install --no-dev &&
poetry build
CMD ["bash"]
奇怪的是,这就足够了:目标实用程序以某种方式被安装到.local/bin
;我不明白为什么。
python:slim
映像为115MB;生成的图像大小为174MB。并非不可接受,但相对臃肿。我想,多阶段构建是有序的。不幸的是,我看不出我应该如何把要点转移到第二阶段。选择性复制.local/bin
和.local/lib
的想法看起来并不特别安全或诱人。或许这就是出路?
或者pip install <target>.whl
进入第二阶段是否可能/可取?
这里是一个示例构建,您可以参考多阶段的诗歌:
https://stackoverflow.com/a/64642121/14305096
FROM python:3.9-slim as base
ENV PYTHONFAULTHANDLER=1
PYTHONHASHSEED=random
PYTHONUNBUFFERED=1
RUN apt-get update && apt-get install -y gcc libffi-dev g++
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.1.3
RUN pip install "poetry==$POETRY_VERSION"
RUN python -m venv /venv
COPY pyproject.toml poetry.lock ./
RUN . /venv/bin/activate && poetry install --no-dev --no-root
COPY . .
RUN . /venv/bin/activate && poetry build
FROM base as final
COPY --from=builder /venv /venv
COPY --from=builder /app/dist .
COPY docker-entrypoint.sh ./
RUN . /venv/bin/activate && pip install *.whl
CMD ["./docker-entrypoint.sh"]