Zenn
🖥️

Docker環境で簡単なウェブアプリのデプロイとSSL証明書を設定

2025/04/11に公開

背景

前回の記事ではホームサーバの構築について説明しましたが、今回はその続編として、ユニバーサルリンクのテスト環境を構築する一環として、Ubuntu上でのDocker環境構築を行い、Nginxを用いたWordPressのデプロイとSSL適用について解説します。

ユニバーサルリンクの動作には、SSL証明書の適用が必須であるため、Certbotを利用したSSL証明書の発行と自動更新の設定を行い、テスト環境として適切なHTTPS環境を整えます。

また、今回はNginxを使用する流れの中で、WordPressをデプロイし、動作確認を兼ねた簡単なウェブアプリの公開も行います。これにより、Nginx環境でのアプリケーションデプロイの流れや、Dockerを活用した運用方法についても理解を深めることができます。

本記事を通じて、ユニバーサルリンクのテスト環境に不可欠なSSLの適用方法や、Nginxを用いた環境構築の流れを学ぶことができると思います。

必要なもの

本記事は、以下の環境がすでに準備されていることを前提に進めます。

  • Ubuntu環境のサーバ
  • 外部からアクセス可能な環境(DDNS、ポートフォワーディング設定済み)

これらの環境は前回の記事で構築および設定済みであることを想定しています。もし未設定の場合は、前回の記事を参考にしながら進めていただくとスムーズかと思います。

Docker環境

  • Dockerインストール
  • Docker-Compose インストール

Dockerファイルの準備

ユニバーサルリンクのテスト環境を構築するため、Nginxを利用したWordPressのデプロイとSSL適用をDocker上で行います。そのため、まず Docker Composeを用いた環境構築 を行います。

この構成では、以下の4つのコンテナを使用します。

  • Nginx(リバースプロキシ)

    • クライアントからのリクエストを受け取り、WordPressのPHP-FPMコンテナへ転送する。
    • SSL証明書の適用やHTTPS対応も担当。
  • WordPress(PHP-FPM)

    • PHP-FPM(FastCGI Process Manager)を利用し、Nginxと連携してWordPressを動作させる。
  • MariaDB(データベース)

    • WordPressのデータ管理を行うデータベース。
    • volumes を利用し、データを永続化。
  • Certbot(SSL証明書管理)

    • Let's Encryptを利用し、SSL証明書の取得・更新を自動化。

各コンテナは共通のネットワーク(wp_network)上で連携し、Nginxをフロントエンドとして動作させます。

WordPressコンテナでFPMを使用する理由

WordPressコンテナには wordpress:6.7.2-php8.1-fpm イメージを使用します。通常の wordpress イメージではなく、FPM版を採用する理由は以下のとおりです。

  1. パフォーマンスの向上

    • PHP-FPMはFastCGIプロトコルを使用し、Nginxとの組み合わせでより効率的に処理を1行える。
    • 静的コンテンツ(画像・CSSなど)はNginxが処理し、PHPスクリプトのみをFPMに渡すことで負荷を分散。
  2. 拡張性と柔軟性

    • PHP-FPMとNginxを分離することで、PHPの設定やバージョン変更が容易 になる。
    • サーバーの負荷に応じてPHP-FPMのプロセス数を調整可能。
  3. セキュリティの向上

    • Apacheを含むWordPress公式イメージは、不要な機能が含まれやすい。
    • FPM版を使用することで、Nginxがリクエストを制御し、PHP処理のみをFPMに任せる構成 にできるため、セキュリティリスクを軽減。

このような理由から、FPM版を採用し、Nginxをフロントエンドとして利用する構成にしています。

完成したdocker-composeは以下のようになります。

docker-compose.yml
version: '3'

services:
  wordpress:
    image: wordpress:6.7.2-php8.1-fpm  # PHP-FPM版のWordPressイメージを使用
    container_name: wordpress
    depends_on:
      - db  # DBサービスが起動してから開始
    environment:
      WORDPRESS_DB_HOST: db  # データベースのホスト名
      WORDPRESS_DB_USER: wordpress  # データベースユーザー名
      WORDPRESS_DB_PASSWORD: mypassword  # データベースパスワード
      WORDPRESS_DB_NAME: wordpress  # 使用するデータベース名
    volumes:
      - ./docker-compose/wordpress:/var/www/html  # WordPressのデータをローカルと共有
    networks:
      - wp_network  # 共通ネットワーク

  db:
    image: mariadb:10.5  # MariaDBのイメージを使用
    container_name: wordpress_db
    environment:
      MYSQL_DATABASE: wordpress  # 初期データベース名
      MYSQL_USER: wordpress  # DBユーザー
      MYSQL_PASSWORD: mypassword  # DBパスワード
      MYSQL_ROOT_PASSWORD: rootpassword  # rootユーザーのパスワード
    volumes:
      - db_data:/var/lib/mysql  # データの永続化
    networks:
      - wp_network

  nginx:
    image: nginx:latest  # 最新のNginxイメージ
    container_name: nginx
    restart: always  # 常に再起動
    ports:
      - "80:80"   # HTTPポート
      - "443:443" # HTTPSポート
    volumes:
      - ./docker-compose/nginx:/etc/nginx/conf.d  # Nginx設定ファイルのマウント
      - ./docker-compose/certbot/conf:/etc/letsencrypt  # SSL証明書の保存先
      - ./docker-compose/certbot/www:/var/www/certbot  # ACMEチャレンジ用ディレクトリ
      - ./docker-compose/wordpress:/var/www/html  # WordPressの公開ディレクトリ
    networks:
      - wp_network

  certbot:
    image: certbot/certbot  # Certbotの公式イメージ
    volumes:
      - ./docker-compose/certbot/conf:/etc/letsencrypt  # 証明書の保存先
      - ./docker-compose/certbot/www:/var/www/certbot  # Web認証ファイルの格納先

volumes:
  db_data:  # DB用の永続ボリューム

networks:
  wp_network:  # サービス間の共通ネットワーク

nginx.confは以下となります。
ssl証明書発行前の設定になります。
docker-compose.ymlに書いてあるパスに配置します。

nginx.conf
server {
    listen 80;  # HTTPリクエストを受け付ける(SSL証明書発行のため)

    root /var/www/html;  # ドキュメントルートの指定(WordPressファイルがある場所)
    index index.php index.html index.htm;  # 優先的に読み込むファイル

    location / {
        try_files $uri $uri/ /index.php?$args;  # リクエストされたファイルが無い場合、index.phpへ
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;  # Certbotのチャレンジファイル用ディレクトリ
    }

    location ~ \.php$ {
        include fastcgi_params;  # FastCGIの基本パラメータを読み込む
        fastcgi_pass wordpress:9000;  # PHPリクエストをWordPress(FPM)コンテナに転送
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;  # 実行するPHPファイルのパス
    }

    location ~ /\.ht {
        deny all;  # .htaccessなどの隠しファイルへのアクセスを禁止
    }
}

Docker Composeによるビルドと起動

コンテナ構成の準備が整ったら、いよいよDocker Composeでコンテナ群をビルド・起動していきます。

まず、プロジェクトルート(docker-compose.yml があるディレクトリ)で以下のコマンドを実行します。

bash
docker-compose up -d

-dオプションを付けることで、バックグラウンド(デタッチドモード)でコンテナが起動されます。

起動後、以下のコマンドでコンテナの状態を確認してみましょう。

bash
docker-compose ps

各サービス(wordpress, db, nginxなど)がUp状態であれば、正常に起動していることを意味します。

次に、ブラウザを開き、サーバのIPアドレスまたはドメイン(例: http://example.ddns.net)にアクセスしてみてください。
正常に設定されていれば、WordPressの初期セットアップ画面 が表示されるはずです。

なお、certbotコンテナはこの段階では自動的に終了し、Exit (1)のステータスになることがあります。これは想定された動作であり、後ほど手動で証明書発行を行う際に再度使用しますので、エラーではありません。

SSL証明書の発行

WordPressが正しく表示されたら、次はCertbotを使用してSSL証明書を発行します。
以下のコマンドを使って、certbotコンテナ経由で証明書を取得します。

bash
docker-compose run --rm certbot certonly --webroot --webroot-path=/var/www/certbot \
    --email you@example.com --agree-tos --no-eff-email --force-renewal -d example.ddns.net

コマンドの各オプションについて

  • --webroot / --webroot-path:ACMEチャレンジ用ファイルの配置先を指定します。
    Nginxの .well-known/acme-challenge と一致している必要があります。
  • --email:証明書更新の通知を受け取るメールアドレス。
  • --agree-tos:Let's Encryptの利用規約に同意。
  • --no-eff-email:EFFからのお知らせメールを受け取らない設定。
  • --force-renewal:常に証明書を再発行(初回発行時でも安全のため指定)。
  • -d:対象となるドメイン名(DDNSや独自ドメインなど)

注意点と事前確認

Let's Encryptの仕様上、1日あたりに発行できる証明書の回数には制限があります。
何度も失敗して制限に達してしまうと、しばらく再試行ができなくなるため注意が必要です。
コマンドを実行する前に、以下のテストモードを使って事前確認しておくのがおすすめです。

bash
docker-compose run --rm certbot certonly --dry-run --webroot --webroot-path=/var/www/certbot \
  -d example.ddns.net

--dry-runを使えば、実際には証明書を発行せずに流れだけテストできます。

発行に失敗する主な原因

もし証明書の発行に失敗する場合、以下の点を確認してみてください。

  • DDNSの設定ミスやDNS反映の遅延により、指定したドメインが正しくサーバに向いていない
  • HTTPポート(80番)が外部からブロックされている(ルーターやファイアウォール設定)
  • Nginxの設定.well-known/acme-challenge/正しく処理していない
  • /var/www/certbotマウントやアクセス権限が適切でない

どれも見落としやすいポイントなので確認してみましょう。

証明書の確認

発行が成功すると、証明書は次のパスに保存されます。

bash
./docker-compose/certbot/conf/live/example.ddns.net/

この中には、以下のようなファイルが含まれており、SSL設定に使用されます。

  • fullchain.pem(証明書本体 + 中間証明書)
  • privkey.pem(秘密鍵)

これで、HTTPS環境の準備が整いました。
次はこの証明書をNginxの設定に反映させ、SSL対応を完了させていきます。

Nginxの設定を変更とコンテナ再起動

SSL証明書の発行が完了したら、次はNginxの設定ファイルを修正してHTTPS通信を有効化します。

初期設定ではHTTP(ポート80)のみが有効になっており、SSL通信(ポート443)には対応していません。ここで設定ファイルを編集し、証明書を読み込むように構成を変更します。

以下は、nginx.confの最終的な設定例です。

nginx.conf
server {
    listen 80;
    server_name example.ddns.net;  # サーバーのドメイン名を指定

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;  # Certbotの検証用ディレクトリ
        default_type "text/plain";
        allow all;
        try_files $uri /index.html;
    }

    location / {
        return 301 https://$host$request_uri;  # HTTPアクセスはHTTPSへリダイレクト
    }
}

server {
    listen 443 ssl;
    server_name example.ddns.net;  # サーバーのドメイン名

    # Let's Encryptで取得したSSL証明書を指定
    ssl_certificate /etc/letsencrypt/live/example.ddns.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.ddns.net/privkey.pem;

    # セキュリティ設定(TLSバージョン、暗号スイートなど)
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 10m;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    root /var/www/html;
    index index.php index.html;

    charset utf-8;
    client_max_body_size 20m;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass wordpress:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~* ^/xmlrpc.php$ {
        deny all;  # セキュリティ対策としてxmlrpcを無効化
    }
}

設定ファイルを保存したら、Nginxコンテナを再起動して設定を反映させます。

bash
docker-compose restart nginx

再起動後、ブラウザでhttps://example.ddns.netにアクセスしてみてください。
HTTPS接続が有効になり、アドレスバーに鍵マークが表示されれば、SSLの設定は完了です。

SSL Labs などの外部サービスを使って、証明書やセキュリティの評価を確認しておくのもおすすめです。

まとめ

本記事では、ホームサーバ上にDocker環境を構築し、WordPressをNginx + PHP-FPM構成でデプロイした上で、Certbotを用いたSSL証明書の取得とHTTPS対応までの一連の流れを解説しました。

具体的には以下の内容をカバーしました。

  • Docker Composeを用いたNginx/WordPress/DB/Certbotの構成
  • FastCGI(PHP-FPM)を活用したWordPressの効率的な実行
  • CertbotによるLet's Encrypt証明書の発行と配置
  • NginxのSSL設定とHTTPSリダイレクトの実装

コンテナ再起動による反映と確認

これにより、ユニバーサルリンクのテスト環境として必要なHTTPS通信を備えたWebサーバの構築が完了しました。

次回は、いよいよ本来の目的である
ユニバーサルリンク(iOS)やアプリリンク(Android) のテスト設定・確認方法について解説していく予定です。

Dockerで構築したHTTPS対応のサーバをベースに、実際にスマートフォンアプリと連携させながら、リンクの動作検証を行っていきます。

ファースト・スクラッチTech Blog

Discussion

ログインするとコメントできます