Last active
April 19, 2025 03:54
-
-
Save aoirint/20f01c1abcc942e458fab2755808d0e9 to your computer and use it in GitHub Desktop.
uvを使ったPythonプロジェクトのDockerイメージ構築例
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# License: CC0-1.0 | |
# syntax=docker/dockerfile:1.14 | |
ARG BASE_IMAGE="ubuntu:22.04" | |
# Pythonバイナリをダウンロードするステージ | |
FROM "${BASE_IMAGE}" AS download-python-stage | |
# ダウンロードに必要なwgetとルート証明書をインストール | |
ARG DEBIAN_FRONTEND="noninteractive" | |
RUN <<EOF | |
set -eu | |
apt-get update | |
apt-get install -y \ | |
wget \ | |
ca-certificates | |
apt-get clean | |
rm -rf /var/lib/apt/lists/* | |
EOF | |
# astral-sh/python-build-standaloneからPythonバイナリをダウンロード | |
ARG PYTHON_VERSION="3.10.17+20250409" | |
ARG PYTHON_SHA256_DIGEST="ba9e325b2d3ccacc1673f98aada0ee38f7d2d262c52253e2b36f745c9ae6e070" | |
RUN <<EOF | |
set -eu | |
mkdir -p /opt/python-download | |
cd /opt/python-download | |
wget -O "python.tar.gz" "https://github.com/astral-sh/python-build-standalone/releases/download/20250409/cpython-${PYTHON_VERSION}-x86_64-unknown-linux-gnu-install_only.tar.gz" | |
echo "${PYTHON_SHA256_DIGEST} python.tar.gz" | sha256sum -c - | |
# Extract to ./python | |
tar xf "python.tar.gz" | |
mv ./python /opt/python | |
rm -f "python.tar.gz" | |
EOF | |
# Python仮想環境を構築するステージ | |
FROM "${BASE_IMAGE}" AS build-python-venv-stage | |
# Pythonライブラリのインストールに必要なgitをインストール | |
ARG DEBIAN_FRONTEND="noninteractive" | |
RUN <<EOF | |
set -eu | |
apt-get update | |
apt-get install -y \ | |
git | |
apt-get clean | |
rm -rf /var/lib/apt/lists/* | |
EOF | |
# ホームディレクトリを持つ作業用ユーザーを作成 | |
ARG BUILDER_UID="999" | |
ARG BUILDER_GID="999" | |
RUN <<EOF | |
set -eu | |
groupadd --non-unique --gid "${BUILDER_GID}" "builder" | |
useradd --non-unique --uid "${BUILDER_UID}" --gid "${BUILDER_GID}" --create-home "builder" | |
EOF | |
# 作業用ユーザーが使用する作業ディレクトリと出力先ディレクトリを作成 | |
RUN <<EOF | |
set -eu | |
mkdir -p "/work" | |
chown -R "${BUILDER_UID}:${BUILDER_GID}" "/work" | |
mkdir -p "/cache/uv" | |
chown -R "${BUILDER_UID}:${BUILDER_GID}" "/cache/uv" | |
mkdir -p "/opt/python_venv" | |
chown -R "${BUILDER_UID}:${BUILDER_GID}" "/opt/python_venv" | |
EOF | |
# Pythonをインストール | |
COPY --chown=root:root --from=download-python-stage /opt/python /opt/python | |
ENV PATH="/home/builder/.local/bin:/opt/python/bin:${PATH}" | |
# 作業用ユーザーに切り替え | |
USER "${BUILDER_UID}:${BUILDER_GID}" | |
WORKDIR "/work" | |
# uvをインストール | |
ARG UV_VERSION="0.6.14" | |
RUN <<EOF | |
set -eu | |
pip install --user "uv==${UV_VERSION}" | |
EOF | |
# Python仮想環境を構築 | |
COPY ./pyproject.toml ./uv.lock /work/ | |
RUN --mount=type=cache,uid="${BUILDER_UID}",gid="${BUILDER_GID}",target=/cache/uv <<EOF | |
set -eu | |
cd "/work" | |
uv venv "/opt/python_venv" | |
UV_PROJECT_ENVIRONMENT="/opt/python_venv" uv sync | |
EOF | |
# Pythonプログラムのバイトコードをビルドするステージ | |
FROM "${BASE_IMAGE}" AS compile-source-stage | |
# Pythonをインストール | |
COPY --from=download-python-stage /opt/python /opt/python | |
# Python仮想環境をインストール | |
COPY --from=build-python-venv-stage /opt/python_venv /opt/python_venv | |
ENV PATH="/opt/python_venv/bin:/opt/python/bin:${PATH}" | |
ARG BUILDER_UID="999" | |
ARG BUILDER_GID="999" | |
# 作業用ディレクトリを作成 | |
RUN <<EOF | |
set -eu | |
mkdir -p "/opt/my_project" | |
chown -R "${BUILDER_UID}:${BUILDER_GID}" "/opt/my_project" | |
EOF | |
# ソースコードをコンテナに追加 | |
COPY --chown="${BUILDER_UID}:${BUILDER_GID}" ./my_project /opt/my_project/my_project | |
COPY --chown="${BUILDER_UID}:${BUILDER_GID}" ./main.py /opt/my_project/ | |
# 作業用ユーザーに切り替え | |
USER "${BUILDER_UID}:${BUILDER_GID}" | |
WORKDIR "/opt/my_project" | |
# __pycache__を生成 | |
RUN <<EOF | |
set -eu | |
python -m compileall . | |
EOF | |
# 実行用ステージ | |
FROM "${BASE_IMAGE}" AS runtime-stage | |
# Pythonをインストール | |
COPY --from=download-python-stage /opt/python /opt/python | |
# Python仮想環境をインストール | |
COPY --from=build-python-venv-stage /opt/python_venv /opt/python_venv | |
ENV PATH="/opt/python_venv/bin:/opt/python/bin:${PATH}" | |
# ソースコードをコンテナに追加 | |
COPY --from=compile-source-stage /opt/my_project /opt/my_project | |
# 一般ユーザーに切り替え | |
# NOTE: 実行時にUIDを変更したい場合、docker run --user "1100:1100" のように変更可 | |
USER "1000:1000" | |
ENTRYPOINT [ "python", "/opt/my_project/main.py" ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment