背景
前情報などはこちらを参照してください。
概要
proxmox VE 8.3 のLXCコンテナ上に、HTTPサーバーとして apache を立てます。
コンテナに割り振っているIPは 192.168.1.7 とします。
コンテナのテンプレートは「rockylinux-9-default_20240912_amd64」
メモリは2GB、プロセッサは2コア与えています。
VirtualServer機能を使って複数ホストを運用します。
うち1つはWordPress(本サイト)を立てるのでそれに必要なモジュール等も導入します。
事前準備
以下を使用します。
テキストエディタに vim を導入していますが別に nano でも何でも好みのもので構いません。
[root@www ~]# dnf -y install vim
[root@www ~]# dnf -y install unzip
インストール
まずは本体
[root@www ~]# dnf -y install httpd
次にPHP
dnf -y install php でインストールされるPHPは8.0なので、サードパーティリポジトリをインストールします
[root@www ~]# dnf install -y 'dnf-command(config-manager)'
[root@www ~]# dnf config-manager --set-enabled crb
[root@www ~]# dnf install -y epel-release
[root@www ~]# dnf install -y https://rpms.remirepo.net/enterprise/remi-release-9.rpm
[root@www ~]# dnf config-manager --enable remi
[root@www ~]# dnf module install -y php:remi-8.3
続けてPHP拡張機能のインストール
[root@www ~]# dnf install -y php-mysqli
[root@www ~]# dnf install -y php83-php-gd.x86_64
[root@www ~]# find / -name gd.so
で、gd.sockの場所を確認します。
Permission denied が大量に出ると思いますが、正しくインストールされていればどこかに表示されるはずです。
当環境では、/opt/remi/php83/root/usr/lib64/php/modules/gd.so にありました。
remiではなくそのまま入れると /usr/lib64/php/modules/gd.so と全然場所が違うので注意。
/etc/php.ini に以下を追記
場所は多分どこでも良いです。一番下でも、extentionを書き連ねそうなコメントがある所など。
extension=/opt/remi/php83/root/usr/lib64/php/modules/gd.so
ついでに /etc/php.ini の以下の部分を変種してPHPのメモリ制限を緩和します
memory_limit = 3G
post_max_size = 2G
upload_max_filesize = 2G
max_input_time = 3600
max_execution_time = 3600
# 大きなファイルのアップロードに時間がかかる場合の考慮
php-fpm と httpd の有効化と起動
[root@www ~]# systemctl enable --now httpd; systemctl start httpd
[root@www ~]# systemctl enable php-fpm; systemctl start php-fpm
さらにデータベースのインストールと起動
[root@www ~]# dnf install -y mariadb-server
[root@www ~]# systemctl enable --now mariadb; systemctl restart mariadb
セットアップウィザードを実行します
[root@www ~]# mysql_secure_installation
内容はお好みで、私は大体以下のようにしています。
パスワード
Switch to unix_socket auth: n
Change root pass: n
Remove anonymous users: y
Deallow remote root login: y
Remove test db: y
Reload privilege table now: y
HTMLファイルとかを置く場所を作ります。
各々の好みの場所で良いですが、私は /var/www に hosts を作って、その中にサブドメイン名のフォルダを掘って、各 DocumentRoot に public_html を作ってます。
[root@www ~]# mkdir -p /var/www/hosts/www/public_html
[root@www ~]# mkdir -p /var/www/hosts/www/logs
複数ホストがあった場合のディレクトリ構造のイメージは以下のような感じです。
/var/www/hosts
├ www
│ ├ logs
│ └ public_html
│ ├ index.php
├ ddrcoterie
│ ├ logs
│ └ public_html
│ ├ index.php
VirtualHostの設定
/etc/httpd/conf/httpd.conf の最下行に以下をを追記します。
# VirtualHost設定
Include conf.hosts/*.conf
設定ファイルを格納する場所を作ります。
[root@www ~]# mkdir /etc/httpd/conf.hosts
VirtualHostの設定を作成します。
ファイル名の末尾は必ず .conf でなければなりません。
下記例では私の環境特有の設定が入っていますが、うまいこと調整してください。
[root@www ~]# vim /etc/httpd/conf.hosts/www.conf
<VirtualHost *:80>
ServerName www.cyane.info
ServerAlias www.local
ServerAdmin [email protected]
DocumentRoot /var/www/hosts/www/public_html
ErrorLog /var/www/hosts/www/logs/error_log
CustomLog /var/www/hosts/www/logs/access_log common
#PassengerEnabled off
DirectoryIndex index.php index.shtml index.html
Addhandler cgi-script .cgi
Addhandler cgi-script .pl
AddHandler text/css .css
AddHandler text/javascript .js
AddHandler php8-script .php
AddType text/html .shtml
AddHandler server-parsed .shtml
ScriptAlias /cgi-bin/ "/var/www/hosts/www/cgi-bin/"
<Directory />
# This relaxes Apache security settings.
AllowOverride all
# MultiViews must be turned off.
Options Includes IncludesNoExec MultiViews FollowSymLinks ExecCGI
#SetHandler cgi-script
Require all granted
</Directory>
</VirtualHost>
ドキュメントルートにオーナー権限を与えておきます。
(WordPressで必要)
[root@www ~]# chown -R apache:apache /var/www/hosts/www/public_html
apache再起動
[root@www ~]# systemctl restart httpd
WordPress用データベース作成
mariadb(mysql)にログイン
[root@www ~]# mysql -u root -p
DB名を db_wordpress
DBユーザー名を dbuser
DBパスワードを password とした場合、
MariaDB [(none)]> CREATE DATABASE db_wordpress;
MariaDB [(none)]> GRANT ALL PRIVILEGES ON db_wordpress.* TO "dbuser"@"localhost" IDENTIFIED BY 'password';
MariaDB [(none)]> FLUSH PRIVILEGES;
もし、手違いなどで削除する場合は
drop database db_wordpress;
退出は exit で出れます。
WordPressの導入
最新版をダウンロードします。
[root@www ~]# curl -LO https://ja.wordpress.org/latest-ja.zip
解凍
[root@www ~]# unzip latest-ja-zip
移動
[root@www ~]# mv wordpress/* /var/www/hosts/www/public_html/
WordPressが推奨要求するモジュールの導入
[root@www ~]# dnf install -y php-zip
[root@www ~]# dnf install -y php-intl
WP-CLIの導入
これは必須ではありませんので必要な場合に。引っ越し時等に便利です。
[root@www ~]# curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
動くかどうか確認
[root@www ~]# php wp-cli.phar --info
実行権限を付け、PATHに通します
[root@www ~]# chmod +x wp-cli.phar
[root@www ~]# mv wp-cli.phar /usr/local/bin/wp
動くかどうか確認
wp cli version
WordPressの設定
これまでの設定が無事完了していれば、ブラウザでアクセスすると設定画面が表示されるはずです。

先で設定したデータベース設定を入力します

あとは画面の指示通りで設定を進めれると思います。
その他、トラブルシューティング
WordPressのデータベース設定後「wp-config.php ファイルに書き込みできません。」という画面が表示される
こんな画面

書き込みのアクセス権限が無いようです。
[root@www ~]# chown -R apache:apache /var/www/hosts/www/public_html
で、オーナー権限を与えてあげてください。
mod_rewrite が動かない
モジュールが有効になってないとか、よく言われている類のものではなかったが、
.htaccessに MultiviewsMatch Any を追加したらいけた
(httpd.confに設定するのも良)
アクセスログのアクセス元がtraefikのIPになって正しく解析できない
仕組み上そうなりますので、対処の策を取る必要があります。
ちゃんと対策するには、CloudflareのEnterpriseプランオプションの「True-Client-IP ヘッダー」を有効にする必要がありそうです(※試していません)
以下、アクセス元を traefik から Cloudflare にするだけでも多少マシにはなりますが、Wordpressによるアクセスカウントは諦めて Google Analytics 等を活用した方が良いと思います。
httpd.confに RemoteIPHeader X-Forwarded-For を追加する
remoteip_module はデフォルトで有効になっていると思いますので以下の設定を行います。
[root@www ~]# vim /etc/httpd/conf/httpd.conf
Include conf.modules.d/*.conf
#の後辺りに以下を追記
RemoteIPHeader X-Forwarded-For
# TraefikのIP
RemoteIPTrustedProxy 192.168.1.4
その後apache再起動
[root@www ~]# systemctl restart httpd
通常、Apacheはリバースプロキシ(例: Cloudflare, Traefik)経由のアクセスではプロキシのIPアドレスをREMOTE_ADDRとして認識します。
RemoteIPHeader X-Forwarded-For を指定すると、リバースプロキシが送信する X-Forwarded-For ヘッダーの値をREMOTE_ADDRに上書きします。
これにより、Apacheは実際のクライアントIPを認識できます。
※ WordPress に SiteGuard の 管理ページアクセス制限 を設定している場合は、この時点で管理画面にアクセスできなくなるようです。管理画面にアクセスする場合はこの設定を外しておきましょう。
Cloudflareを設定し、「真のクライアント IP を送信する」 機能を有効にする。
有料機能
ドメイン選択 -> ネットワーク -> True-Client-IP ヘッダー
Cloudflare は、True-Client-IP ヘッダーでエンド ユーザーの IP アドレスを送信します
Enterpriseまたはそれ以上が必要です
を有効にすると出来そうな気がします。(※未確認)