はじめに

このガイドでは、Flask(Webフレームワーク)Gunicorn(WSGIサーバー)Docker(コンテナ化)を組み合わせて、本番環境に対応したWebアプリケーションを作成する方法を学びます。

必要な前提知識

  • Pythonの基本文法
  • コマンドラインの基本操作
  • Dockerの基本概念(推奨)

プロジェクト構成

最終的なディレクトリ構造は以下のようになります:

my_flask_app/
├── app.py                 # Flaskアプリケーション本体
├── requirements.txt       # Python依存パッケージ
├── Dockerfile            # Dockerイメージ定義
├── docker-compose.yaml   # Docker Compose設定
├── templates/            # HTMLテンプレート
│   ├── base.html
│   └── index.html
└── static/              # 静的ファイル
    ├── css/
    └── js/

ステップ1: Flaskアプリケーションの作成

プロジェクトフォルダの作成

mkdir my_flask_app
cd my_flask_app

app.py の作成

これがアプリケーションのメインファイルです。

#!/usr/bin/env python3
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html', 
                         title='Flask App',
                         message='Hello, World!')

@app.route('/about')
def about():
    return render_template('about.html')

@app.route('/api/health')
def health():
    return {'status': 'healthy'}, 200

if __name__ == '__main__':
    # 開発環境用
    app.run(host='0.0.0.0', port=5000, debug=True)

重要なポイント

  • @app.route('/'): URLパスとPython関数を紐付けるデコレータ
  • render_template(): HTMLテンプレートをレンダリング
  • host='0.0.0.0': すべてのネットワークインターフェースで待ち受け

ステップ2: テンプレートの作成

templates/base.html

すべてのページで共通するベーステンプレートを作成します。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}Flask App{% endblock %}</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <header>
        <h1>My Flask Application</h1>
        <nav>
            <a href="/">Home</a>
            <a href="/about">About</a>
        </nav>
    </header>
    
    <main>
        {% block content %}{% endblock %}
    </main>
    
    <footer>
        <p>© 2025 Flask App</p>
    </footer>
</body>
</html>

templates/index.html

{% extends "base.html" %}

{% block title %}Home - Flask App{% endblock %}

{% block content %}
<h2>{{ title }}</h2>
<p>{{ message }}</p>
{% endblock %}

ステップ3: 依存関係の定義

requirements.txt の作成

Pythonパッケージの依存関係を定義します。

Flask==3.0.0
gunicorn==23.0.0
Jinja2==3.1.2
MarkupSafe==2.1.3
Werkzeug==3.0.1

各パッケージの役割

  • Flask: Webフレームワーク本体
  • Gunicorn: 本番環境用のWSGIサーバー
  • Jinja2: テンプレートエンジン(Flaskに含まれる)
  • Werkzeug: WSGIユーティリティライブラリ

ステップ4: Dockerファイルの作成

Dockerfile

アプリケーションをコンテナ化するための設定です。

FROM python:3.12-slim

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

# 依存パッケージをコピーしてインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

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

# ポート8000を公開
EXPOSE 8000

# Gunicornで起動
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"]

Dockerfileの詳細解説

  • FROM python:3.12-slim: 軽量なPython 3.12イメージを使用
  • WORKDIR /app: コンテナ内の作業ディレクトリを設定
  • --no-cache-dir: キャッシュを保存せず、イメージサイズを削減
  • --workers 4: 4つのワーカープロセスで並列処理

ステップ5: Docker Composeの設定

docker-compose.yaml

複数のコンテナをまとめて管理するための設定です。

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: flask_app
    ports:
      - "8000:8000"
    volumes:
      - .:/app
    environment:
      - FLASK_ENV=production
    restart: always

  nginx:
    image: nginx:latest
    container_name: nginx_proxy
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
    depends_on:
      - web
    restart: always

設定の説明

  • ports: ホスト:コンテナのポートマッピング
  • volumes: ホストとコンテナ間でファイルを共有
  • depends_on: 起動順序を制御
  • restart: always: 障害時に自動再起動

ステップ6: アプリケーションの起動

開発環境での起動

# 仮想環境の作成
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# 依存パッケージのインストール
pip install -r requirements.txt

# 開発サーバーの起動
python app.py

ブラウザで http://localhost:5000 にアクセスします。

Dockerでの起動

# イメージのビルドと起動
docker compose up -d

# ログの確認
docker compose logs -f

# 停止
docker compose down

ブラウザで http://localhost:8000 にアクセスします。

ステップ7: Gunicornの詳細設定

gunicorn_config.py の作成

より詳細な設定が必要な場合、設定ファイルを作成します。

# gunicorn_config.py
import multiprocessing

# ワーカー数(CPUコア数 × 2 + 1 が推奨)
workers = multiprocessing.cpu_count() * 2 + 1

# ワーカークラス
worker_class = 'sync'

# バインドアドレス
bind = '0.0.0.0:8000'

# タイムアウト(秒)
timeout = 30

# アクセスログ
accesslog = '-'
errorlog = '-'

# ログレベル
loglevel = 'info'

# プロセス名
proc_name = 'flask_app'

設定ファイルの使用

gunicorn -c gunicorn_config.py app:app

本番環境へのデプロイ

セキュリティ設定

  • DEBUG=True は絶対に使わない
  • 環境変数でシークレットキーを管理
  • HTTPSを使用(次の記事で解説)

パフォーマンス最適化

  • ワーカー数の調整: CPU数に応じて設定
  • 静的ファイルの配信: Nginxで処理
  • キャッシュの利用: Redis等を活用

トラブルシューティング

ポートが使用中のエラー

# ポートを使用しているプロセスを確認
lsof -i :8000

# プロセスを終了
kill -9 [PID]

モジュールが見つからないエラー

# 依存パッケージを再インストール
pip install -r requirements.txt --force-reinstall

まとめ

この記事では、Flask + Gunicorn + Dockerを使った本番環境対応のWebアプリケーション構築方法を学びました。

学んだこと

  • Flaskアプリケーションの基本構造
  • Gunicornによる本番環境での実行
  • Dockerによるコンテナ化
  • Docker Composeでの複数コンテナ管理

次のステップ

次の記事では、ドメインとサーバーの契約方法を解説します。