🐳

docker-compose で Django×Nginx を起動するローカル環境構築

に公開

docker-compose で Django×Nginx を起動するローカル環境構築

Django × Tailwind の開発環境を「docker-compose 一発」で起動できるようにする手順をまとめました。
本構成では、Nginx リバースプロキシ + ASGI(Gunicorn + Uvicorn Worker)構成で Django を動かし、静的ファイルは Nginx から直接配信します。


🎯 ゴール

Docker Compose 一式で以下が動く状態を目指します:

  • Nginx(ポート80)で / をアプリにプロキシ、/static/ は直接配信
  • Django(ASGI構成)を gunicorn + uvicorn_worker で起動
  • Tailwind CSS をビルドして collectstatic した静的ファイルを Nginx で配信
  • uv による Python 依存固定・同期

🧩 扱う内容と扱わない内容

扱うこと

  • docker-compose による起動構成
  • Nginx リバースプロキシの最小設定
  • ASGI(Gunicorn + Uvicorn Worker)による Django 起動
  • 静的ファイル配信 + Tailwind のビルド
  • uv による依存管理

扱わないこと

  • メール関連設定
  • 本番運用セキュリティ設定(SSL 等)
  • 大容量ファイルや保護メディア配信

🏗️ 全体構成イメージ

[Client]
   ↓
[Nginx :80]
  ├── /static/ → /staticfiles/ (直接配信)
  └── /        → proxy → [web:8000]
                      ↑
                Gunicorn + UvicornWorker
                      ↑
                  Django (ASGI)

⚙️ docker-compose.yml

nginx がフロントを受け、web が Django を起動します。

services:
  nginx:
    image: nginx:alpine
    container_name: django-tailwindcss-auth-nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./staticfiles:/staticfiles

  web:
    build: .
    container_name: django-tailwindcss-auth-web
    command: uv run gunicorn config.asgi:application -k uvicorn_worker.UvicornWorker --bind 0.0.0.0:8000
    volumes:
      - .:/app
    env_file:
      - .env
    networks:
      - django-tailwindcss-auth-network

networks:
  django-tailwindcss-auth-network:
    driver: bridge

🐍 Dockerfile(ASGI起動)

uv で依存をロックし、Gunicorn + UvicornWorker で Django を起動します。

FROM ghcr.io/astral-sh/uv:0.8.22-python3.12-trixie-slim

ARG APP_HOME=/app
WORKDIR ${APP_HOME}

COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

COPY . .
CMD ["uv", "run", "gunicorn", "config.asgi:application", "-k", "uvicorn_worker.UvicornWorker"]

🌐 Nginx 設定(静的ファイル配信 + プロキシ)

nginx.conf のポイントは /static/ の alias とアプリへのプロキシ。

events {}

http {
    upstream web {
        server web:8000;
    }

    server {
        listen 80;

        location /static/ {
            alias /staticfiles/;
        }

        location / {
            proxy_pass http://web:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

⚡ Django 側設定(settings.py

STATIC_URL = "static/"
STATICFILES_DIRS = [BASE_DIR / "static"]
STATIC_ROOT = BASE_DIR / "staticfiles"

開発用の静的ファイルは static/
collectstatic 後の配信ディレクトリは staticfiles/ にまとめます。


🎨 Tailwind ビルド

Tailwind は npm 経由でビルド。
開発中は --watch モードを使うと便利です。

# ビルド(監視あり)
npm run build

必要に応じて --minify を追加して本番向けに最小化。


🚀 起動手順

  1. 依存の同期(初回のみ)
    Docker ビルド時に uv sync --frozen --no-dev が実行されます。

  2. Tailwind のビルド
    別ターミナルで

    npm run build
    
  3. コンテナ起動

    docker compose up --build -d
    
  4. アクセス確認


🧱 よくあるハマりどころ

症状 原因と対処
CSS が反映されない Tailwind のビルド忘れ
/static/ が 404 collectstatic 未実行 or STATIC_URL 不一致
Nginx の alias が反映されない location /static/ と Django 側設定の整合を確認

✅ まとめ

  • Django × Tailwind のローカル環境を docker-compose で再現
  • ASGI構成(Gunicorn + UvicornWorker) により非同期対応
  • 静的ファイルは Nginx 配信依存は uv で固定
  • 開発環境を本番構成に近づけつつ、軽量で再現性の高い構成にできます。

Discussion