> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Django アプリを PostgreSQL と Redis で Docker コンテナ化する

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Postgres と Redis を使って Django アプリを Docker 化する" description="Devin がマルチステージ Dockerfile と、Django・PostgreSQL・Redis を含む docker-compose.yml を作成し、そのスタックをビルドして実行し、動作を検証します。" prompt="src/ 配下の Django API を Docker 化してください。データベースには PostgreSQL を、キャッシュと Celery のタスクキューには Redis を使用します。python:3.12-slim ベースのマルチステージ Dockerfile と、Django（gunicorn）、PostgreSQL 16、Redis 7、および Celery ワーカーを含む docker-compose.yml を用意してください。root 以外のユーザーで実行し、/api/health/ へのヘルスチェックを設定します。ビルドしてから docker-compose up を実行し、API が応答することを確認し、コンテナ内でテストスイートを実行してください。何か失敗した場合は、デバッグして修正し、すべてが動作するまで反復してください。スタック全体がクリーンに起動し、すべてのテストに合格するまで PR は作成しないでください。" category="機能開発" features="" />

<div className="uc-detail-wrapper">
  <Tip>手動でのセットアップが面倒ですか？このページのリンクを Devin のセッションに貼り付けて、すべてセットアップするよう依頼してください。</Tip>

  <Steps>
    <Step title="（任意）Ask Devin でプロジェクトのスコープを決める">
      Django アプリがどのサービスに依存しているかや、プロジェクト構成が分からない場合は、まず [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) を使って調査してください。

      <PromptBlock agent="ada">
        ```txt Scope the Django project for containerization theme={null}
        What does our Django app in src/ depend on?
        1. Which databases and caches does it connect to?
        2. Does it use Celery or any background workers?
        3. What's in requirements.txt or pyproject.toml?
        4. Are there any existing Docker files or deployment configs?
        5. How does the app handle static files and media?
        ```
      </PromptBlock>

      Ask Devin から直接 Devin セッションを開始することもでき、その場合は Ask Devin で取得した情報がコンテキストとしてすべて引き継がれます。
    </Step>

    <Step title="Devin に Django プロジェクトと requirements ファイルを渡す">
      Devin にコンテナ化したい Django プロジェクトを指定し、ベースイメージの希望、アプリが依存しているサービス、イメージサイズの制約など、特別な要件があれば伝えてください。Devin は `requirements.txt` や `pyproject.toml` を読み取り、残りを把握します。

      <PromptBlock>
        ```txt Postgres と Redis を使う Django API をコンテナ化する theme={null}
        src/ にある Django API をコンテナ化してください。データベースには
        PostgreSQL を、キャッシュと Celery のタスクキューには Redis を使います。

        - マルチステージの Dockerfile: 依存関係をビルダーステージでインストールし、
          venv のみをスリムな python:3.12-slim ランタイムイメージにコピーする
        - Django（gunicorn）、PostgreSQL 16、Redis 7 を含む docker-compose.yml
        - テスト、ドキュメント、.git、__pycache__ を除外する .dockerignore
        - 非 root ユーザーで実行する
        - /api/health/ へのヘルスチェック
        - Celery ワーカーを compose 内の別サービスとして定義する

        ## テストと検証
        - イメージをビルドして docker-compose up を実行する
        - すべてのサービスの状態が正常になるまで待つ
        - localhost:8000/api/health/ で API が応答することを確認する
        - コンテナ内で Django のテストスイートを実行する
        - ビルドエラー、環境変数の不足、接続問題、テスト失敗など、
          何か問題があればデバッグして修正する。スタック全体が問題なく起動し、
          すべてのテストが通るまで繰り返すこと。
        - すべてがエンドツーエンドで動作するまでは PR を作成しないこと
        ```
      </PromptBlock>
    </Step>

    <Step title="Devin は調査し、構築します">
      Devin は Django プロジェクトと依存関係ファイルを読み取り、ビルドプロセスを把握したうえで、Docker 用の設定を作成します:

      1. **依存関係ファイルを読む** — `requirements.txt` または `pyproject.toml` を解析し、Django、psycopg2、redis、celery、gunicorn を特定します
      2. **Dockerfile を作成する** — 依存関係をインストールするビルダーステージと、その仮想環境を最小限の `python:3.12-slim` ランタイムイメージにコピーするステージから成るマルチステージビルドを作成します

      ```dockerfile theme={null}
      # ---- ビルダー ----
      FROM python:3.12-slim AS builder
      WORKDIR /app
      COPY requirements.txt .
      RUN python -m venv /opt/venv \
          && /opt/venv/bin/pip install --no-cache-dir -r requirements.txt

      # ---- ランタイム ----
      FROM python:3.12-slim
      RUN groupadd -r django && useradd -r -g django django
      COPY --from=builder /opt/venv /opt/venv
      ENV PATH="/opt/venv/bin:$PATH"
      WORKDIR /app
      COPY src/ .
      RUN python manage.py collectstatic --noinput
      EXPOSE 8000
      USER django
      CMD ["gunicorn", "config.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "3"]
      ```

      3. **docker-compose.yml を作成** — Django、PostgreSQL、Redis、Celery ワーカーを追加し、ヘルスチェック、ボリューム、共有ネットワークを設定します

      ```yaml theme={null}
      services:
        web:
          build: .
          ports:
            - "8000:8000"
          env_file: .env
          depends_on:
            db:
              condition: service_healthy
            redis:
              condition: service_healthy
          healthcheck:
            test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health/')"]
            interval: 10s
            retries: 3

        db:
          image: postgres:16-alpine
          environment:
            POSTGRES_DB: app_db
            POSTGRES_USER: app_user
            POSTGRES_PASSWORD: app_pass
          volumes:
            - pgdata:/var/lib/postgresql/data
          healthcheck:
            test: ["CMD-SHELL", "pg_isready -U app_user -d app_db"]
            interval: 5s
            retries: 5

        redis:
          image: redis:7-alpine
          healthcheck:
            test: ["CMD", "redis-cli", "ping"]
            interval: 5s
            retries: 5

        celery:
          build: .
          command: celery -A config worker -l info
          env_file: .env
          depends_on:
            db:
              condition: service_healthy
            redis:
              condition: service_healthy

      volumes:
        pgdata:
      ```

      4. **`.dockerignore` を追加** — ビルドコンテキストに含める必要のないファイルを除外します (`__pycache__`、`.git`、`tests/`、`docs/`、`*.pyc`)
      5. **`docker compose up --build` を実行** — イメージをビルドし、Devin のターミナルですべてのサービスを起動します
      6. **アプリを検証** — `/api/health/` に対して curl コマンドを実行し、Django がクリーンに起動し、PostgreSQL に接続し、Redis にも接続できることを確認します
    </Step>

    <Step title="スラッシュコマンドでセッションを制御する">
      セッション中にスラッシュコマンドを使って、Devin のワークフローの進め方を調整します。

      * **`/plan`** — Devin に、Docker の設定を書く前に進め方を整理して説明するよう依頼します。計画を確認し、必要に応じて修正案を提案してください。
      * **`/test`** — Devin にコンテナー スタックを再ビルドして再検証するよう指示します。問題を早期に発見するため、変更のたびにこれを使ってください。
      * **`/review`** — Devin に、自身の Dockerfile と Compose 設定について、セキュリティ上の問題、イメージサイズ、およびベストプラクティスの観点から、PR を作成する前にレビューするよう依頼します。
    </Step>

    <Step title="検証と反復">
      Devin が PR を作成したら、生成されたファイルをレビューしてください。よくあるフォローアップの例:

      <PromptBlock>
        ```txt Optimize image size theme={null}
        Docker イメージが 520MB あります。サイズを縮小してください。不必要なファイルをコピーしていないことを確認し、venv から .pyc ファイルを削除し、最終イメージからは pip を除外してください。
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Add dev hot-reload theme={null}
        ローカル開発用に docker-compose.override.yml を追加し、ソースディレクトリをマウントして、gunicorn の代わりに自動リロード有効の Django の開発サーバーを実行してください。
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Add CI docker build theme={null}
        すべての PR に対して Docker イメージをビルドし、コンテナ内で pytest を実行し、main にマージされたときに ECR へプッシュする GitHub Actions ワークフローを作成してください。タグには git の SHA を付けてください。
        ```
      </PromptBlock>
    </Step>

    <Step title="Devin Review を使用して PR をレビューする">
      Devin が PR を作成したら、[Devin Review](https://app.devin.ai/review?utm_source=docs\&utm_medium=use-case-gallery) を使って Docker の設定をレビューします。Devin Review は、セキュリティ上の問題 (root での実行、シークレットの露出) 、ベストプラクティスが守られていない点 (`.dockerignore` がない、ヘルスチェックがない) 、既存のインフラとの不整合を検知できます。
    </Step>
  </Steps>
</div>
