Strapi CMSのDocker化:PostgreSQLとDocker Composeを使用したプロフェッショナルなHeadless CMSの構築

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

なぜ今、StrapiをDocker化すべきなのか?

Strapiは優れたHeadless CMSですが、デプロイのたびにNode.jsやPostgreSQLのバージョンを手動で設定するのは非常に手間がかかります。以前、ローカル環境とUbuntuサーバー間のライブラリバージョンの不一致を修正するだけで、午前中を丸々潰してしまったことがあります。Dockerは、まさに「自分のマシンでは動くのに」という悩みを根本から解決してくれます。

実務経験から言うと、Strapiはかなりリソースを消費します。2GB RAMのVPSでは、ビルドプロセスがシステムをフリーズさせてしまうこともあります。Multi-stage buildを活用することで、イメージサイズを1.2GBから約450MBまで削減できました。これにより、帯域幅の節約だけでなく、CI/CDの速度も3倍に向上します。

標準的なプロジェクト構造の作成

まずは新しいStrapiプロジェクトを作成しましょう。実案件では、SQLiteよりも負荷耐性とデータ整合性に優れたPostgreSQLを優先的に使用します。

npx create-strapi-app@latest my-project --quickstart --no-run

最適化されたディレクトリ構造は以下のようになります:

.
├── strapi-app/
│   ├── Dockerfile
│   ├── .dockerignore
│   └── ... (ソースコード)
├── docker-compose.yml
└── .env

最適なDockerfileの構築(Multi-stage build)

このプロセスの核心はDockerfileにあります。すべてのビルドツールを最終イメージに含めるのではなく、「Build」と「Runtime」の2つのステージに分けます。この手法により、不要な依存関係を排除し、本番環境を常にクリーンで軽量に保つことができます。

strapi-app/ ディレクトリに Dockerfile を作成します:

# ステージ 1: ビルド
FROM node:18-alpine as build
RUN apk update && apk add --no-cache build-base gcc autoconf automake zlib-dev libpng-dev vips-dev git
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

WORKDIR /opt/
COPY package.json package-lock.json ./
RUN npm install -g node-gyp
RUN npm config set fetch-retry-maxtimeout 600000 -g && npm install --only=production

WORKDIR /opt/app
COPY . .
RUN npm run build

# ステージ 2: 実行環境
FROM node:18-alpine
RUN apk add --no-cache vips-dev
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}

WORKDIR /opt/
COPY --from=build /opt/node_modules ./node_modules
WORKDIR /opt/app
COPY --from=build /opt/app ./

EXPOSE 1337
CMD ["npm", "run", "start"]

重要な注意点: .dockerignore ファイルを忘れないでください。ローカルの node_modules ディレクトリを誤ってコンテナにコピーしてしまうと、sharp のようなネイティブライブラリがOSアーキテクチャの違いにより即座にエラーを起こします。

Docker ComposeによるStrapiとPostgreSQLの連携

Strapiには、データベースの起動が完了していないと頻繁にクラッシュするという「癖」があります。これを解決するために、healthcheck メカニズムを使用します。Docker Composeは、PostgreSQLが完全に準備できるまで待機してからStrapiコンテナを起動します。

ルートディレクトリにある docker-compose.yml の内容は以下の通りです:

version: '3.8'

services:
  strapi-db:
    image: postgres:15-alpine
    container_name: strapi-db
    env_file: .env
    volumes:
      - strapi-data:/var/lib/postgresql/data
    healthcheck:
      # データベースが準備できているか確認
      test: ["CMD-SHELL", "pg_isready -U $${DATABASE_USERNAME} -d $${DATABASE_NAME}"]
      interval: 10s
      timeout: 5s
      retries: 5

  strapi-app:
    container_name: strapi-app
    build: 
      context: ./strapi-app
    depends_on:
      strapi-db:
        condition: service_healthy
    env_file: .env
    ports:
      - "1337:1337"
    volumes:
      - ./strapi-app/uploads:/opt/app/public/uploads

volumes:
  strapi-data:

安定運用のための実践的なテクニック

1. ユーザーデータの保護

コンテナ内のデータは、イメージを更新すると消失します。Strapiでは、uploads ディレクトリにすべての画像やドキュメントが保存されます。データ消失を防ぐため、Composeファイルで行ったように、このディレクトリを必ず外部ボリュームにマッピングしてください。

2. 低スペックサーバー向けのRAM最適化

低価格なVPS(DigitalOceanの$6プランやLinodeの1GBプランなど)にデプロイする場合は、Node.jsのRAM使用量を制限しましょう環境変数 NODE_OPTIONS=--max-old-space-size=1024 を追加することで、Strapiがメモリを使い果たしてサーバーがダウンするのを防げます。

3. 開発環境のワークフロー

ローカルでコードを書く際は、ホットリロード機能が必要です。本番用のDockerfileを使用する代わりに、コードを直接コンテナにマウントして npm run develop コマンドを実行します。これにより、イメージを再ビルドすることなく、変更を即座に反映できます。

システムのデプロイ

準備が整いました。あとは次のコマンドを1つ実行するだけで、システム全体が起動します:

docker-compose up -d --build

Dockerがイメージをダウンロードし、ソースコードをビルドするまで約2分待ちます。その後、http://localhost:1337/admin にアクセスして最初の管理者アカウントを作成してください。おめでとうございます!これであなたのCMSは、隔離され、安全で、非常にスケーラブルな環境に構築されました。

Share: