Jiwon Min Developer

本番環境に匹敵するローカル開発環境をDocker Composeで構築する

「私のPCではちゃんと動くのですが…」開発者なら一度は経験したことがある、あるいは口にしたことがある言葉でしょう。開発環境と実際のサービスが稼働する本番環境の微妙な違いは、予期せぬバグやデプロイ失敗の主な原因となります。ライブラリのバージョン、オペレーティングシステム、システム設定など、無数の変数が存在するためです。このような問題を解決するために登場した技術が、まさにDockerです。

Dockerは、アプリケーションとそれに必要なすべての依存関係を「コンテナ」という隔離された空間にパッケージングし、どの環境でも同じように実行されることを保証します。これにより、開発者は本番環境とほぼ同一の環境をローカルPCに簡単に構築でき、チームメンバーと一貫した開発環境を共有できます。本稿では、Docker Composeを使用して、Python Djangoウェブフレームワーク、PostgreSQLデータベース、Redisキャッシュサーバーで構成されるマルチコンテナ開発環境を構築する実践的な方法をステップバイステップでご案内します。

Building a Production-Ready Local Development Environment with Docker Compose

© AI Generated by Imagen 4.0


なぜDockerを使うべきか?

本格的な構築に入る前に、Dockerを使用する理由を明確にしておきましょう。

  • 環境の一貫性: Dockerは、アプリケーションの実行に必要なすべて(コード、ランタイム、システムツール、ライブラリなど)を一つのコンテナイメージにまとめます。このイメージを通じて、開発、ステージング、本番環境のすべてで同じ環境が保証され、「環境の違いによる」バグを根本的に防ぎます。
  • 隔離された環境: 各コンテナはホストシステムや他のコンテナから隔離されて実行されます。これにより、複数のプロジェクトで異なるバージョンのライブラリやデータベースが互いに衝突する問題を回避できます。
  • 迅速な構築とデプロイ: Dockerfiledocker-compose.ymlというコードベースの設定ファイルを通じて、開発環境の構築を自動化できます。新しいチームメンバーが加わっても、複雑なインストールプロセスなしに、いくつかのコマンドだけで開発環境全体を即座に構築できます。
  • クラウドフレンドリー: AWSのECS (Elastic Container Service)EKS (Elastic Kubernetes Service)のような現代的なクラウドサービスは、すべてコンテナベースで動作します。ローカルでDockerを使用することは、クラウドへのデプロイパイプラインへの第一歩です。

プロジェクト構造の設計

効率的な管理のため、以下のようなディレクトリ構造でプロジェクトを開始します。

my-project/
├── .env          # 環境変数ファイル
├── docker-compose.yml # Docker Compose設定ファイル
└── app/
    ├── Dockerfile    # Djangoアプリ用のDockerfile
    ├── manage.py
    ├── myproject/
    │   ├── settings.py
    │   └── ...
    └── requirements.txt # Python依存関係リスト

ステップ1:DjangoアプリケーションのDockerfileを作成する

まず、Djangoアプリケーションを実行するコンテナイメージを定義するDockerfileを作成します。このファイルはapp/ディレクトリ内に配置します。

app/Dockerfile

# 1. ベースイメージの選択
FROM python:3.11-slim

# 2. Python関連の環境変数を設定
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# 3. 作業ディレクトリの作成と設定
WORKDIR /app

# 4. 依存関係ファイルのコピーとインストール
COPY requirements.txt .
RUN pip install --upgrade pip && pip install -r requirements.txt

# 5. アプリケーションコードのコピー
COPY . .

# 6. Django開発サーバーの実行
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

app/requirements.txt

Django>=4.2
psycopg2-binary
redis
gunicorn

上記のDockerfileは、Python 3.11イメージをベースに、必要なパッケージをインストールし、アプリケーションコードをコピーした後、開発サーバーを実行するプロセスを定義しています。

ステップ2:Docker Composeでサービスをオーケストレーションする

次に、プロジェクトのルートディレクトリにdocker-compose.ymlファイルを作成し、複数のサービス(ウェブ、データベース、キャッシュ)を一度に定義して連携させます。

docker-compose.yml

version: '3.8'

services:
  # 1. Djangoウェブサービス
  web:
    build:
      context: ./app
      dockerfile: Dockerfile
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - ./app:/app  # ローカルコードとコンテナ内部コードをリアルタイムで同期
    ports:
      - "8000:8000" # ホストの8000番ポートとコンテナの8000番ポートを接続
    env_file:
      - ./.env      # 環境変数ファイルをロード
    depends_on:
      - db
      - redis

  # 2. PostgreSQLデータベースサービス
  db:
    image: postgres:15
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    environment:
      - POSTGRES_DB=${SQL_DATABASE}
      - POSTGRES_USER=${SQL_USER}
      - POSTGRES_PASSWORD=${SQL_PASSWORD}

  # 3. Redisキャッシュサービス
  redis:
    image: redis:7

volumes:
  postgres_data: # データベースデータを永続的に保存するためのボリューム

この設定ファイルは、webdbredisという3つのサービスを定義します。

  • webapp/Dockerfileをビルドして生成され、ローカルのappディレクトリをコンテナ内の/appにマウントすることで、コードの変更が即座に反映されるようにします。
  • db:公式のPostgreSQLイメージを使用し、コンテナが削除されてもデータが保持されるようにpostgres_dataというボリューム(volume)を使用します。
  • redis:公式のRedisイメージを使用します。
  • depends_onwebサービスがdbredisサービスの起動後に開始されるように依存関係を設定します。

ステップ3:環境変数の管理(.envファイル)

データベースの接続情報のような機密情報は、コードに直接書き込む代わりに環境変数を使用することが安全で望ましい方法です。プロジェクトのルートに.envファイルを作成します。

.env

# PostgreSQL Settings
SQL_DATABASE=mydb
SQL_USER=myuser
SQL_PASSWORD=mypassword

# Django Settings
SECRET_KEY=your-django-secret-key-here
DEBUG=1

このように分離された環境変数は、docker-compose.ymlenv_fileディレクティブを通じてwebサービスに注入されます。Djangoのsettings.pyでは、os.environ.get()を使用してこれらの値を読み込むように修正する必要があります。

実行と検証

すべての設定が完了しました。ターミナルで次のコマンドを実行して、開発環境全体を起動します。

# コンテナイメージをビルドして実行(バックグラウンドで実行するには-dオプションを追加)
docker-compose up --build

# 実行中のコンテナ一覧を確認
docker-compose ps

# Djangoデータベースのマイグレーションを実行
docker-compose exec web python manage.py migrate

docker-compose upコマンドが正常に実行されたら、ウェブブラウザでhttp://localhost:8000にアクセスし、DjangoアプリケーションがPostgreSQLデータベースおよびRedisと連携して正常に動作することを確認できます。コードを修正した後は、別途ビルドプロセスなしで変更が即座にコンテナに反映されます。

このようにDocker Composeを活用すれば、複雑なマルチサービスアーキテクチャもいくつかの設定ファイルとコマンドで簡単に管理できます。これは個人プロジェクトだけでなく、複数の開発者が協業するチームプロジェクトにおいて、開発環境の標準化を実現し、生産性を最大化する強力なツールとなるでしょう。また、このようにコンテナ化されたアプリケーションは、将来的にAWSのようなクラウド環境へ移行する際に非常に有利な立場を築くことができます。

参考文献