ConoHa VPSでWordPress+ツール系アプリを公開するまでの奮闘記5【Nginxリバースプロキシ設定~Docker起動編】

Wordpress備忘録

WordPressで技術ブログを運営しつつ、練習がてら作ったツール系アプリも同じサーバーで公開したい!
そんなケチな目標を掲げ、ConoHa VPSを契約して本番環境を構築した記録です。

前回はドメインの取得・DNS設定、そしてSSL証明書の取得まで実施しました。
今回はNginxリバースプロキシ設定から、Dockerコンテナの起動までを追っていきます。

前回の記事はこちら。

ConoHa VPSでWordPress+ツール系アプリを公開するまでの奮闘記4【ドメイン・DNS設定~SSL証明書取得編】
ConoHa VPS構築記録の第4回。ConoHaでのドメイン取得・DNS設定(ネームサーバー混乱トラブルも解説)から、certbotを使ったLet's EncryptのSSL証明書取得・自動更新確認まで、実際のハマりどころを交えて詳しく解説します。

前提環境

ConoHa VPSUbuntu 24.04 LTS / メモリ2GB / SSD 100GB / Dockerプリインストール
ローカルPC → VPSSSH鍵認証(ed25519)、ポート2222
VPSログインユーザーuser
WordPressテーマCocoon(親テーマ)+ cocoon-child-master(子テーマ+自作)

前回までのあらすじ

  • ConoHaセキュリティグループ:2222/80/443のインバウンドを許可(22番は削除済み)
  • SSH:ポートを2222に変更、root直接ログイン禁止、パスワード認証無効、鍵認証のみ
  • UFW:2222/80/443を許可
  • Docker:インストール済み
  • Nginx:インストール・自動起動設定済み
  • ドメイン:DNS設定済み
  • certbot:インストール・証明書取得済み

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用の設定ファイルと見比べると、変更されるのは以下。

  • server_name:test_app1.hibitsuiki.com;
  • return 301 後のURL:return 301 https://test_app1.hibitsuiki.com$request_uri;
  • proxy_pass:proxy_pass http://127.0.0.1:3001;

アップロードサイズ制限のトラブル

後続の作業で、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

【各設定の意味】

  • image: mysql:8.0 → MySQL公式イメージのバージョン8.0を使用
  • container_name → コンテナ名を明示(操作しやすくなる)
  • restart: always → VPS再起動時にコンテナも自動起動
  • ${MYSQL_DATABASE} → .envファイルの値を参照
  • ./data/db:/var/lib/mysql → VPS側のdata/dbにDBデータを永続化
  • depends_on: db → DBコンテナが起動してからWPを起動
  • ports: 8080:80 → VPSの8080番をコンテナの80番に接続
    NginxがVPSの8080番に転送してくる
  • phpmyadmin → ブラウザからDBを管理できるツール(8081番)
    いらなかったかも

コンテナの起動

さぁ、ついにDockerコンテナを起動させます。
ymlファイルに問題がなければ、スムーズにいってくれるはず…!

$ cd ~/apps/hibitsuiki
$ docker compose up -d

起動確認してUpとなっていれば成功です。

docker ps
# 出力:
# hibitsuiki_db          → Up
# hibitsuiki_wp          → Up
# hibitsuiki_phpmyadmin  → Up

上記Dockerコマンド、業務でもかなり頻繁に叩くので記事にまとめてます。
よければこちらもどうぞ。

【初心者向け】現場で本当に使うDockerコマンドはこれだった
Docker初心者が現場で本当に使うコマンドを厳選して解説。up -d・down・ps・logs -fの基本4つを中心に、使うタイミングや注意点もわかりやすく紹介します。

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

タイトルとURLをコピーしました