Docker は便利ですが、受託案件で本番までコンテナ化すべきかは別の判断です。
実際には「開発環境だけ Docker、本番は素の構成」を選ぶことが多くあります。
なぜ本番はコンテナ化しないことがあるのか
- 引き継ぎ先にコンテナの運用経験が無い
- サーバーが1台で、オーケストレーションの利点が出ない
- 障害時の調査手順が増える(コンテナに入る、ログの場所が変わる)
運用する人のスキルセットに合わせるのが受託の基本です。
自分が運用し続けるなら別ですが、そうでないなら「読める構成」を優先します。
開発環境だけなら利点が大きい
一方、開発環境の統一は誰にとっても利点があります。
- Python や PostgreSQL のバージョン差による「自分の環境では動く」が消える
- 新しく参加した人が1コマンドで動かせる
- OS を問わない
services:
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: dev
ports: ["5432:5432"]
volumes: ["pgdata:/var/lib/postgresql/data"]
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes: [".:/app"]
ports: ["8000:8000"]
depends_on: [db]
volumes:
pgdata:
開発用 Dockerfile の要点
FROM python:3.9-slim
# 依存を先にコピーする(コード変更でキャッシュが壊れないように)
COPY requirements.txt /tmp/
RUN pip install --no-cache-dir -r /tmp/requirements.txt
WORKDIR /app
requirements.txt を先にコピーするのが定石です。
コードと一緒にコピーすると、1行直すたびに依存を再インストールします。
よく詰まる点
DBの起動待ち
depends_on はコンテナの起動順を制御するだけで、
PostgreSQL が接続を受け付ける状態になるまでは待ちません。
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 3s
retries: 10
depends_on:
db: { condition: service_healthy }
ファイル権限
Linux ではコンテナ内で作ったファイルが root 所有になり、ホストから編集できなくなります。
user: "${UID:-1000}:${GID:-1000}"
本番との差を小さく保つ
開発だけ Docker にすると、本番との差が事故の原因になります。
最低限、次は揃えます。
- Python のマイナーバージョン
- PostgreSQL のメジャーバージョン
- タイムゾーンとロケール
requirements.txt はバージョンを固定し、両環境で同じものを使います。
まとめ
- 本番のコンテナ化は「運用する人が誰か」で決める
- 開発環境の統一だけでも利点は十分大きい
- 依存のコピーを先にしてビルドキャッシュを効かせる
depends_onだけでは起動を待てない。healthcheck を使う- Python / DB / タイムゾーンは本番と揃える