ローカルにPythonを直接インストールして開発していると、バージョン問題や依存ライブラリの衝突がじわじわしんどくなってくる。そのうち「あれ、このプロジェクトってPython 3.10だっけ3.12だっけ」ってなるやつ。Docker Composeを使えばその辺がきれいに解決できるので、今回は入門レベルの構成をまとめてみました。
この記事では、最小構成のPython環境をDocker Composeで作ってコードを動かすまでの手順を書いています。AWSとかAPIとか関係ない、ただのローカル開発環境の話です。
この記事でわかること
- Docker Compose V2の基本的な使い方
- Dockerfile と compose.yaml の最小構成
- Pythonスクリプトをコンテナで実行する方法
- ファイルマウントと環境変数の設定
- データベースと連携した複数サービスの構成
まず「Docker Compose V2」の話を一瞬だけ
古い記事を参考にするとき地味にハマるのがこれなんですが、2026年現在はDocker Compose V2が標準です。
何が変わるかというと、コマンドが変わります。
# 旧(V1)- もう使わなくていい
docker-compose up
# 新(V2)- これを使う
docker compose up
ハイフンがスペースになっただけなんですが、Docker Desktop をインストールすれば自動的にV2が使える状態になっています。V1はEOL(サポート終了)となっており、V2の使用が推奨されます。今から始める人は最初からV2の書き方で覚えてしまって大丈夫です。
ファイル名もちょっと変わっていて、V2では compose.yaml が推奨されるようになっています。とはいえどちらも読めるので、既存プロジェクトを壊すほどの話ではないです。新規で作るなら compose.yaml にしておくのが今後のスタンダードに沿っています。
Docker Compose開発環境のディレクトリ構成
今回作るのはこんな感じのシンプルな構成。
my-python-app/
├── compose.yaml
├── Dockerfile
├── requirements.txt
└── src/
└── main.py
src/ フォルダにソースを置いて、コンテナ内にマウントする形にします。こうすると手元でファイルを編集したらすぐコンテナに反映されて便利です。
Dockerfile を書く
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "src/main.py"]
いくつかポイントを補足します。
python:3.12-slim を使う理由
python:3.12(フル版)はサイズがかなり大きいことが多いです。開発環境なら slim で十分なことも多く、イメージサイズを大きく削減できるケースもあります。ちなみに Alpine はさらに軽いですが、Alpine(musl)まわりは一部のライブラリで互換性のハマりどころがあると言われることもあるので、利用前に要件と相性(必要な依存・脆弱性情報など)を確認したほうが安心です。特にこだわりなければ slim が無難寄りでおすすめです。
requirements.txt を先にコピーする理由
Dockerはレイヤーキャッシュの仕組みがあって、変更がなければ前のビルドキャッシュを使い回します。requirements.txt が変わっていなければライブラリのインストールをスキップしてくれるので、ビルドが速くなります。ソースコードより先にコピーしておくのがコツです。
compose.yaml を書く
services:
app:
build: .
volumes:
- ./src:/app/src
environment:
- PYTHONUNBUFFERED=1
シンプルです。各設定の意味をざっくり。
build: .― カレントディレクトリの Dockerfile でイメージをビルドするvolumes― ホストの./srcをコンテナの/app/srcにマウント。手元で編集したらすぐ反映されるPYTHONUNBUFFERED=1― Pythonの標準出力がバッファされにくくなるので、ログがすぐ出てほしい用途で効くことがあります(環境や実行状況によっては体感差が出ないこともあります)。地味に重要
あと、Compose Spec ではトップレベルの version キーは obsolete(廃止)となりました。古い記事だと最初に version: '3.8' と書いてあることが多いですが、今は書かなくて大丈夫です。
requirements.txt と main.py を用意する
試しに requests を入れて、適当なAPIを叩くだけのスクリプトを作ってみます。
# requirements.txt
requests==2.32.4
# src/main.py
import requests
def main():
res = requests.get("https://httpbin.org/json")
print(res.json())
if __name__ == "__main__":
main()
そういえば最近は pip の代わりに uv を使う人も増えているようで、Dockerfileでも uv ベースの構成を見かけることがあります。ただ今回は入門向けなので pip で行きます。
Docker Composeで開発環境を実行する
ファイルが揃ったらビルドして起動するだけです。
# イメージをビルドしてコンテナを起動
docker compose up --build
# バックグラウンドで動かしたい場合
docker compose up --build -d
# ログを確認
docker compose logs app
# コンテナを止める
docker compose down
うまくいけば main.py が実行されて、httpbin からのレスポンスが表示されるはずです。
コンテナの中に入って直接操作したいときはこれ。
docker compose exec app sh
インストールされているパッケージを確認したり、インタラクティブにPythonを動かしたりするのに使います。
便利な機能:Docker Compose Watch
Docker Compose Watchは、ファイル変更を自動検知してコンテナに同期・再構築するツールです。volumesマウントでもファイル編集は反映されますが、Watch を使うとより細かく同期の挙動を制御できます。
compose.yaml に develop.watch を追加するだけ。
services:
app:
build: .
volumes:
- ./src:/app/src
environment:
- PYTHONUNBUFFERED=1
develop:
watch:
- action: sync
path: ./src
target: /app/src
- action: rebuild
path: requirements.txt
起動は docker compose up --watch。syncアクションはコンテナ内のホットリロード機構と組み合わせて使い、rebuildはpip installの再実行が必要なファイルが変わったときに設定します。これで、
src/以下のファイルが変わったらコンテナ内に自動syncrequirements.txtが変わったらイメージを自動rebuild
という動きになります。ライブラリを追加するたびに手動でビルドし直すのを忘れるのが地味なストレスだったので、この機能は地味に嬉しい。
複数サービスの構成:PostgreSQL連携例
実際の開発だとDBと一緒に使いたいことが多いので、PostgreSQLを追加した例も載せておきます。
services:
app:
build: .
volumes:
- ./src:/app/src
environment:
- PYTHONUNBUFFERED=1
- DATABASE_URL=postgresql://user:password@db:5432/mydb
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: mydb
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
interval: 10s
timeout: 5s
retries: 5
volumes:
db_data:
depends_on に condition: service_healthy を付けておくと、Composeの実装やバージョンによっては、DBのヘルスチェックが通ってから app 側を起動するような挙動になります。これをやっておかないと「DBがまだ起動してないのにアプリが接続しようとして落ちる」という事故がたまに起きるので、ここは注意ポイントです(最終的にはアプリ側のリトライ実装もあると安心)。
正直、healthcheck の書き方は毎回ぐぐってる気がします。パラメータが多くて覚えられない。
まとめ
Docker Composeは、複数のDockerコンテナを定義・管理するためのツールで、compose.yamlファイルに各サービスの設定を記述し、docker compose upコマンド一つで開発環境全体を起動できます。「環境をコードで定義できる」ことがキモで、ファイルさえあれば誰でも同じ環境を再現できます。「自分のMacでは動くのに」という不毛な問題もだいぶ減ります。
今回は入門向けに最小構成で書きましたが、実際にはDB・キャッシュ・非同期ワーカーとサービスが増えていくにつれて compose.yaml も育っていきます。複雑な構成になってきたら、各セクションに comment を入れたり、環境変数を .env ファイルで管理したりするのも検討の余地があります。

