Open5
Rye を Docker で使う
ピン留めされたアイテム
翻訳
マルチステージビルドのためのDockerfileを書いてみました。以下に一例を示します:
ARG PYTHON_BASE_IMAGE='python'
FROM ${PYTHON_BASE_IMAGE}:3.11 AS rye
# Pythonがpycファイルを書き込まないようにします。
ENV PYTHONDONTWRITEBYTECODE=1
# Pythonがstdoutとstderrをバッファリングしないようにします。これにより、
# バッファリングによりログが発生せずにアプリケーションがクラッシュする状況を避けることができます。
ENV PYTHONUNBUFFERED=1
ENV PYTHONPATH="/workspace/src:$PYTHONPATH"
# 仮想環境はryeが実行されるワーキングディレクトリで作成されるため、
# 開発環境と本番環境はそれぞれ同一のディレクトリにする必要があります。
WORKDIR /workspace
RUN \
\
apt-get update \
&& apt-get install -y --no-install-recommends build-essential
ENV RYE_HOME="/opt/rye"
ENV PATH="$RYE_HOME/shims:$PATH"
# RYE_INSTALL_OPTIONはビルドに必要です。
# 参照: https://github.com/mitsuhiko/rye/issues/246
RUN curl -sSf https://rye-up.com/get | RYE_NO_AUTO_INSTALL=1 RYE_INSTALL_OPTION="--yes" bash
# Dockerのキャッシュを利用するために、依存関係のダウンロードを別のステップとして行います。
# バインドマウントを利用して一部のファイルをこのレイヤーにコピーすることを避けます。
RUN \
rye sync --no-dev --no-lock
RUN . .venv/bin/activate
# 開発のためのステージ。
# 開発環境はdevcontainerを想定し、環境はコンテナ内部に閉じ込められているため、
# 仮想環境を意識する必要はありません。
FROM rye AS dev
RUN
\
--mount=type=bind,source=README.md,target=README.md \
rye sync --no-lock
# 本番用のステージ
FROM rye AS run
# アプリケーションが実行する非特権ユーザーを作成します。
# 参照: https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#user
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
# アプリケーションを実行するために非特権ユーザーに切り替えます。
USER appuser
COPY . .
ENTRYPOINT ["python3", "./src/main.py"]
想定しているディレクトリ構造は以下のようなものです。(これはかなり単純化したバージョンです。)
.
├── .devcontainer
│ ├── devcontainer.json
│ ├── docker-compose.yml
│ └── postCreateCommand.sh
├── src # アプリケーションのソースコードディレクトリ
├── tests # テストコードディレクトリ
├── Dockerfile
└── docker-compose.yml
プロジェクトルートのdocker-compose.yml
version: "3.9"
services:
app:
build:
context: .
dockerfile: Dockerfile
target: run # マルチステージビルドターゲットを指定する
ports:
- 8080:8080
devcontainer.json
{
"name": "rye",
"dockerComposeFile": [
"../docker-compose.yml",
"docker-compose.yml"
],
"service": "app",
"workspaceFolder": "/workspace",
"postCreateCommand": "bash .devcontainer/postCreateCommand.sh",
"userEnvProbe": "loginInteractiveShell",
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"charliermarsh.ruff",
"bungcip.better-toml",
"ms-azuretools.vscode-docker"
]
}
}
}
.devcontainerディレクトリ内のdocker-compose.yml
version: "3.9"
services:
app:
container_name: app-dev
build:
args:
- PYTHON_BASE_IMAGE=mcr.microsoft.com/vscode/devcontainers/python
target: ${TARGET_STAGE:-dev} # devステージを使用するためにオーバーライド
command: sleep infinity
volumes:
- .:/workspace:cached
tty がないせいか、現時点ではインストールに失敗する。
FROM python:3.11
RUN curl -sSf https://rye-up.com/get | bash
CMD ["python3"]
作者も docker での利用方法をドキュメントにまとめようとしているらしい
考えてること
- Pythonの仮想環境は必要ないと思っている。なぜなら、コンテナ内部に依存関係とアプリケーションコードを閉じ込めるから。
-
curl https://rye-up.com/get
の行を実行するたびに、cpython@3.10
がインストールされるが、これも必要ないと思っている。.python-version
のものをインストールしたい。(書き方に何か問題があるかも)
Python3.9~3.12までなら、デフォルトでインストールするバージョンは以下のオプションで指定できるようです。https://rye.astral.sh/guide/installation/#customized-installation
curl -sSf https://rye.astral.sh/get | RYE_TOOLCHAIN_VERSION=3.9