最近のLinuxサーバ運用では、セキュリティと管理のしやすさから「Webサーバ(Nginx)はホストで動かし、アプリケーション(WordPress)はコンテナで動かす」という構成が流行りつつあります。
今回は、「さくらのVPS」上にインストールされた「AlmaLinux 10」をベースに、デーモンレスで安全なコンテナエンジン「Podman」と「Nginx」を組合わせて、WordPress環境(Let's EncryptによるSSL対応)を構築する手順を紹介します。
今回のシステム構成
今回は、WordPressを「wp.server-memo.net」という名前(ドメイン)で外部に公開する構成を目指します。
みなさんの環境では適宜読み替えて作業を行ってください。
Nginx(ホスト側)
- ホストOSに直接インストール
- 外部からのhttps通信(443番ポート)を処理
- SSL/TLSの証明書を管理
- wp.server-memo.net宛の通信を、ローカルで動くPodmanコンテナ(wordpress)に転送(リバースプロキシ)
WordPress(Podmanコンテナ)
- Apacheやphp等のアプリケーション機能を担当
- WordPressのデータを管理
- ホストの127.0.0.1:8080番ポートにバインドし、localhostからのアクセスのみ許可
MariaDB(Podmanコンテナ)
- 最新のLTS版である「MariaDB 11.8」を使用し、データベース機能を担当
この構成のメリット
- SSL管理が簡単: コンテナ内部ではなく、ホスト側のNginxでCertbotを動かすため、Let's Encryptを利用したSSL証明書の取得と自動更新が簡単です。
- 高いセキュリティ: WordPressコンテナはローカルホスト(127.0.0.1)からの通信しか受け付けないため、外部から直接攻撃されるリスクを大幅に減らせます。
- 拡張性が抜群: 今後、別のドメインで他のアプリを動かしたくなった場合も、Nginxの設定を追加するだけで簡単に共存できます。
ファイアウォール(firewalld)設定
まずは外部からのWebアクセスを受け付けるために、HTTP(80番)とHTTPS(443番)のポートを開放しておきます。
ここからは root 権限で作業を行います。
# firewall-cmd --add-service=http --permanent # firewall-cmd --add-service=https --permanent # firewall-cmd --reload
Nginxインストール
最新版のNginxを利用するため、Nginxの公式リポジトリを使用してNginxをインストールします。
Nginxリポジトリを作成
# 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
Nginxのインストール
dnfを使ってnginxをインストールします。
# dnf install nginx
Nginxの起動と自動起動設定
Nginxの起動と、サーバ起動時に自動起動する設定も行っておきます。
# systemctl start nginx # systemctl enable nginx
Nginxの、より詳しいインストール方法の説明は、以下のページを参照してください。
https://www.server-memo.net/server-setting/nginx/almalinux10-nginx-install.html
Let's Encryptを使用してSSL/TLS証明書を取得
Certbotインストール
Let's EncryptでSSL/TLS証明書を取得するために必要な、certbotをインストールします。
# dnf install epel-release # dnf install certbot python3-certbot-nginx
SSL証明書取得
証明書を発行するために、Let's Encryptから一時的にアクセスできるドメインの疎通確認用のページを作ります。
ディレクトリ作成
今回は「/usr/share/nginx/wordpress」ディレクトリを作成します。
# mkdir -p /usr/share/nginx/wordpress # chown nginx:nginx /usr/share/nginx/wordpress
index.html作成
動作確認用のindex.htmlを作成します。
中身は適当に「TestPage」とか記述しておきます。
# vi /usr/share/nginx/wordpress/index.html
Nginx設定(SSL/TLS証明書取得用設定)
Let's Encryptがドメインの確認を行えるように、httpでアクセスできるだけという最低限の設定を行います。
# cd /etc/nginx/conf.d/ # vi wp.server-memo.net.conf
設定ファイルの中身は以下の通りです。
server {
listen 80;
server_name wp.server-memo.net;
root /usr/share/nginx/wordpress;
index index.html;
}
設定の反映
設定ファイルの構文チェックをした後に、Nginxの再起動して設定を反映させます。
# nginx -t # systemctl restart nginx
動作確認
Webブラウザで「http://wp.server-memo.net」へアクセスして、index.htmlの内容が表示されることを確認してください。
SSL/TLS証明書の取得
動作確認で問題がなければ、以下のコマンドでLet's EncryptからSSL/TLSの証明書を取得します。
# certbot --nginx -d ホスト名 -m 連絡先メールアドレス --agree-tos
以下は、コマンドの実行例になります。
# certbot --nginx -d wp.server-memo.net -m tamohiko@server-memo.net --agree-tos
SSL/TLS証明書の取得時、Nginxの設定ファイルへ自動的にhttps接続用の設定が追記されます。
https接続の確認
Webブラウザで「https://wp.server-memo.net」アクセスして、https接続にてindex.htmlの内容が表示されることを確認しておきます。
Podmanと関連ツールのインストール
AlmaLinux10では、標準リポジトリから簡単にPodmanをインストールできるので、コンテナエンジンの「podman」と、複数コンテナをまとめて管理できる「podman-compose」をインストールします。
# sudo dnf install podman podman-compose
インストールが完了したら、バージョンを確認しておきましょう。
# podman --version podman version 5.6.0 # podman-compose --version podman-compose version 1.5.0 podman version 5.6.0
Podman作業用ディレクトリの作成
ここから先はroot権限ではなく、一般ユーザで作業を進めていきます。
Podmanで作るコンテナを動作させるためのディレクトリ作成します。
今回はユーザのホームディレクトリに「wordpress-podman」という名前のディレクトリを作成していきます。
$ mkdir -p ~/wordpress-podman
compose.yaml の作成
2026年6月1日時点での最新LTS(長期サポート)版である「MariaDB 11.8」と「WordPress」の公式イメージを定義します。
$ cd ~/wordpress-podman $ vi compose.yaml
設定変更が必要な環境変数について
以下の項目は、セキュリティのためにご自分の環境に合わせた固有のパスワード等に適宜変更してください。
その際、WordPressコンテナの設定は、MariaDBコンテナで指定した値と必ず一致させる必要があります。
dbコンテナの環境変数(データベースの作成設定)
WordPress用のデータベースを新規作成するための初期設定です。
- MARIADB_ROOT_PASSWORD: MariaDB全体の管理者(rootユーザー)用のパスワードを設定
- MARIADB_DATABASE: WordPressが使用するデータベース名
- MARIADB_USER: wordpress用データベースの管理ユーザ名
- MARIADB_PASSWORD: wordpress用データベースの管理ユーザのパスワード
wordpressコンテナの環境変数(データベースへの接続設定)
WordPressがデータベースへアクセスするための情報です。
必ず上記「dbコンテナ」で設定した値と同じものを指定してください。
- WORDPRESS_DB_USER: MARIADB_USERで設定したユーザ名と一致させる
- WORDPRESS_DB_PASSWORD: MARIADB_PASSWORDで設定したパスワードと一致させる
- WORDPRESS_DB_NAME: MARIADB_DATABASEで設定したデータベース名と一致させる
services:
db:
image: docker.io/library/mariadb:11.8
restart: always
environment:
MARIADB_ROOT_PASSWORD: dbpass_change_me!
MARIADB_DATABASE: wordpress
MARIADB_USER: blog_admin
MARIADB_PASSWORD: blog_password_change_me!
volumes:
- db_data:/var/lib/mysql
wordpress:
image: docker.io/library/wordpress:latest
restart: always
ports:
# 外部には公開せずローカルホストからのアクセスのみ許可
# 8080番ポートをコンテナの80番ポートに転送
- "127.0.0.1:8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: blog_admin
WORDPRESS_DB_PASSWORD: blog_password_change_me!
WORDPRESS_DB_NAME: wordpress
# リバースプロキシ環境下でのリダイレクトループを防止
WORDPRESS_CONFIG_EXTRA: |
if (($$_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https') {
$$_SERVER['HTTPS'] = 'on';
}
volumes:
- wp_data:/var/www/html
depends_on:
- db
volumes:
db_data:
wp_data:
構築最大の罠:_SERVER のエスケープ($$)
WORDPRESS_CONFIG_EXTRA を使うと、コンテナ内のWordPressの設定ファイルである「wp-config.php」へ任意のPHPコードを設定できます。
ここで、Nginx側から引き渡された「HTTPS通信であること」をWordPressに正しく認識させるため「$_SERVER」を記述しますが、必ず「$$」と重ねて「$$_SERVER」とエスケープしてください。
「$」を1つのままにしてしまうと、「podman-compose」が起動時にホスト側の環境変数として解釈・展開しようとするため、コンテナに渡る段階で「$_SERVER」という文字列が丸ごと消滅してしまいます。
これが原因で、原因不明の「PHP Fatal error (500エラー)」を引き起こす最大級の罠が存在するため、必ずエスケープを忘れないようにしましょう。
データベースの文字コード設定について
古いMariaDB(10.5 以前)では、初期設定の文字コードは「latin1」となっていることが多く、日本語環境や絵文字を扱うには「utf8mb4」への設定変更が必要でした。
ですが、MariaDB 10.6 以降からは標準で、「utf8mb4」が適用されています。
今回の構成で使用している、MariaDB 11.8(LTS)も、文字コードが初期設定で「utf8mb4」になっているため、文字コードに関する設定を行う必要はありません。
コンテナの起動と初期動作確認
compose.yamlの準備ができたら、「podman-compose」コマンドを使ってコンテナをバックグラウンドで起動します。
$ podman-compose up -d
初回はイメージのダウンロード(Pull)が行われるため、少し時間がかかります。
コンテナの起動完了後、正常に動いているか「podman-compose ps」コマンドで確認します。
$ podman-compose ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 65ddd9eb2c2b docker.io/library/mariadb:11.8 mariadbd 44 minutes ago Up 44 minutes 3306/tcp wordpress-podman_db_1 d583ca3016a9 docker.io/library/wordpress:latest apache2-foregroun... 44 minutes ago Up 44 minutes 127.0.0.1:8080->80/tcp wordpress-podman_wordpress_1
2つのコンテナのSTATUSが「Up」状態になっていれば、コンテナの起動は成功です!
SSHトンネルを使った一時的な動作確認
現在の設定では、ホストのファイアウォールで8080番ポートへの接続を許可していないですし、wordpress用コンテナへ接続を127.0.0.1(localhost)からのみ許可する設定もしているため、外部からブラウザで直接8080番ポートへアクセスすることが出来ません。
ですので、手元のPCからSSHのポートフォワーディング(トンネル機能)を使ってセキュアにコンテナへ接続し、初期画面を確認してみます。
$ ssh -L 8080:localhost:8080 ユーザ名@接続先サーバ
このSSH接続を維持したまま、手元のPCのWebブラウザで 「http://localhost:8080」を開きます。
無事にWordPressのセットアップ画面(言語選択)が表示されれば、コンテナは正常に動作していることになります。
なお、ここではコンテナの動作確認を行うだけなので、WordPressの初期設定は行わないでください。
動作確認後、Webブラウザは閉じておいてください。
Nginxリーバスプロキシ設定
コンテナの動作確認ができたら、WordPress宛の通信をホスト側のNginxからwordpressコンテナへ転送する設定を行います。
ここからは再び管理者権限(root)で作業を行います。
共通プロキシ用パラーメタ設定
複数のドメインを設定する際にも使い回せるよう、プロキシ用のヘッダー定義ファイルを作成します。
# cd /etc/nginx # vi 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;
wordpressコンテナへリバースプロキシ設定とSSL/TLS証明書の自動更新用設定
現在の設定は、certbotを使用してEncryptのSSL/TLS証明書を取得した際に、httpsによる接続まではできるようになっています。
そこに、wp.server-memo.netあての通信をwordpressのコンテナに通信を転送(リバースプロキシ)する設定と、SSL証明書の自動更新を行うための設定を追加します。
# cd conf.d # cp -p wp.server-memo.net.conf wp.server-memo.net.conf_$(date "+%Y%m%d-%H%M%S") # vi wp.server-memo.net.conf
赤字部分の設定を追加します。
# 転送先の設定 (追加する設定) upstream podman_nginx { server 127.0.0.1:8080 fail_timeout=0; } server { server_name wp.server-memo.net; root /usr/share/nginx/wordpress; index index.html; listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/wp.server-memo.net/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/wp.server-memo.net/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot # Let's Encrypt 更新用設定 (追加する設定) location ^~ /.well-known { root /usr/share/nginx/wordpress; } # リバースプロキシ設定 (追加する設定) # wp.server-memo.net宛の通信は # upstreamで設定したpodman_nginxへ転送する location / { include proxy_params; proxy_pass http://podman_nginx; } } server { if ($host = wp.server-memo.net) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name wp.server-memo.net; return 404; # managed by Certbot }
設定反映
設定ファイルの構文チェックと、Nginxの再起動を行って設定の反映を行います。
# nginx -t # systemctl restart nginx
WordPressのセットアップ
webブラウザで「https://wp.server-memo.net」を開いてください。
WordPressのセットアップ画面が表示されるので、画面の指示に従って初期設定を行ってください。
その後、問題なくWordPressの管理画面にログインできれば構築は完了です。
コンテナの自動起動設定(Podman特有の必須設定)
最後に、サーバー起動時にデータベースとWordPressのコンテナが自動的に起動するように設定を行います。
この作業は、コンテナを動作させている「一般ユーザー」に戻って行います。
一般ユーザーでコンテナの自動起動を有効化
「systemctl」コマンドで、ユーザのsystemdにPodmanのコンテナを自動起動させるためのサービス「podman-restart.service」を登録します。
「podman-restart.service」は「Podman」をインストールした時点で、自動的に「/usr/lib/systemd/user/」に作成されているので、これを一般ユーザの「Systemd」に登録します。
$ systemctl --user enable --now podman-restart.service
ユーザーのシステム常駐(Linger)を許可
Almalinuxの標準仕様では、一般ユーザーがシステムからログアウトすると、そのユーザーが動かしていたバックグラウンドプロセスもすべて終了してしまいます。
「ユーザーがログインしていなくても、サーバ起動時にバックグラウンドでコンテナを動かす」ために、以下のコマンドで常駐許可(Linger)を出します。
これで、ユーザがログインしていない状態でもサービスを提供し続けられるようになります。
$ sudo loginctl enable-linger $USER
このコマンドは、sudoをつかって実行する必要があります。
root権限(#)の状態で「$USER」という環境変数を使うと、一般ユーザーではなく root ユーザーの「Linger」が有効になってしまうので、かならず「sudo」を使ってください。
常駐設定が正常に有効化されたか、以下のコマンドでステータスを確認しておきます。
$ loginctl show-user $USER -p Linger Linger=yes
「Linger=yes」と出力されれば設定は完了です。
サーバ再起動後の動作確認
サーバを再起動して、コンテナが自動的に起動し、「WordPress」が正常に動作するか確認してください。
# reboot
無事WordPressが動作すれば、構築は完了です。
お疲れ様でした!
コメント