それぞれ異なるサーバーで運用していた複数のWordPressサイトを、1台の新サーバー(AlmaLinux 10)に移行し、「ホストOS側のNginx」+「Podman上の1つのMariaDBコンテナと2つのWordPressコンテナ」という構成にする手順を解説します。
今回構築する構成
移行前は別々のサーバーで動いていた環境を、新サーバー(AlmaLinux 10)上では以下のように1つの compose.yaml でスッキリまとめます。
[クライアント]
│
▼
[ホスト側 Nginx]
│
├ (:8081) ─> [WordPress site1] ─┐
│ │
└ (:8082) ─> [WordPress site2] ─┴─> [共有 MariaDB (wp_db)]
├── データベース: db_site1
└── データベース: db_site2
旧サーバーでのバックアップ
移行元の旧サーバー(サーバー1、サーバー2)それぞれにログインし、WordPressの「公開ファイル」と「データベース」をバックアップして新サーバーへ転送します。
WordPress公開ファイルのバックアップ
WordPressがインストールされているディレクトリ(例: /var/www/html/site1 など)の中身を丸ごとtarでバックアップします。
# サーバー1(サイト1)の場合 sudo tar -czvf site1_files.tar.gz -C /var/www/html/site1 . # サーバー2(サイト2)の場合 sudo tar -czvf site2_files.tar.gz -C /var/www/html/site2 .
※末尾の半角スペースと「.」を忘れずに入力してください。「-C ディレクトリ名 .」と指定することで、親ディレクトリ階層を含めず「中身のファイルだけ」をアーカイブできます(これを省いてフルパスで固めると、後でコンテナのボリュームに展開した際に階層が二重になってしまいます)。
データベースのエクスポート
それぞれの旧サーバーにある「wp-config.php」を確認し、記載されている接続情報を使ってmysqldumpを実行します。
- DBユーザー名: DB_USER の値
- DBパスワード: DB_PASSWORD の値
- DB名: DB_NAME の値
# サーバー1(サイト1)の場合 mysqldump -u DBユーザー名 -p'DBパスワード' \ --default-character-set=utf8mb4 \ --single-transaction \ --hex-blob \ --quick \ DB名 > site1_backup.sql # サーバー2(サイト2)の場合 mysqldump -u DBユーザー名 -p'DBパスワード' \ --default-character-set=utf8mb4 \ --single-transaction \ --hex-blob \ --quick \ DB名 > site2_backup.sql
※パスワードは「-p'パスワード'」と直接続けるか、「-p」のみ指定して対話型で入力します。
新サーバーへバックアップファイルを転送
バックアップしたファイル(tar.gz と .sql)を新サーバーへ転送します。
# サーバー1(サイト1)から転送する場合 scp site1_files.tar.gz site1_backup.sql 新サーバーのユーザー名@新サーバーIP:~/ # サーバー2(サイト2)から転送する場合 scp site2_files.tar.gz site2_backup.sql 新サーバーのユーザー名@新サーバーIP:~/
※ 転送方法は「scp」や「sftp」など使いやすい方法で問題ありません。
新サーバー(移行先)でのPodman環境の作成
Podmanインストール
新サーバーに「Podman」および「Podman Compose」をインストールします。
sudo dnf install podman podman-compose
compose.yaml作成
新サーバー側で、すべてのコンテナを統合管理する「compose.yaml」を「~/wordpress」ディレクトリに作成します。
今回は、DBコンテナのメモリ消費を抑えるため、1つのMariaDBコンテナを共有する設計です。
mkdir ~/wordpress cd ~/wordpress vi compose.yaml
設定内容
コンテナ名などは、環境に合わせて自分で分かりやすい名前を設定してください。
※名前を変更した場合は、これ以降の手順でも適宜読み替えて作業を行ってください。
services:
# ─── 統合する1つの共通MariaDBコンテナ ───
wp_db:
image: docker.io/library/mariadb:11.4
container_name: wp_db
restart: always
environment:
MYSQL_ROOT_PASSWORD: secure_root_password
TZ: Asia/Tokyo
volumes:
- db_data:/var/lib/mysql
# ─── 旧サーバーから移行するサイト1 ───
site1:
image: docker.io/library/wordpress:latest
container_name: site1
restart: always
environment:
TZ: Asia/Tokyo
ports:
- "127.0.0.1:8081:80" # ホストOSのnginxからは8081へ転送
volumes:
- site1_data:/var/www/html
depends_on:
- wp_db
# ─── 旧サーバーから移行するサイト2 ───
site2:
image: docker.io/library/wordpress:latest
container_name: site2
restart: always
environment:
TZ: Asia/Tokyo
ports:
- "127.0.0.1:8082:80" # ホストOSのnginxからは8082へ転送
volumes:
- site2_data:/var/www/html
depends_on:
- wp_db
volumes:
db_data:
site1_data:
site2_data:
ports設定で「127.0.0.1:8081:80」のようにローカルホスト(127.0.0.1)を指定することで、外部からの直接アクセスを防ぎ、ホストOSのNginx経由でのみアクセスを許可するセキュアな構成にしています。
また、環境変数「TZ: Asia/Tokyo」を指定してコンテナ内の時刻を日本標準時(JST)に合わせています。
WordPressデータのリストア
WordPressコンテナを起動する前に、あらかじめ名前付きボリュームを作成してバックアップデータを展開しておきます。
あらかじめデータを配置しておくことで、コンテナ初回起動時にWordPress公式イメージが新規ファイルを自動展開(上書き)してしまうのを防ぎ、旧サーバーの環境をそのまま安全に引き継ぐことができます。
名前付きボリュームの作成
バックアップデータを展開するための「受け皿」となる名前付きボリュームを先行して作成します。
podman volume create wordpress_site1_data podman volume create wordpress_site2_data
なぜボリューム名に「wordpress_」を付けるのか?
「compose.yaml」内では「site1_data」「site2_data」と定義していますが、Composeはプロジェクトディレクトリ名(今回は wordpress)を接頭辞として自動付与するため、実際に作成されるボリューム名は「wordpress_site1_data」「wordpress_site2_data」になります。そのため、手動で先行作成・インポートを行う際もこの名前を指定します。
WordPressバックアップデータのインポート
Podman標準の「volume import」コマンドを使い、各サイトのバックアップアーカイブをそれぞれのボリュームに直接展開します。
※バックアップファイルの配置場所が異なる場合は、適宜パスを読み替えて実行してください。
podman volume import wordpress_site1_data ~/site1_files.tar.gz podman volume import wordpress_site2_data ~/site2_files.tar.gz
ファイル所有者(権限)の調整
インポートしたファイルは旧サーバーの所有者(UID/GID)のまま展開されているため、このままではWordPressからファイルの更新やアップロードができず、書き込み権限エラーが発生します。
WordPress公式イメージ(Apache版)は、内部で「www-data」ユーザー(UID: 33 / GID: 33)として動作しています。
そのため、一時的な軽量コンテナ(Alpine Linux)を起動し、ボリューム内の全ファイルの所有者を「33:33」に変更します。
podman run --rm -v wordpress_site1_data:/target alpine chown -R 33:33 /target podman run --rm -v wordpress_site2_data:/target alpine chown -R 33:33 /target
※「--rm」オプションを指定しているため、権限変更の処理が終わると一時コンテナは自動的に破棄されます。
データベースの作成とリストア
1つのMariaDBコンテナ内に、サイト1とサイト2それぞれのデータベースと接続ユーザーを作成し、旧サーバーから取得したバックアップデータを順番にインポートします。
MariaDBコンテナの先行起動
データベースの作成やリストアを行うため、まずはMariaDBコンテナのみを起動します。
cd ~/wordpress podman-compose up -d wp_db
各サイト用データベースの作成
起動したMariaDBコンテナ(wp_db)内で、各サイト用のデータベースを新規作成します。
コマンド構文
実行するコマンドの構文は以下の通りです。
- MariaDBコンテナ: 「compose.yaml」の「container_name」で設定した名前(例: wp_db)
- MariaDBのrootパスワード: 「compose.yaml」の「MYSQL_ROOT_PASSWORD」で設定したパスワード
- 作成するDB名: 各サイトの「wp-config.php」の「DB_NAME」で設定されている名前
※DB名を変更したい場合は、後述する「wp-config.php」の編集時に合わせて「DB_NAME」部分も変更が必要になります。
podman exec -it MariaDBコンテナ mariadb \ -u root -p'MariaDBのrootパスワード' \ -e "CREATE DATABASE IF NOT EXISTS 作成するDB名 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
実行例
以下の内容が「wp-config.php」に設定されていたとして実行しています。
- サイト1 DB_NAME: db_site1
- サイト2 DB_NAME: db_site2
# サイト1用データベース(db_site1)の作成 podman exec -it wp_db mariadb \ -u root -p'secure_root_password' \ -e "CREATE DATABASE IF NOT EXISTS db_site1 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # サイト2用データベース(db_site2)の作成 podman exec -it wp_db mariadb \ -u root -p'secure_root_password' \ -e "CREATE DATABASE IF NOT EXISTS db_site2 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
接続用ユーザーの作成と権限付与
各WordPressコンテナが対応するデータベースにアクセスできるよう、専用の接続ユーザーを作成して権限を付与します。
コマンド構文
実行するコマンドの構文は以下の通りです。
- MariaDBコンテナ: 「compose.yaml」の「container_name」で設定した名前(例: wp_db)
- MariaDBのrootパスワード: 「compose.yaml」の「MYSQL_ROOT_PASSWORD」で設定したパスワード
- DBユーザー: 各サイトの「wp-config.php」の「DB_USER」で設定されている名前
- DBパスワード: 各サイトの「wp-config.php」の「DB_PASSWORD」で設定されているパスワード
- DB名: 一つ前の手順で作成したDB名
podman exec -it MariaDBコンテナ mariadb -u root -p'MariaDBのrootパスワード' -e " CREATE USER IF NOT EXISTS 'DBユーザー'@'%' IDENTIFIED BY 'DBパスワード'; GRANT ALL PRIVILEGES ON DB名.* TO 'DBユーザー'@'%'; FLUSH PRIVILEGES;"
※「DBユーザー」「DBパスワード」を変更する場合は、後述する「wp-config.php」の編集時に合わせて変更が必要になります。
実行例
以下の内容が「wp-config.php」に設定されていたとして実行しています。
- サイト1 DB_USER: user_site1
- サイト1 DB_PASSWORD: db_password_site1
- サイト1 DB_NAME: db_site1
- サイト2 DB_USER: user_site2
- サイト2 DB_PASSWORD: db_password_site2
- サイト2 DB_NAME: db_site2
# サイト1用ユーザーの作成と権限付与 podman exec -it wp_db mariadb -u root -p'secure_root_password' -e " CREATE USER IF NOT EXISTS 'user_site1'@'%' IDENTIFIED BY 'db_password_site1'; GRANT ALL PRIVILEGES ON db_site1.* TO 'user_site1'@'%'; FLUSH PRIVILEGES;" # サイト2用ユーザーの作成と権限付与 podman exec -it wp_db mariadb -u root -p'secure_root_password' -e " CREATE USER IF NOT EXISTS 'user_site2'@'%' IDENTIFIED BY 'db_password_site2'; GRANT ALL PRIVILEGES ON db_site2.* TO 'user_site2'@'%'; FLUSH PRIVILEGES;" # ユーザーが正しく作成されたかの確認 podman exec -it wp_db mariadb -u root -p'secure_root_password' -e " SELECT User, Host FROM mysql.user WHERE User IN ('user_site1', 'user_site2');" +------------+------+ | User | Host | +------------+------+ | user_site1 | % | | user_site2 | % | +------------+------+
データのリストア(SQLインポート)
作成したデータベースへ、転送しておいたSQLバックアップファイルを順番にインポートします。
コマンド構文
podman exec -i DBコンテナ名 mariadb -u root -p'MariaDBのrootパスワード' DB名 < バックアップ.sql
実行例
# サイト1のリストア podman exec -i wp_db mariadb -u root -p'secure_root_password' db_site1 < ~/site1_backup.sql # サイト2のリストア podman exec -i wp_db mariadb -u root -p'secure_root_password' db_site2 < ~/site2_backup.sql
wp-config.php の修正(DB接続情報とHTTPS設定)
旧サーバーからリストアしたデータには、旧サーバー環境の「wp-config.php」が含まれています。
このままでは、接続するDBサーバーのホスト名が、本環境のMariaDBコンテナではなく旧環境のDBサーバー(localhostなど)を参照してしまい、「データベース接続確立エラー」が発生してしまうため、新環境のMariaDBコンテナに接続するようにボリューム内の「wp-config.php」を編集します。
※ DBを作成する際に、DB名を変更したり、接続用ユーザーの名前やパスワードを変更した場合も、それにあわせて変更を行う必要があります。
一時コンテナ(Alpine Linux)の標準viで開くと日本語コメントが文字化けしてしまうため、「podman unshare」コマンドを使い、ホストOS側の日本語対応エディタ(viなど)で直接編集するのが最も確実です。
# サイト1の設定編集 podman unshare vi ~/.local/share/containers/storage/volumes/wordpress_site1_data/_data/wp-config.php # サイト2の設定編集 podman unshare vi ~/.local/share/containers/storage/volumes/wordpress_site2_data/_data/wp-config.php
「podman unshare」を実行することで、直前に変更した所有者(33:33)によるパーミッションエラーを防ぎ、コンテナ内root相当の権限でホスト側エディタを開くことができます。
もし「vi」で開いた際に行末に「^M」と表示される場合は、過去にWindows環境等で編集されたことによる改行コード(CRLF)が残っているためです。
事前に以下のsedコマンドを実行して「^M」を一括削除(Linux標準のLF改行に統一)しておくと安全です。
# 行末の ^M(CRコード)を一括削除する場合 podman unshare sed -i 's/\r$//' ~/.local/share/containers/storage/volumes/wordpress_site1_data/_data/wp-config.php podman unshare sed -i 's/\r$//' ~/.local/share/containers/storage/volumes/wordpress_site2_data/_data/wp-config.php
データベース接続情報の変更
新サーバーの設定に合わせて、該当する部分を書き換えます。
「DB_HOST」には、「compose.yaml」で設定したMariaDBのコンテナ名(container_name)を指定してください。
/** データベース名 */
define( 'DB_NAME', '作成したDB名' ); // 例: db_site1
/** データベースのユーザー名 */
define( 'DB_USER', '作成したユーザー名' ); // 例: user_site1
/** データベースのパスワード */
define( 'DB_PASSWORD', '設定したパスワード' ); // 例: db_password_site1
/** データベースのホスト名 */
define( 'DB_HOST', 'wp_db' ); // 重要: MariaDBのコンテナ名を指定
HTTPS対応(リバースプロキシ環境下のリダイレクトループ防止)の追記
ホスト側のNginxでSSL(HTTPS)を処理してコンテナへHTTP転送している場合、以下の設定がないとWordPressが「HTTPでアクセスされた」と誤認し、無限リダイレクトループ(ERR_TOO_MANY_REDIRECTS)やCSS・画像が表示されない不具合が発生します。
Nginxから渡されるヘッダーを読み取り、HTTPSアクセスとして正しく処理させるため、以下のコードを「wp-config.php」内(「require_once ABSPATH . 'wp-settings.php';」より前)に追記します。
/* Add any custom values between this line and the "stop editing" line. */
/* 追加設定 リバースプロキシ(Nginx)環境下でのHTTPS認識 */
if (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https') {
$_SERVER['HTTPS'] = 'on';
}
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
コンテナ起動
すべてのインポートと設定ファイルの修正が完了したら、全コンテナを起動します。
podman-compose up -d
起動の確認
コンテナが起動しているかの確認を行います。
podman-compose ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 25ed8fce5e4f docker.io/library/mariadb:11.4 mariadbd 2 hours ago Up 2 hours 3306/tcp wp_db fa5e15fd8ecf docker.io/library/wordpress:latest apache2-foregroun... 4 seconds ago Up 4 seconds 127.0.0.1:8081->80/tcp site1 c4e18573d250 docker.io/library/wordpress:latest apache2-foregroun... 4 seconds ago Up 4 seconds 127.0.0.1:8082->80/tcp site2
STATUSが「Up」になっていれば、コンテナは起動しています。
コンテナの停止
コンテナが起動することを確認できたら、自動起動設定を行うのでコンテナを停止します。
podman-compose down
コンテナの自動起動設定(Quadlet)
サーバー再起動時にもコンテナが自動的に立ち上がるよう、Podman標準の機能である「Quadlet(クアドラット)」を設定します。
以前使われていた「podman generate systemd」は非推奨となっており、現在は設定ファイルを配置するだけでsystemdサービスを自動生成してくれるQuadletを使用するのが標準です。
設定ファイル用ディレクトリの作成
コンテナを実行している一般ユーザーで、Quadlet用の設定ディレクトリを作成します。
mkdir -p ~/.config/containers/systemd
ネットワーク定義ファイルの作成(wordpress.network)
コンテナ同士が「wp_db」という名前で通信できるよう、共通のブリッジネットワークを定義します。
vi ~/.config/containers/systemd/wordpress.network
設定内容は以下のとおりです。
[Network] NetworkName=wordpress_net
コンテナ定義ファイルの作成(.container)
各コンテナの設定ファイルを作成します。
「Network=」には、先ほど作成したネットワーク定義ファイル名「wordpress.network」を指定します。
これにより、コンテナ起動前に「systemd」がネットワークを自動作成してくれるようになります。
MariaDBコンテナ用(wp_db.container)
MariaDB用コンテナ(wp_db)の設定を作成します。
vi ~/.config/containers/systemd/wp_db.container
設定内容は以下のとおりです。
[Unit] Description=MariaDB Database for WordPress [Container] ContainerName=wp_db Image=docker.io/library/mariadb:11.4 Environment=MYSQL_ROOT_PASSWORD=secure_root_password Volume=wordpress_db_data:/var/lib/mysql Network=wordpress.network Timezone=Asia/Tokyo [Install] WantedBy=default.target
サイト1用WordPressコンテナ(site1.container)
サイト1用WordPressコンテナ(site1)の設定を作成します。
vi ~/.config/containers/systemd/site1.container
「After=」と「Requires=」を指定することで、必ずMariaDBコンテナが起動してからWordPressが起動するように依存関係を制御します。
[Unit] Description=WordPress Site 1 After=wp_db.service Requires=wp_db.service [Container] ContainerName=site1 Image=docker.io/library/wordpress:latest PublishPort=127.0.0.1:8081:80 Volume=wordpress_site1_data:/var/www/html Network=wordpress.network Timezone=Asia/Tokyo [Install] WantedBy=default.target
サイト2用WordPressコンテナ(site2.container)
サイト2用WordPressコンテナ(site2)の設定を作成します。
vi ~/.config/containers/systemd/site2.container
設定内容は以下のとおりです。
[Unit] Description=WordPress Site 2 After=wp_db.service Requires=wp_db.service [Container] ContainerName=site2 Image=docker.io/library/wordpress:latest PublishPort=127.0.0.1:8082:80 Volume=wordpress_site2_data:/var/www/html Network=wordpress.network Timezone=Asia/Tokyo [Install] WantedBy=default.target
systemdの再読み込みとサービスの起動
設定ファイルを配置したら、「systemd」を再読み込みしてサービスを起動します。
# 設定ファイルの再読み込み systemctl --user daemon-reload # サービスの起動 systemctl --user start wp_db site1 site2
「.container」ファイル内に「WantedBy=default.target」を記述しているため、「daemon-reload」を実行した時点で自動起動の有効化は完了しています。
そのため手動で「systemctl enable」を実行する必要はなく(実行すると is transient or generated エラーになります)、「start」で起動するだけで次回サーバー起動時にも自動的に立ち上がります。
以下のコマンドでステータスを確認し、「active (running)」になっていれば正常に起動しています。
systemctl --user status site1 systemctl --user status site2 systemctl --user status wp_db
ユーザー常駐(Linger)の有効化
ルートレスPodmanでは、一般ユーザーがログアウトしてもバックグラウンドでコンテナを動かし続け、サーバー起動時にも自動起動させるために「Linger」の有効化が必須です。
loginctl enable-linger $USER
以下のコマンドで「Linger=yes」と表示されれば設定完了です。
loginctl show-user $USER -p Linger
Quadlet設定後の「compose.yaml」の扱いとコンテナ管理
「Quadlet」の設定完了後は、コンテナの起動・停止・自動起動のすべてを「systemd」が直接制御します。
そのため、「~/wordpress/compose.yaml」を削除してもコンテナの動作には一切影響しませんが、ポート番号やボリューム、環境変数といった全体構成がひと目でわかる「設計図」としてそのまま残しておくことをおすすめします。
注意点として、Quadletによる稼働中に「podman-compose up」などを実行すると、コンテナ名やポートの重複エラーが発生してしまいますので、日常の起動・停止や再起動は、すべて以下の「systemctl --user」コマンドで行うようにしてください。
# 全コンテナの停止 systemctl --user stop site1 site2 wp_db # 全コンテナの起動 systemctl --user start wp_db site1 site2 # コンテナの再起動 systemctl --user restart site1 site2 wp_db
ホストOS側のNginx設定(リバースプロキシ用)
フロントに配置しているOS側の「Nginx」で、それぞれのドメイン宛てのアクセスを各WordPressコンテナのポートへ転送する設定をします。
Nginxインストール
最新版のNginxを利用するため、Nginxの公式リポジトリを使用して「Nginx」をインストールします。
Nginxリポジトリを作成
sudo vi /etc/yum.repos.d/nginx.repo
[nginx-stable] name=nginx stable repo baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true [nginx-mainline] name=nginx mainline repo baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true
インストール
sudo dnf install nginx
自動起動設定
自動起動の設定と起動を同時に行います。
sudo systemctl enable --now nginx
certbotインストール
Let's EncryptでSSL証明書を取得するために必要なcertbotをインストールします。
sudo dnf install epel-release sudo dnf install certbot python3-certbot-nginx
Let's Encrypt用ディレクトリ作成
Let's EncryptのWeb認証(ACMEチャレンジ)で使用するディレクトリを作成します。
sudo mkdir -p /usr/share/nginx/site1 sudo mkdir -p /usr/share/nginx/site2
テスト用SSL/TLS証明書と秘密鍵を用意
DNS切り替え前にクライアントPCの「hosts」を使ってHTTPS接続による動作確認を行うため、旧サーバーで使用しているSSL/TLS証明書と秘密鍵を新サーバーへ一時的にコピーします。
「/etc/letsencrypt/live/」内のファイルはシンボリックリンクになっているため、実体ファイルをコピーできる「cp -L」コマンドを使って取り出します。
また、サイト1とサイト2でファイル名が重複しないよう名前を変更して新サーバーへ転送します。
サーバー1(サイト1)から証明書を転送
旧サーバー1にログインし、証明書と秘密鍵を取り出して新サーバーへ転送します。
# 実体ファイルを名前を変更してコピー sudo cp -L /etc/letsencrypt/live/site1.example.com/fullchain.pem ./site1-fullchain.pem sudo cp -L /etc/letsencrypt/live/site1.example.com/privkey.pem ./site1-privkey.pem # 転送できるように所有者をログインユーザーに変更 sudo chown $USER:$USER ./site1-*.pem # 新サーバーへ転送 scp site1-*.pem 新サーバーのユーザー名@新サーバーIP:~/
サーバー2(サイト2)から証明書を転送
旧サーバー2でも同様に、証明書と秘密鍵を取り出して新サーバーへ転送します。
# 実体ファイルを名前を変更してコピー sudo cp -L /etc/letsencrypt/live/site2.example.com/fullchain.pem ./site2-fullchain.pem sudo cp -L /etc/letsencrypt/live/site2.example.com/privkey.pem ./site2-privkey.pem # 転送できるように所有者をログインユーザーに変更 sudo chown $USER:$USER ./site2-*.pem # 新サーバーへ転送 scp site2-*.pem 新サーバーのユーザー名@新サーバーIP:~/
新サーバー側での配置とパーミッション設定
新サーバーに届いた証明書と秘密鍵を「/etc/nginx」へ移動し、パーミッションを設定します(セキュリティのため秘密鍵はrootのみ読み取り可能にします)。
# /etc/nginx へ移動 sudo mv ~/site1-*.pem /etc/nginx/ sudo mv ~/site2-*.pem /etc/nginx/ # 所有者をrootに変更 sudo chown root:root /etc/nginx/site*.pem # パーミッション設定 sudo chmod 644 /etc/nginx/site*-fullchain.pem sudo chmod 600 /etc/nginx/site*-privkey.pem
リバースプロキシ用設定
WordPress宛の通信をホスト側のNginxからWordPressコンテナへ転送する設定を行います。
複数のドメインを設定する際にも使い回せるよう、共通のプロキシ用ヘッダー定義ファイルを作成します。
sudo vi /etc/nginx/proxy_params
以下の内容を記述します。
proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;
サイト1用のNginx設定ファイル作成
サイト1用の設定ファイルを作成します。
※ここではsite1のドメイン名を「site1.example.com」としていますので、各自の環境に合わせて読み替えてください。
sudo vi /etc/nginx/conf.d/site1.conf
以下の内容を記述します。
# 転送先の設定
upstream site1 {
server 127.0.0.1:8081 fail_timeout=0;
}
server {
listen 443 ssl;
server_name site1.example.com;
root /usr/share/nginx/site1;
index index.html;
access_log /var/log/nginx/site1_access.log;
error_log /var/log/nginx/site1_error.log;
ssl_certificate /etc/nginx/site1-fullchain.pem;
ssl_certificate_key /etc/nginx/site1-privkey.pem;
# Let's Encrypt 更新用設定
location ^~ /.well-known {
root /usr/share/nginx/site1;
}
# リバースプロキシ設定(WordPressコンテナへ転送)
location / {
include proxy_params;
proxy_pass http://site1;
}
}
server {
listen 80;
server_name site1.example.com;
location / {
return 301 https://$host$request_uri;
}
}
サイト2用のNginx設定ファイル作成
サイト2用も同様に設定ファイルを作成します。
sudo vi /etc/nginx/conf.d/site2.conf
以下の内容を記述します。
# 転送先の設定
upstream site2 {
server 127.0.0.1:8082 fail_timeout=0;
}
server {
listen 443 ssl;
server_name site2.example.com;
root /usr/share/nginx/site2;
index index.html;
access_log /var/log/nginx/site2_access.log;
error_log /var/log/nginx/site2_error.log;
ssl_certificate /etc/nginx/site2-fullchain.pem;
ssl_certificate_key /etc/nginx/site2-privkey.pem;
# Let's Encrypt 更新用設定
location ^~ /.well-known {
root /usr/share/nginx/site2;
}
# リバースプロキシ設定(WordPressコンテナへ転送)
location / {
include proxy_params;
proxy_pass http://site2;
}
}
server {
listen 80;
server_name site2.example.com;
location / {
return 301 https://$host$request_uri;
}
}
設定反映と事前動作確認
「nginx -t」で書式の確認を行ってから、「Nginx」を再起動し設定を反映させます。
sudo nginx -t sudo systemctl restart nginx
クライアントPCのhosts設定変更
クライアントPC(作業用PC)のhostsファイルを編集し、一時的に移行作業を行ったサイトが新サーバーのIPを向くように設定します。
ブラウザでの動作確認
Webブラウザで「https://site1.example.com」や「https://site2.example.com」にアクセスし、新サーバー上で問題なくWordPressの閲覧や管理画面へのログイン、記事の投稿・画像の表示ができるかを確認してください。
トップページ以外が「404 Not Found」になる場合
もし、トップページは表示されるのに記事ページや固定ページを開くと「404 Not Found」になる場合は、URLリライト用の「.htaccess」が存在しないことが原因です(特に旧環境がNginxだった場合、「.htaccess」が存在しないため必ず発生します)。
また、プラグイン等でログインURLを変更している場合、「.htaccess」がないとログイン画面自体も404になり管理画面に入れなくなってしまいます。
その場合は、新サーバー側で以下のコマンドを実行して直接「.htaccess」を作成してください。
ボリュームのパスはご自分の環境にあわせて適宜読み替えてください。
サイト1用
podman unshare sh -c 'cat << "EOF" > ~/.local/share/containers/storage/volumes/wordpress_site1_data/_data/.htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOF
chown 33:33 ~/.local/share/containers/storage/volumes/wordpress_site1_data/_data/.htaccess'
サイト2用
podman unshare sh -c 'cat << "EOF" > ~/.local/share/containers/storage/volumes/wordpress_site2_data/_data/.htaccess
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
EOF
chown 33:33 ~/.local/share/containers/storage/volumes/wordpress_site2_data/_data/.htaccess'
※コマンド末尾の「chown 33:33」で、作成したファイルの所有者をWordPress(www-data)に設定し、管理画面からの編集や書き込み権限を付与しています。
コマンド実行後、ブラウザをリロードすれば各ページや変更後のログイン画面が正常に表示されるようになります。
管理画面にログインできる状態であれば、「設定」-「パーマリンク」を開いて「変更を保存」をクリックすることでも同様に「.htaccess」を自動生成できます。
確認が完了したら、PCのhosts設定は元に戻しておきます。
サーバー切り替え作業
DNS切り替え
ドメインのDNS設定(Aレコード)を変更し、サイト1とサイト2のアクセス先を新サーバーのIPアドレスに切り替えます。
Let's EncryptでSSL/TLS証明書の再取得
DNSの切り替えが完了し、インターネット上から新サーバーにアクセスできることが確認できたら、「certbot」を実行して新サーバー上で正式にSSL/TLS証明書を取得します。
sudo certbot --nginx -d site1.example.com -m メールアドレス --agree-tos sudo certbot --nginx -d site2.example.com -m メールアドレス --agree-tos
「--nginx」プラグインを指定しているため、コマンドが成功すると設定ファイル内の証明書パスが自動的にLet's Encrypt管理下のパス(/etc/letsencrypt/live/...)へ書き換えられ、Nginxへの設定反映(リロード)も自動的に完了します。
そのため、手動でNginxを再起動する必要はありません。
最終動作確認
Webブラウザでサイト1とサイト2にそれぞれHTTPSでアクセスし、問題なく表示されることを確認します。
ブラウザのアドレスバーにある鍵マークをクリックして証明書情報を開き、有効期間の開始日(発行日)が本日取得した日付に更新されていれば、すべての移行作業は完了です!
まとめ
別々のサーバーにあったWordPressでも、コンテナの「名前付きボリューム」と「独立したポート割り当て」を活用すれば、1つのMariaDBインスタンスに安全に集約・統合することができます。サーバーの運用コストやリソースを抑えたい方は、ぜひお試しください!
コメント