WordPressで技術ブログを運営しつつ、練習がてら作ったツール系アプリも同じサーバーで公開したい!
そんなケチな目標を掲げ、ConoHa VPSを契約して本番環境を構築した記録です。
前回はドメインの取得・DNS設定、そしてSSL証明書の取得まで実施しました。
今回はNginxリバースプロキシ設定から、Dockerコンテナの起動までを追っていきます。
前回の記事はこちら。

前提環境
| ConoHa VPS | Ubuntu 24.04 LTS / メモリ2GB / SSD 100GB / Dockerプリインストール |
| ローカルPC → VPS | SSH鍵認証(ed25519)、ポート2222 |
| VPSログインユーザー | user |
| WordPressテーマ | Cocoon(親テーマ)+ cocoon-child-master(子テーマ+自作) |
前回までのあらすじ
Nginxのリバースプロキシ設定
なぜリバースプロキシが必要か?
外部からのリクエストは全て80/443番ポートに届きます。
でも、Dockerコンテナはそれぞれ別のポート(8000とか)で動いてますよね。
このままだとせっかくリクエストがあっても意図したコンテナに到着できないのです。
Nginxはサブドメインを見て、正しいコンテナに転送(プロキシ)する、いわゆる「交通整理役」を担ってくれます。
また、SSLの終端(HTTPS→HTTP変換)もここで行うので、インフラ業務の中でもかなり重要な存在です。
ブラウザ(HTTPS:443)
↓
Nginx(SSL終端・サブドメインで振り分け)
↓
Dockerコンテナ(WordPress:8080 / ツール:3001)
設定ファイルの作成
WordPress用
$ sudo nano /etc/nginx/sites-available/hibitsuiki.com
コマンドを実行すると、設定ファイルを編集できます。値の後に解説をつけました。
# HTTPをHTTPSにリダイレクト
server {
listen 80; # IPv4のHTTP(port80)を受け付けるよ
listen [::]:80; # IPv6のHTTP(port80)を受け付けるよ
server_name hibitsuiki.com www.hibitsuiki.com;
# HTTPSへリダイレクトしてね
return 301 https://www.hibitsuiki.com$request_uri;
}
# WordPress本体
server {
listen 443 ssl; # HTTPS(port443)を受け付けるよ
listen [::]:443 ssl;
server_name hibitsuiki.com www.hibitsuiki.com;
# SSL証明書・秘密鍵はここだよ
ssl_certificate /etc/letsencrypt/live/hibitsuiki.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hibitsuiki.com/privkey.pem;
# アップロードできるファイルの最大サイズ(実は後から必要になった)
client_max_body_size 64M;
location / {
# 受け付けたら、DockerのWordPressコンテナに転送してね
proxy_pass http://127.0.0.1:8080;
# コンテナさんへ、元のドメイン名・アクセス元の本当のIPはこうだよ
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# 経由したプロキシのIPを記録するよ
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# コンテナさんへ、httpsでアクセスされたよ
proxy_set_header X-Forwarded-Proto $scheme;
}
}
ツールアプリ用
ここではアプリ名をtest_app1としています。
$ sudo nano /etc/nginx/sites-available/test_app1
WordPress用の設定ファイルと見比べると、変更されるのは以下。
アップロードサイズ制限のトラブル
後続の作業で、Wordpressのテーマを管理画面からアップロードしようとしたところ、413 Request Entity Too Largeエラーが発生してしまいました。
【原因】
Nginxにはデフォルトでアップロードファイルのサイズ制限(1MB)が設定されている
というわけで、先ほどのNginxの設定ファイルに項目を追加したわけですね。
sites-enabledにシンボリックリンクを作成
シンボリックリンクというのは、簡単に言うとショートカットのようなものです。
sites-availableのファイルへの「ショートカット」をsites-enabledに追加することでNginxが設定を有効化できます。
ややこしいので自分もまだよくわかってないんですけどね…。
sites-available → 設定ファイルの保管場所(有効・無効問わず) sites-enabled → 実際にNginxが読み込む設定ファイルの場所
$ sudo ln -s /etc/nginx/sites-available/hibitsuiki.com /etc/nginx/sites-enabled/
$ sudo ln -s /etc/nginx/sites-available/test_app1 /etc/nginx/sites-enabled/
設定が反映されたか確認してみます。
# 構文チェック
$ sudo nginx -t
# 出力:nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
# nginx: configuration file /etc/nginx/nginx.conf test is successful
# 設定の再読み込み(reloadはrestartと違い既存の接続を維持する)
$ sudo systemctl reload nginx
再起動後、以下のコマンド実行結果が Active: active (running) であればオールオッケーです!
$ sudo systemctl status nginx
ディレクトリ構成とDocker設定
ディレクトリ見直し
- Qなんでディレクトリを見直ししたの?
- A
これは自分も知らなったのですが、Dockerコンテナは「使い捨て」が基本思想らしいんです。なので、コンテナを削除=データも消えるような設定が基本なんですね。
私個人としては、万が一、億が一の確率で本番環境のDockerを削除してしまう可能性もあるわけで、データは残しておきたいんです。
てことで、VPS上にディレクトリを作り、コンテナとマウント(紐付け)することでデータをVPS側に永続化しましょう。
なんかもうDockerじゃなくてええやろがいという話にもなるが、ここでは無視。
【ディレクトリ構成】
/home/user/apps/
└── hibitsuiki/
├── docker-compose.yml
├── .env
├── wordpress/ ← WordPressファイル(バインドマウント)
└── data/
└── db/ ← MySQLデータ永続化
ツール系アプリは別ディレクトリで独立させます。
/home/user/apps/
├── hibitsuiki/ ← WordPress
└── test_app1/ ← ツールA
├── docker-compose.yml
└── app/
バインドマウントに変更
最初は名前付きボリューム(wp_data)を使っていました。
こんな感じで。
# 最初の設定(名前付きボリューム)
volumes:
- wp_data:/var/www/html
別に悪いわけではないんですよ。
ただ、名前付きボリュームはDockerが/var/lib/docker/volumes/配下で管理するため、rootユーザーしかアクセスできませんでした。
つまり、作成したユーザー(user)ではリモートリポジトリからgit pullできないんですよ。
子テーマをデプロイするたびに、sudo権限でソースをコピーする手間があったんです。なんで気づかなかったんや…。
よって、バインドマウントに変更しました。
volumes:
- ./wordpress:/var/www/html
バインドマウントはVPS上の実際のディレクトリをコンテナに直接マウントします。userユーザーで直接操作でき、git pullだけでデプロイ可能に。
.envファイル作成
docker-compose.ymlにDB接続情報を直書きすると、GitHub(だけじゃなく、リモートリポジトリならなんでも)にpushした際にパスワードが漏洩します。
なんか似たようなインシデントがつい最近ニュースになってましたね。
.envファイルに機密情報を分離することで、docker-compose.ymlは安全にGit管理できます。
中身はシンプルです。
# ~/apps/hibitsuiki/.env
MYSQL_DATABASE=wordpress
MYSQL_USER=wpuser
MYSQL_PASSWORD=(任意のパスワード)
MYSQL_ROOT_PASSWORD=(任意のrootパスワード)
docker-compose.yml
最終的にどんなymlファイルになったか、備忘のため残しておきましょう。
services:
db:
image: mysql:8.0
container_name: hibitsuiki_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./data/db:/var/lib/mysql
wordpress:
image: wordpress:latest
container_name: hibitsuiki_wp
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
WORDPRESS_DB_USER: ${MYSQL_USER}
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- ./wordpress:/var/www/html
depends_on:
- db
phpmyadmin:
image: phpmyadmin:latest
container_name: hibitsuiki_phpmyadmin
restart: always
ports:
- "8081:80"
environment:
PMA_HOST: db
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
depends_on:
- db
【各設定の意味】
コンテナの起動
さぁ、ついにDockerコンテナを起動させます。
ymlファイルに問題がなければ、スムーズにいってくれるはず…!
$ cd ~/apps/hibitsuiki
$ docker compose up -d
起動確認してUpとなっていれば成功です。
docker ps
# 出力:
# hibitsuiki_db → Up
# hibitsuiki_wp → Up
# hibitsuiki_phpmyadmin → Up
上記Dockerコマンド、業務でもかなり頻繁に叩くので記事にまとめてます。
よければこちらもどうぞ。

ではまた次回、いよいよシリーズ最終回となります。
WordPressのセットアップからGitHubのデプロイ編にて!


