T-CREATOR

Python Dev Containers 完全レシピ:再現可能な開発箱を VS Code で作る

Python Dev Containers 完全レシピ:再現可能な開発箱を VS Code で作る

「このプロジェクト、私の環境では動かないんですけど…」そんなやり取り、もううんざりですよね。

Dev Containers を使えば、チーム全員が完全に同じ開発環境で作業できるようになります。Python のバージョン違い、依存パッケージの不一致、OS の違いによるトラブル——こうした問題から解放される開発体験を、この記事で手に入れていきましょう。

この記事では、VS Code の Dev Containers を使って、Python プロジェクトの再現可能な開発環境を構築する方法を、基礎から実践まで段階的に解説していきます。

背景

Dev Containers が解決する開発環境の課題

従来の開発環境構築では、開発者ごとに異なる OS、Python バージョン、システムライブラリのバージョンが原因で、「ローカルでは動くのに本番では動かない」「新しいメンバーの環境構築に 1 日かかる」といった問題が頻発していました。

Dev Containers は、Docker コンテナ内で開発環境を完全に定義し、VS Code から直接アクセスできるようにする技術です。これにより、環境構築の手順書は不要になり、プロジェクトをクローンして VS Code で開くだけで、誰でも同じ環境で開発を始められるようになります。

以下の図は、Dev Containers を使った開発環境の基本構造を示しています。

mermaidflowchart TB
    dev["開発者のマシン<br/>(Windows/Mac/Linux)"]
    vscode["VS Code"]
    container["Dev Container<br/>(Docker)"]
    project["プロジェクトコード"]

    dev -->|起動| vscode
    vscode -->|接続| container
    container -->|マウント| project

    subgraph docker["Docker 環境"]
        container
        python["Python 3.12"]
        libs["システムライブラリ"]
        packages["pip パッケージ"]
    end

この図が示すように、開発者のローカルマシンの違いに関わらず、全員が同じ Docker コンテナ内で開発作業を行うため、環境の違いによる問題が発生しません。

Dev Containers の主要な利点

Dev Containers を導入することで、以下のようなメリットが得られます。

#利点詳細
1環境の完全な再現性Dockerfile と設定ファイルで環境が定義されるため、誰が、いつ、どこで構築しても同じ環境になる
2高速なオンボーディング新メンバーは VS Code でプロジェクトを開くだけで、すぐに開発を開始できる
3クリーンな分離プロジェクトごとに独立した環境を持つため、システムを汚さず、依存関係の競合もない
4本番環境との一致Docker を使うことで、本番環境に近い条件で開発・テストできる

課題

従来の Python 開発環境構築における問題点

Dev Containers を使わない場合、Python プロジェクトでは次のような課題に直面します。

Python バージョン管理の複雑さ

pyenv や asdf などのバージョン管理ツールを使っても、OS ごとにインストール方法が異なり、チームメンバー全員が同じバージョンを使っている保証はありません。

システムレベル依存関係の問題

機械学習プロジェクトで必要な CUDA、OpenCV のようなシステムライブラリは、インストール手順が複雑で、OS によって大きく異なります。これらを手動でセットアップすると、環境構築だけで数時間から数日かかることも珍しくありません。

環境構築手順書のメンテナンス負担

詳細な手順書を作成しても、OS のアップデート、ツールのバージョンアップにより、すぐに古くなってしまいます。手順書の更新作業自体が大きな負担となります。

以下の図は、従来の環境構築と Dev Containers の違いを示しています。

mermaidflowchart LR
    subgraph traditional["従来の方法"]
        dev1["開発者A<br/>(Mac)"]
        dev2["開発者B<br/>(Windows)"]
        dev3["開発者C<br/>(Linux)"]

        dev1 -.->|異なる手順| env1["環境A"]
        dev2 -.->|異なる手順| env2["環境B"]
        dev3 -.->|異なる手順| env3["環境C"]
    end

    subgraph devcontainer["Dev Containers"]
        dev4["開発者A"]
        dev5["開発者B"]
        dev6["開発者C"]

        dev4 -->|同じ手順| container["同一コンテナ環境"]
        dev5 -->|同じ手順| container
        dev6 -->|同じ手順| container
    end

この図から分かるように、従来の方法では各開発者が異なる環境を構築する一方、Dev Containers では全員が同じコンテナ環境にアクセスするため、環境の一貫性が保証されます。

具体的なエラー事例

Python プロジェクトでよく遭遇するエラーとして、以下のようなものがあります。

エラーコード: ModuleNotFoundError

pythonModuleNotFoundError: No module named 'numpy'

発生条件: ローカル環境で pip install を実行したが、別の Python バージョンにインストールされてしまった場合

エラーコード: ImportError

pythonImportError: libGL.so.1: cannot open shared object file: No such file or directory

発生条件: OpenCV を使用するプロジェクトで、システムレベルのグラフィックライブラリがインストールされていない場合

これらのエラーは、Dev Containers で環境を統一することで完全に防げます。

解決策

Dev Containers による統一開発環境の実現

Dev Containers を使うことで、Docker コンテナ内に Python 実行環境、必要なシステムライブラリ、VS Code 拡張機能まで含めた完全な開発環境を定義できます。

設定は .devcontainer ディレクトリ内のファイルで管理され、Git にコミットすることで、チーム全体で共有されます。

Dev Containers の構成要素

Dev Containers は、主に以下のファイルで構成されます。

#ファイル名役割
1.devcontainer​/​devcontainer.jsonコンテナの設定、VS Code 拡張機能、起動コマンドなどを定義
2.devcontainer​/​DockerfilePython バージョン、システムパッケージ、環境変数などを定義
3.devcontainer​/​requirements.txtPython パッケージの依存関係を定義
4.devcontainer​/​docker-compose.yml(オプション)データベースなど複数のサービスが必要な場合に使用

以下の図は、Dev Containers の起動フローを示しています。

mermaidsequenceDiagram
    participant user as 開発者
    participant vscode as VS Code
    participant docker as Docker
    participant container as Dev Container

    user->>vscode: プロジェクトを開く
    vscode->>vscode: .devcontainer を検出
    vscode->>user: "Reopen in Container" を提示
    user->>vscode: コンテナで再起動
    vscode->>docker: Dockerfile をビルド
    docker->>container: コンテナ起動
    vscode->>container: リモート接続
    container->>vscode: 開発環境準備完了
    vscode->>user: 開発開始可能

この図が示すように、開発者はプロジェクトを開いてコンテナで再起動するだけで、あとは自動的に環境が構築されます。

基本的な実装ステップ

Dev Containers を導入する基本的な手順は以下の通りです。

  1. VS Code に Dev Containers 拡張機能をインストール
  2. Docker Desktop をインストールして起動
  3. プロジェクトに .devcontainer ディレクトリを作成
  4. devcontainer.jsonDockerfile を配置
  5. VS Code でプロジェクトをコンテナ内で再起動

次のセクションで、具体的なコード例を見ていきましょう。

具体例

前提条件の確認

まず、開発環境に以下がインストールされていることを確認してください。

#ツール確認方法
1VS Code公式サイトからダウンロード
2Docker Desktop公式サイトからダウンロード
3Dev Containers 拡張機能VS Code の拡張機能検索で "Dev Containers" をインストール

ステップ 1: プロジェクトディレクトリの準備

まず、Python プロジェクトのルートディレクトリで作業を開始します。

bash# プロジェクトディレクトリに移動
cd your-python-project

# .devcontainer ディレクトリを作成
mkdir .devcontainer

このディレクトリに、Dev Containers の設定ファイルを配置していきます。

ステップ 2: devcontainer.json の作成

.devcontainer​/​devcontainer.json ファイルを作成し、コンテナの基本設定を定義します。

json{
  "name": "Python 3.12 開発環境",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  }
}

この設定では、コンテナの名前と、使用する Dockerfile の場所を指定しています。context.. にすることで、プロジェクトルートをビルドコンテキストとして使用します。

次に、VS Code の拡張機能を自動インストールする設定を追加します。

json{
  "name": "Python 3.12 開発環境",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-python.black-formatter",
        "charliermarsh.ruff"
      ]
    }
  }
}

これらの拡張機能は、コンテナ起動時に自動的にインストールされます。Pylance は型チェックとコード補完、Black はコードフォーマッター、Ruff は高速なリンターです。

さらに、VS Code のエディタ設定を追加します。

json{
  "name": "Python 3.12 開発環境",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-python.black-formatter",
        "charliermarsh.ruff"
      ],
      "settings": {
        "python.defaultInterpreterPath": "/usr/local/bin/python",
        "python.linting.enabled": true,
        "python.formatting.provider": "black",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
          "source.organizeImports": true
        }
      }
    }
  }
}

このエディタ設定により、ファイル保存時に自動的にコードフォーマットとインポート整理が実行されます。

最後に、コンテナ起動後に実行するコマンドを追加します。

json{
  "name": "Python 3.12 開発環境",
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-python.black-formatter",
        "charliermarsh.ruff"
      ],
      "settings": {
        "python.defaultInterpreterPath": "/usr/local/bin/python",
        "python.linting.enabled": true,
        "python.formatting.provider": "black",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
          "source.organizeImports": true
        }
      }
    }
  },
  "postCreateCommand": "pip install -r requirements.txt",
  "remoteUser": "vscode"
}

postCreateCommand は、コンテナ作成後に一度だけ実行されます。ここで依存パッケージをインストールすることで、環境の準備が自動的に完了します。

ステップ 3: Dockerfile の作成

次に、.devcontainer​/​Dockerfile を作成し、Python 環境を定義します。

まず、ベースイメージを指定します。

dockerfile# Python 3.12 の公式イメージを使用
FROM python:3.12-slim

slim バージョンは、必要最小限のパッケージのみを含む軽量なイメージです。ビルド時間とイメージサイズを削減できます。

次に、システムパッケージをインストールします。

dockerfile# システムパッケージの更新と必要なツールのインストール
RUN apt-get update && apt-get install -y \
    git \
    curl \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

build-essential は、C 拡張を含む Python パッケージ(NumPy、Pandas など)のビルドに必要です。rm -rf ​/​var​/​lib​/​apt​/​lists​/​* で、パッケージリストのキャッシュを削除し、イメージサイズを削減しています。

開発用のユーザーを作成します。

dockerfile# 開発用ユーザーの作成
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID

RUN groupadd --gid $USER_GID $USERNAME \
    && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME \
    && apt-get update \
    && apt-get install -y sudo \
    && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
    && chmod 0440 /etc/sudoers.d/$USERNAME

root ユーザーで作業するのはセキュリティ上好ましくないため、専用ユーザーを作成します。このユーザーは sudo 権限を持つため、必要に応じて管理者操作も可能です。

Python ツールをインストールします。

dockerfile# Python 開発ツールのインストール
RUN pip install --no-cache-dir \
    black \
    ruff \
    pytest \
    pytest-cov \
    mypy

--no-cache-dir オプションで、pip のキャッシュを保存しないようにし、イメージサイズを削減します。

作業ディレクトリを設定します。

dockerfile# 作業ディレクトリの設定
WORKDIR /workspace

# ユーザーを切り替え
USER $USERNAME

これで、基本的な Python Dev Container 環境が完成します。

ステップ 4: requirements.txt の作成

プロジェクトのルートディレクトリに requirements.txt を作成し、Python パッケージの依存関係を定義します。

text# Web フレームワーク
flask==3.0.0
requests==2.31.0

# データ処理
numpy==1.26.0
pandas==2.1.0

# テスト
pytest==7.4.0
pytest-cov==4.1.0

このファイルは、postCreateCommand で自動的にインストールされます。バージョンを固定することで、環境の再現性が保証されます。

ステップ 5: コンテナ起動と動作確認

VS Code でプロジェクトを開き、左下の緑色のアイコンをクリックして「Reopen in Container」を選択します。

初回起動時は、Docker イメージのビルドに数分かかりますが、2 回目以降はキャッシュが使われるため、数秒で起動します。

コンテナが起動したら、VS Code のターミナルで Python のバージョンを確認しましょう。

bashpython --version
# Python 3.12.x が表示されます

インストールされたパッケージも確認します。

bashpip list
# requirements.txt で指定したパッケージが表示されます

応用例 1: データベース付き環境の構築

Web アプリケーション開発では、データベースも含めた環境が必要になります。この場合、docker-compose.yml を使います。

.devcontainer​/​docker-compose.yml を作成します。

yamlversion: '3.8'

services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity
    network_mode: service:db

このサービス定義では、プロジェクトディレクトリをコンテナにマウントし、コンテナを起動し続けるために sleep infinity を実行しています。

データベースサービスを追加します。

yamlversion: '3.8'

services:
  app:
    build:
      context: ..
      dockerfile: .devcontainer/Dockerfile
    volumes:
      - ..:/workspace:cached
    command: sleep infinity
    network_mode: service:db

  db:
    image: postgres:16
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD: devpass
      POSTGRES_DB: devdb

volumes:
  postgres-data:

PostgreSQL データベースが、永続的なボリュームと共に起動します。network_mode: service:db により、app コンテナから localhost でデータベースにアクセスできます。

devcontainer.json を更新して、docker-compose を使うように変更します。

json{
  "name": "Python + PostgreSQL 開発環境",
  "dockerComposeFile": "docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/workspace",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-python.black-formatter",
        "mtxr.sqltools",
        "mtxr.sqltools-driver-pg"
      ]
    }
  },
  "postCreateCommand": "pip install -r requirements.txt"
}

SQLTools 拡張機能を追加することで、VS Code から直接データベースを操作できるようになります。

応用例 2: 機械学習開発環境の構築

機械学習プロジェクトでは、より多くのシステムライブラリが必要になります。Dockerfile を拡張しましょう。

dockerfile# CUDA をサポートする Python イメージを使用
FROM nvidia/cuda:12.2.0-cudnn8-devel-ubuntu22.04

# Python 3.12 のインストール
RUN apt-get update && apt-get install -y \
    software-properties-common \
    && add-apt-repository ppa:deadsnakes/ppa \
    && apt-get update \
    && apt-get install -y \
    python3.12 \
    python3.12-dev \
    python3-pip

CUDA 対応のベースイメージを使用し、その上に Python 3.12 をインストールします。

機械学習に必要なシステムライブラリを追加します。

dockerfile# 機械学習・画像処理用ライブラリのインストール
RUN apt-get install -y \
    libopencv-dev \
    libgl1-mesa-glx \
    libglib2.0-0 \
    && rm -rf /var/lib/apt/lists/*

これらのライブラリは、OpenCV や画像処理系のパッケージで必要になります。

requirements.txt も機械学習用に更新します。

text# 機械学習フレームワーク
torch==2.1.0
tensorflow==2.15.0
scikit-learn==1.3.0

# データ処理
numpy==1.26.0
pandas==2.1.0
matplotlib==3.8.0
seaborn==0.13.0

# Jupyter
jupyterlab==4.0.0
ipykernel==6.25.0

JupyterLab を含めることで、コンテナ内でノートブックを使った実験も可能になります。

トラブルシューティング

Dev Containers 使用時によくあるエラーと解決方法をまとめます。

エラーコード: Error: Docker is not running

textError response from daemon: dial unix docker.raw.sock: connect: no such file or directory

発生条件: Docker Desktop が起動していない場合

解決方法:

  1. Docker Desktop を起動する
  2. Docker が完全に起動するまで待つ(通常 30 秒〜1 分)
  3. VS Code でコンテナを再起動する

エラーコード: Error: Failed to build image

textERROR [internal] load metadata for docker.io/library/python:3.12-slim

発生条件: ネットワーク接続の問題、または Docker Hub へのアクセスが制限されている場合

解決方法:

  1. インターネット接続を確認する
  2. プロキシ環境の場合、Docker Desktop のプロキシ設定を確認する
  3. Dockerfile のベースイメージが正しいか確認する

エラーコード: Error: Permission denied

textPermissionError: [Errno 13] Permission denied: '/workspace/file.txt'

発生条件: コンテナ内のユーザー権限とホスト側のファイル権限が一致していない場合

解決方法:

  1. Dockerfile の USER_UIDUSER_GID を、ホストユーザーの ID に合わせる
  2. Linux の場合、id -uid -g でユーザー ID とグループ ID を確認する
  3. devcontainer.json"remoteUser": "vscode" を追加する

図で理解できる要点

Dev Containers の構成要素:

  • devcontainer.json が VS Code の設定を管理
  • Dockerfile が Python 環境とシステムパッケージを定義
  • docker-compose.yml が複数サービスの連携を管理
  • すべての設定ファイルを Git で管理することで、チーム全体で環境を共有

環境構築のフロー:

  • 開発者はプロジェクトを開いて「Reopen in Container」を選択するだけ
  • Docker が自動的にイメージをビルドし、コンテナを起動
  • VS Code がコンテナに接続し、拡張機能と設定を自動適用
  • postCreateCommand で依存パッケージがインストールされ、すぐに開発開始可能

まとめ

Dev Containers を使うことで、Python プロジェクトの開発環境を完全にコード化し、チーム全体で共有できるようになります。

環境構築の手順書を書く必要も、新メンバーが環境構築で苦労することもなくなり、「私の環境では動く」問題から解放されます。VS Code と Docker さえあれば、プロジェクトを開いた瞬間から、全員が同じ環境で開発できるのです。

この記事で紹介した設定ファイルをベースに、プロジェクトの要件に合わせてカスタマイズしていけば、より生産的な開発環境を構築できるでしょう。

最初は設定ファイルの記述に戸惑うかもしれませんが、一度作成してしまえば、その後のプロジェクトでも再利用できます。ぜひ、次のプロジェクトから Dev Containers を導入してみてください。開発体験が劇的に向上することを実感していただけるはずです。

関連リンク