Docker環境で簡単なウェブアプリのデプロイとSSL証明書を設定
背景
前回の記事ではホームサーバの構築について説明しましたが、今回はその続編として、ユニバーサルリンクのテスト環境を構築する一環として、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版を採用する理由は以下のとおりです。
-
パフォーマンスの向上
- PHP-FPMはFastCGIプロトコルを使用し、Nginxとの組み合わせでより効率的に処理を1行える。
- 静的コンテンツ(画像・CSSなど)はNginxが処理し、PHPスクリプトのみをFPMに渡すことで負荷を分散。
-
拡張性と柔軟性
- PHP-FPMとNginxを分離することで、PHPの設定やバージョン変更が容易 になる。
- サーバーの負荷に応じてPHP-FPMのプロセス数を調整可能。
-
セキュリティの向上
- Apacheを含むWordPress公式イメージは、不要な機能が含まれやすい。
- FPM版を使用することで、Nginxがリクエストを制御し、PHP処理のみをFPMに任せる構成 にできるため、セキュリティリスクを軽減。
このような理由から、FPM版を採用し、Nginxをフロントエンドとして利用する構成にしています。
完成したdocker-composeは以下のようになります。
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に書いてあるパスに配置します。
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 があるディレクトリ)で以下のコマンドを実行します。
docker-compose up -d
-d
オプションを付けることで、バックグラウンド(デタッチドモード)でコンテナが起動されます。
起動後、以下のコマンドでコンテナの状態を確認してみましょう。
docker-compose ps
各サービス(wordpress
, db
, nginx
など)がUp
状態であれば、正常に起動していることを意味します。
次に、ブラウザを開き、サーバのIPアドレスまたはドメイン(例: http://example.ddns.net)にアクセスしてみてください。
正常に設定されていれば、WordPressの初期セットアップ画面 が表示されるはずです。
なお、certbot
コンテナはこの段階では自動的に終了し、Exit (1)
のステータスになることがあります。これは想定された動作であり、後ほど手動で証明書発行を行う際に再度使用しますので、エラーではありません。
SSL証明書の発行
WordPressが正しく表示されたら、次はCertbotを使用してSSL証明書を発行します。
以下のコマンドを使って、certbot
コンテナ経由で証明書を取得します。
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日あたりに発行できる証明書の回数には制限があります。
何度も失敗して制限に達してしまうと、しばらく再試行ができなくなるため注意が必要です。
コマンドを実行する前に、以下のテストモードを使って事前確認しておくのがおすすめです。
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
のマウントやアクセス権限が適切でない
どれも見落としやすいポイントなので確認してみましょう。
証明書の確認
発行が成功すると、証明書は次のパスに保存されます。
./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
の最終的な設定例です。
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コンテナを再起動して設定を反映させます。
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対応のサーバをベースに、実際にスマートフォンアプリと連携させながら、リンクの動作検証を行っていきます。
Discussion