閉じる

Python開発環境をDockerで構築する方法|仮想環境いらずのシンプル手順

Pythonで開発を始めるとき、毎回venvで仮想環境を作ったり、PCごとにバージョン差異に悩まされたりしていないでしょうか。

Dockerを使えば、Python本体からライブラリ、OSレベルの依存関係までを1つのイメージに閉じ込めて管理できます。

本記事では、「DockerでPython開発環境を構築するための最小かつ実用的な手順」を、Docker初心者でも迷わないように図解とサンプルコード付きで詳しく解説します。

Python開発環境をDockerで構築するメリット

DockerでPython開発環境を作るメリット

DockerでPython開発環境を作る最大の魅力は、「同じ環境をどこでも再現できること」です。

Pythonのバージョンやライブラリの組み合わせをイメージに閉じ込めてしまうため、次のようなメリットが生まれます。

まず、PCを変えても、OSが違っても、同じDockerイメージさえあれば同一のPython環境を一瞬で再現できます。

また、環境が壊れたりライブラリの依存関係がぐちゃぐちゃになっても、コンテナを削除してイメージから作り直せば、すぐにクリーンな状態に戻せます。

さらに、Pythonだけでなく、システムパッケージ(curlやbuild-essentialなど)も含めて「環境ごとバージョン管理」できるため、「このライブラリはLinuxでしか動かない」「ローカルMacだと動くのに本番サーバでは動かない」といったトラブルも大きく減らせます。

仮想環境(venv)不要になる理由

従来のPython開発では、プロジェクトごとにpython -m venv venvで仮想環境を作り、その中でpip installを行うのが一般的でした。

これは、「同じPC上でプロジェクトごとにライブラリのバージョンを分離する」ための仕組みです。

一方で、DockerはPythonよりも一段下のOSレイヤー全体を分離します。

各コンテナは、それぞれが独立した小さなLinux環境を持ち、そこにPython本体とライブラリをインストールします。

結果として、プロジェクトごとに別のコンテナを用意すれば、そもそもグローバルのPythonに触れることがなくなり、仮想環境(venv)を使う理由がほぼ消えていきます。

もちろん、Dockerコンテナの中でさらにvenvを使うことも可能ですが、通常の開発用途では「コンテナが仮想環境の役割を兼ねる」と考えて問題ありません。

ローカル環境を汚さない開発フロー

Dockerを使うと、ローカルPCにインストールするものを最小限に抑えられます。

基本的には、Docker自体とエディタ(VS Codeなど)さえあれば足ります。

開発フローとしては、ローカルにはソースコードだけを置き、Pythonやpip、各種ライブラリはすべてコンテナ内に閉じ込める形になります。

これにより、ローカルのグローバルPythonやグローバルpipを一切使わない運用が可能になります。

例えば、あるプロジェクトで実験的なバージョンのライブラリをたくさん試したとしても、それはコンテナの中だけの話です。

ローカルの他のプロジェクトに影響を与えないので、環境を壊す不安なく、思い切って試行錯誤することができます。

Python用Dockerイメージの選び方と準備

python公式イメージの種類

Docker Hubには、Python用の公式イメージが多数公開されています。

代表的なタグは次の通りです。

タグ例ベースOS / 特徴用途の目安
python:3.12Debian系(フルサイズ)開発用・学習用で使いやすい標準
python:3.12-slimDebian系・不要パッケージ削減版軽量化したい開発・本番環境
python:3.12-alpineAlpine Linuxベース・非常に軽量要件が合う場合の軽量構成
python:3.11一世代前など、バージョン固定に使う既存システム準拠
python:3.12-bullseyeDebian bullseye明示・長期サポート向きOSバージョンまで厳密に揃えたいとき

学習や一般的なWeb開発では、まずpython:3.xもしくはpython:3.x-slimを選ぶのがおすすめです。

alpineは非常に軽量ですが、ビルドに追加作業が必要なライブラリも多く、初心者には少しハードルが高くなります

プロジェクトに合ったバージョン選定

Pythonバージョンを選ぶときは、プロジェクトの状況に応じて考えます。

新規プロジェクトでは、基本的に最新の安定版(例: 3.12系)を選ぶのが合理的です。

最新の言語機能や最適化が利用でき、ライブラリ側も最新バージョンへの対応が進んでいるためです。

一方で、既存システムの開発や保守の場合は、本番サーバで使われているPythonバージョンに合わせることが重要です。

例えば本番がPython 3.10ならpython:3.10を、3.11ならpython:3.11をDockerイメージとして利用するようにします。

このように、Dockerイメージのタグを工夫することで、「Pythonバージョンの固定」が簡単かつ明示的に行えます。

Docker DesktopとDocker CLIのインストール確認

PythonのDocker環境を構築する前に、Docker本体が使える状態かを確認します。

ここではWindows/MacのDocker Desktop、LinuxのDocker Engineを問わず、コマンドラインでの確認手順を紹介します。

まず、ターミナル(またはPowerShell)で次のコマンドを実行します。

Shell
docker -v

Dockerのバージョン情報が表示されれば、CLIは正しくインストールされています。

続いて、Dockerが正しくコンテナを起動できるかを確認するために、次のコマンドを実行します。

Shell
docker run --rm hello-world

問題なく動作すれば、Docker Engineが正常に動いていることが確認できます。

ここでエラーが出る場合は、Docker Desktopが起動していない、権限設定に問題があるなどの可能性があるため、先にそちらを解決しておきましょう。

DockerでPython開発環境を構築する基本手順

最小構成のDockerfile例

ここでは、最小限の構成でPython開発用のDockerfileを作成します。

次のようなファイル構成を想定します。

ファイル名役割
DockerfileDockerイメージの設計図
requirements.txtPythonパッケージ一覧
app.py動作確認用のPythonスクリプト

まずはシンプルなDockerfileを用意します。

dockerfile
# ベースとなるPython公式イメージを指定
# ここでは3.12のslim版を使用 (軽量で扱いやすい)
FROM python:3.12-slim

# コンテナ内の作業ディレクトリを指定
WORKDIR /app

# 依存パッケージ一覧をコンテナにコピー
# (requirements.txtがある前提)
COPY requirements.txt .

# 必要なパッケージをインストール
# --no-cache-dir でキャッシュを残さず、イメージを軽量に保つ
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションのソースコードをコピー
COPY . .

# デフォルトの実行コマンドを指定
# ここでは app.py を起動する例
CMD ["python", "app.py"]

このDockerfileは、Pythonのベースイメージを元に、requirements.txtで指定したライブラリをインストールし、最後にpython app.pyを実行するという、ごく標準的な構成になっています。

requirements.txtでPythonパッケージを管理する

Pythonの依存パッケージ管理には、requirements.txtを用いるのが最もシンプルです。

たとえば、次のような内容になります。

requests==2.32.3
pandas==2.2.3

これをDockerfileのRUN pip install -r requirements.txtで読み込むことで、コンテナ内に必要なライブラリを一括インストールできます。

また、ローカル開発時にもpip freeze > requirements.txtのようにして、現在の依存関係をファイルに吐き出し、チームメンバーと共有することが可能です。

Dockerではこのファイルがそのままイメージ作成時のインストールに使われるため、環境の再現性が非常に高くなります。

docker buildでPythonイメージを作成する手順

Dockerfileを作成したら、次はDockerイメージをビルドします。

ターミナルでDockerfileがあるディレクトリに移動し、次のコマンドを実行します。

Shell
docker build -t python-app:latest .

ここでのポイントは次の通りです。

  • -t python-app:latest はイメージ名とタグを指定しています。
  • 最後の.は、ビルドコンテキスト(=Dockerfileやソースコードが置いてあるディレクトリ)を意味します。

ビルドが完了すると、ローカルのDockerイメージ一覧にpython-app:latestが追加されます。

Shell
docker images

このコマンドを実行すると、作成されたイメージが確認できます。

REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
python-app    latest    123456789abc   10 seconds ago   250MB

docker runでコンテナ内Python環境を起動する

ビルドしたイメージからコンテナを起動するには、docker runを使います。

Shell
docker run --rm python-app:latest

ここでは、DockerfileのCMD ["python", "app.py"]が実行されます。

--rmを付けることで、コンテナの停止時に自動的に削除され、不要なコンテナが溜まるのを防げます。

試しに、app.pyを次のようにしておくと、Dockerによる実行結果が確認しやすくなります。

Python
# app.py

# 動作確認用のシンプルなスクリプト
import platform
import sys

def main():
    print("Hello from Dockerized Python!")
    print(f"Python version: {sys.version}")
    print(f"Platform: {platform.platform()}")

if __name__ == "__main__":
    main()

この状態でdocker runを実行すると、次のような出力が得られます。

Hello from Dockerized Python!
Python version: 3.12.0 (main, ...)
Platform: Linux-6.6.0-...-x86_64-with-glibc2.36

ここでのポイントは、ホストOSに依存せず、常にコンテナ内のLinux+Python環境で実行されているという点です。

ボリュームマウントでソースコードを共有する方法

開発中に毎回イメージをビルドし直すのは効率が悪いため、ボリュームマウントを使って、ローカルのソースコードをコンテナ内と共有するのが一般的です。

例えば、次のようなコマンドでコンテナを起動します。

Shell
docker run --rm -it \
  -v $(pwd):/app \
  -w /app \
  python:3.12-slim \
  bash

ここでのオプションの意味は次の通りです。

  • -v $(pwd):/app: 現在のディレクトリをコンテナ内の/appにマウント
  • -w /app: コンテナ内の作業ディレクトリを/appに設定
  • -it bash: 対話的なbashシェルを起動

この状態でコンテナ内からlsすると、ローカルと同じソースコードが見えるようになります。

ローカルでファイルを編集すると、その変更が即座にコンテナ内にも反映されるため、「ローカル編集+コンテナ実行」という自然な開発スタイルが実現できます。

コンテナ内でpip install・実行する流れ

ボリュームマウントしたコンテナ内では、通常のLinux環境と同様に作業できます。

具体的な流れの一例は次のようになります。

Shell
# コンテナに入る (前節の例と同じ)
docker run --rm -it \
  -v $(pwd):/app \
  -w /app \
  python:3.12-slim \
  bash

コンテナに入った後の操作例です。

Shell
# コンテナ内のシェル上での操作例

# 必要なライブラリをインストール
pip install requests

# 動作確認用のスクリプトを実行
python app.py

このとき、pipでインストールされたライブラリはコンテナ内にのみ反映され、ホストのPython環境には一切影響しません。

気軽にライブラリを試しつつ、問題があればコンテナごと破棄する、という使い方ができるため、試行錯誤がとても快適になります。

docker-composeでPython開発環境をさらにシンプルに

docker-compose.ymlでPythonサービスを定義する

Dockerコマンドを毎回手入力するのは面倒になりがちです。

そこで、docker-compose.ymlを使って設定をファイル化すると、環境構築がさらにシンプルになります。

まずは、単一のPythonサービスを定義した最小構成の例を示します。

YAML
# docker-compose.yml
version: "3.9"

services:
  app:
    image: python:3.12-slim      # ベースイメージ
    working_dir: /app            # コンテナ内の作業ディレクトリ
    volumes:
      - ./:/app                  # カレントディレクトリをマウント
    command: bash -c "pip install --no-cache-dir -r requirements.txt && python app.py"
    stdin_open: true             # 対話的な入出力を許可
    tty: true                    # 擬似端末を割り当て

この定義では、docker compose upを実行するだけで、次の処理が自動的に行われます。

  1. Python 3.12 slimイメージを取得(なければ自動ダウンロード)
  2. カレントディレクトリを/appとしてマウント
  3. pip install -r requirements.txtで依存パッケージをインストール
  4. python app.pyを実行

手で長いdocker runコマンドを書く代わりに、設定をファイル化して再利用できる点が大きなメリットです。

docker compose upだけで環境を立ち上げる手順

先ほどのdocker-compose.ymlがあるディレクトリで、次のコマンドを実行します。

Shell
docker compose up

(古い環境ではdocker-compose upというコマンド名の場合もあります。)

これにより、定義されたappサービスが起動し、ログがターミナルに表示されます。

実行を止めたい場合は、Ctrl + Cで中断すればコンテナが停止します。

バックグラウンドで動かしたい場合は、-dオプションを付けます。

Shell
docker compose up -d

この場合、コンテナはバックグラウンドで動作し続けるので、別のターミナルからログを確認したり、コンテナに入って作業したりできます。

デバッグやログ確認の基本コマンド

docker composeを使うと、複数のコンテナをまとめて扱えるだけでなく、デバッグ用のコマンドも非常に分かりやすくなります。

代表的なものをいくつか紹介します。

Shell
# 起動中コンテナの一覧
docker compose ps

# ログの確認 (appサービスのみ)
docker compose logs app

# ログをリアルタイムで追いかける
docker compose logs -f app

# appサービスのコンテナに入って対話的に操作
docker compose exec app bash

# すべてのコンテナを停止
docker compose stop

# すべてのコンテナとネットワークを削除
docker compose down

特にdocker compose exec app bashは、実行中のコンテナに入って、その場でpip installやpythonの実行ができるため、デバッグ時に非常に便利です。

チーム開発でのDocker環境共有のポイント

Dockerとdocker-composeを組み合わせることで、チーム開発における「環境差異問題」を大幅に軽減できます。

ポイントは、環境構築に必要な情報をすべてリポジトリに含めることです。

具体的には、次のファイルをGitなどのバージョン管理に含めます。

  • Dockerfile
  • docker-compose.yml
  • requirements.txt (もしくはpoetry.lockなど)
  • 必要に応じて.envファイルの雛形

これにより、新しいメンバーが参加したときの手順は、基本的に次の2ステップで済むようになります。

  1. リポジトリをクローンする
  2. プロジェクトディレクトリでdocker compose upを実行する

こうすることで、「Pythonのバージョンが違った」「ローカルにインストールしたライブラリのバージョンが微妙に違った」といった典型的なトラブルを回避できます。

さらに、本番環境も同じDockerイメージをベースに構築すれば、開発・ステージング・本番の差異も小さく抑えられます。

まとめ

Dockerを使ったPython開発環境の構築は、一度仕組みを理解してしまえば「venvいらずでどこでも同じ環境を再現できる強力な方法」になります。

Python公式イメージを選び、Dockerfileとrequirements.txtで環境を定義し、docker build・docker runで動作確認を行う流れが基本です。

さらにdocker-compose.ymlを用意すれば、docker compose upだけで開発環境を立ち上げられ、チーム全員が同じコマンド・同じ挙動で開発できるようになります。

ローカル環境を汚さず、安心して試行錯誤できるDockerベースのPython開発フローを、ぜひ自身のプロジェクトでも取り入れてみてください。

クラウドSSLサイトシールは安心の証です。

URLをコピーしました!