- 記事一覧 >
- ブログ記事
RHEL9インストールからapache2+php-fpm+postgresql環境をオフラインで作成
はじめに
インターネット接続一切無し(オフライン)の状況で、RHEL9(Red Hat Enterprise Linux 9)をインストールして、
apache2(httpd) + php + php-fpm + postgresql 環境を作成しました。
この記事では、一連の作業を OS インストールからやっていきます。
オフラインの状況ですので、yum や dnf は使わず、DVD に入っている rpm のみで実施します。
https://rhel91.example.com/
とブラウザでアクセスして、/var/www/html/index.php
により、
postgresql の hello という DB にレコードをインサート、インサートした結果表示
までをゴールとします。
短時間で作業したい方は、
まとめ
セクションを見てください。OSインストール以降のやることを、説明を省略してまとめ直しています。
オフラインとは言っても、OS の iso はダウンロード済みとします。
今回使用するのは、
rhel-baseos-9.1-x86_64-dvd.iso
です。
【検証環境】
Windows 10 Pro x64
Red Hat Enterprise Linux 9.1(5.14.0-162.6.1.el9_1.x86_64)
VMware Workstation 16 Pro
httpd-2.4.53-7
php-8.1.8-1
postgresql-13.7-1
CentOS Stream 9 の場合もやってみましたが、ほぼ同じでした。
細かいバージョンが若干違っていたため、
おまけ(CentOS9) セクションにまとめました。
CentOS Stream 9 のカーネルバージョンは、
5.14.0-205.el9.x86_64
です。
今回、
ホスト名=
rhel91.example.com
IPアドレス=
192.168.12.12
としてやっていきます。
RHEL9.1 インストール
OS インストール
新規仮想マシン作成のところは省略します。今回、9 が選択肢に無かったため、Red Hat Enterprise Linux 8 (64 ビット) を選択して、新規仮想マシンを作成しています。
...細かいところは省略します。
時刻と日付 を選択して、東京 を選択します。
今回、NTP は使わないものとし、ネットワーク時刻を OFF にして手動で設定します。
ソフトウェアの選択 は、変更せず、デフォルトの サーバー (GUI 使用) とします。
インストール先 を選択して、ストレージの設定 - カスタム を選択し、完了をクリックします。
ここをクリックすると自動的に作成します。 をクリックします。
/home
、/
を マイナスボタン で削除して、プラスボタン をクリックし、
マウントポイント:/
要求される容量:(空白)
とします。
マウスホイールで下の隠れている部分を表示して、root パスワード をクリックします。
root パスワードを設定後、インストールの開始 をクリックします。
起動したら、ユーザー設定後、IP アドレスを設定し、SSH で接続可能になります。
ユーザーの設定は、インストールを終えて、起動後になったようです。
ホスト名設定
ここからは、SSH で作業になります。ターミナルで作業でも構いません。
特別な説明が無い場合、
root
で作業しているものとします。
ホスト名を設定します。ここでは、ホスト名=rhel91.example.com
とします。
# hostnamectl set-hostname rhel91.example.com
php-fpm 設定について
mod_php は、Deprecated というか、インストールされなくなりました。そのため、apache - php の連携は、php-fpm(fpm = FastCGI Process Manager)を使います。
【 FastCGI 】
FastCGI とは、Web サーバ上でユーザプログラムを動作させるためのインタフェース仕様の一つです。プロセスの起動/終了を省略することで、負荷を軽減しています。
また、MPM(Multi Processing Module、Apache がどのようにリクエストを処理するかの方式)が worker、prefork、event とあるのですが、この記事の手順通りの進めると、最初から event になっているため、このままとします。
Apache 側の FastCGI 対応は、この記事の手順通りの進めると、最初から mod_proxy_fcgi によって実現するため、これをそのまま使います。
よって、ほとんど意識しないまま、以下の設定が最初から組み込まれます。
機能 | 初期設定 |
---|---|
Apache の MPM | event |
Apache 側の FastCGI 対応 | mod_proxy_fcgi |
Apache - PHP 連携 | php-fpm |
Apache - php-fpm 間は、UNIX ドメインソケット /run/php-fpm/www.sock
を通して行う設定になっています。
Apache、php-fpm 双方最初からその設定になっています。
ユーザーは、双方、apache
が設定されています。
よって、ソケットファイル違いやパーミッション問題が起きることは無く、そのまま使えます。
# User/Group: The name (or #number) of the user/group to run httpd as.
# It is usually good practice to create a dedicated user and group for
# running httpd, as with most system services.
#
User apache
Group apache
<IfModule !mod_php.c>
# Enable http authorization headers
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
<FilesMatch \.(php|phar)$>
SetHandler "proxy:unix:/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>
</IfModule>
; Note: This value is mandatory.
listen = /run/php-fpm/www.sock
; Set listen(2) backlog.
; Default Value: 511
;listen.backlog = 511
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server.
; Default Values: user and group are set as the running user
; mode is set to 0660
;listen.owner = nobody
;listen.group = nobody
;listen.mode = 0660
; When POSIX Access Control Lists are supported you can set them using
; these options, value is a comma separated list of user/group names.
; When set, listen.owner and listen.group are ignored
listen.acl_users = apache,nginx
httpd インストール
OS インストールで使った DVD(rhel-baseos-9.1-x86_64-dvd.iso
)をマウントします。
# mount /dev/cdrom /media
httpd-2.4.53
をインストールします。
# rpm -i /media/AppStream/Packages/httpd-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/httpd-core-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/redhat-logos-httpd-90.4-1.el9.noarch.rpm \
/media/AppStream/Packages/httpd-filesystem-2.4.53-7.el9.noarch.rpm \
/media/AppStream/Packages/httpd-tools-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/apr-1.7.0-11.el9.x86_64.rpm \
/media/AppStream/Packages/apr-util-1.6.1-20.el9.x86_64.rpm \
/media/AppStream/Packages/apr-util-bdb-1.6.1-20.el9.x86_64.rpm
httpd-2.4.53-7.el9.x86_64.rpm
以外にインストールしているのは、依存性の欠如エラー回避のためです。念のため入れているとかではなく、事実上必須です。以降、複数まとめて
rpm -i
のところは、同じ理由です。
PHP インストール
php-8.1.8-1
をインストールします。
# rpm -i /media/AppStream/Packages/php-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/php-cli-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/php-pgsql-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/php-common-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/libpq-13.5-1.el9.x86_64.rpm \
/media/AppStream/Packages/php-pdo-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
PostgreSQL インストール
postgresql-13.7-1
をインストールします。
# rpm -i /media/AppStream/Packages/postgresql-13.7-1.el9_0.x86_64.rpm \
/media/AppStream/Packages/postgresql-private-libs-13.7-1.el9_0.x86_64.rpm
PostgreSQL サーバー(postmaster)をインストールします。
# rpm -i /media/AppStream/Packages/postgresql-server-13.7-1.el9_0.x86_64.rpm
php-fpm インストール
php-fpm をインストールします。
# rpm -i /media/AppStream/Packages/php-fpm-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/nginx-filesystem-1.20.1-13.el9.noarch.rpm
mod_ssl インストール
今回、https://rhel91.example.com/
でアクセスしようと思うため、mod_ssl をインストールします。
# rpm -i /media/AppStream/Packages/mod_ssl-2.4.53-7.el9.x86_64.rpm
自己署名の SSL 証明書を作成します。
証明書の作り方は任意です。
別記事「CentOS8 & Apacheの自己署名証明書作成と証明書エラー回避」のやり方で作成しています。
# cd /home/admin
# openssl genrsa -out server.key 2048
# openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Aichi
Locality Name (eg, city) [Default City]:Toyota
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:rhel91.example.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# echo "subjectAltName=DNS:*.example.com,IP:192.168.12.12" > san.txt
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -extfile san.txt
# mkdir /etc/httpd/conf/ssl.key /etc/httpd/conf/ssl.crt
# cp server.key /etc/pki/tls/private/localhost.key
# cp server.crt /etc/pki/tls/certs/localhost.crt
# chmod 400 /etc/pki/tls/private/localhost.key
# chmod 400 /etc/pki/tls/certs/localhost.crt
設定調整
冒頭記載の通り、最初から以下の組み合わせの設定になっているため、最低限の変更にします。
機能 | 初期設定 |
---|---|
Apache の MPM | event |
Apache 側の FastCGI 対応 | mod_proxy_fcgi |
Apache - PHP 連携 | php-fpm |
動けばOKで、セキュリティの都合とかは全く考えていません。
ssl.conf
443 ポートのホスト名を設定します。
# vi /etc/httpd/conf.d/ssl.conf
#ServerName www.example.com:443
ServerName rhel91.example.com:443
php.ini
php のタイムゾーンを変更します。(ログ出力が UTC になるため、ここだけ変更します。)
# vi /etc/php.ini
date.timezone = Asia/Tokyo
firewall 解放
443 ポートを開放します。
# firewall-cmd --add-service=https --permanent
# firewall-cmd --reload
SELinux 設定
httpd - php -> postgresql
の接続を許可します。
これが無いと、php から postgresql への接続に失敗し、/var/log/audit/audit.log
に以下の出力があります。
type=AVC msg=audit(1670753373.220:225): avc: denied { name_connect } for pid=2866 comm="php-fpm" dest=5432 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:postgresql_port_t:s0 tclass=tcp_socket permissive=0
# setsebool -P httpd_can_network_connect 1
httpd php-fpm 起動
# /usr/sbin/apachectl configtest
Syntax OK
# systemctl start httpd
# systemctl start php-fpm
PostgreSQL DB 作成
テスト用DBを作成します。
DB名:hello
テーブル名:hello_table
で、
テーブルのスキーマは、以下とします。
列名 | 型 |
---|---|
id | SERIAL |
message | VARCHAR |
まず、DB を初期化します。
# su - postgres
$ initdb
postgresql サービスを起動します。
$ exit
# systemctl start postgresql
DB名:hello
を作成します。
# su - postgres
$ psql -l
データベース一覧
名前 | 所有者 | エンコーディング | 照合順序 | Ctype(変換演算子) | アクセス権限
-----------+----------+------------------+-------------+-------------------+-----------------------
postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 |
template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
(3 行)
$ createdb hello
テーブル名:hello_table
を作成します。
$ psql -d hello
hello=# CREATE TABLE hello_table (
id SERIAL,
message VARCHAR,
PRIMARY KEY(id)
);
hello=# \q
$ exit
動作確認
プログラム作成
phpinfo()
を表示する php プログラムを作成します。https://rhel91.example.com/info.php
でアクセスするものです。
# vi /var/www/html/info.php
# chown apache /var/www/html/info.php
<?php
phpinfo();
次に、
DB Select
↓
DB Insert
↓
DB Select
の結果を表示するプログラムを作成します。
https://rhel91.example.com/
でアクセスするものです。
# vi /var/www/html/index.php
# chown apache /var/www/html/index.php
<?php
$connection = pg_connect("host=localhost dbname=hello user=postgres password=");
if (!$connection) {
exit(pg_last_error());
}
echo "Successful connection.<br />";
$select_sql = "SELECT id, message FROM hello_table";
echo "<br />" . $select_sql . "<br />";
$result = pg_query($select_sql);
if (!$result) {
exit(pg_last_error());
}
for ($i = 0; $i < pg_num_rows($result); $i++) {
$rows = pg_fetch_array($result, null, PGSQL_ASSOC);
echo "id=" . $rows["id"];
echo ",message=" . $rows["message"] . "<br />";
}
$insert_sql =
"INSERT INTO hello_table(message) VALUES ('hello php and postgresql!')";
echo "<br />" . $insert_sql . "<br />";
$result_flag = pg_query($insert_sql);
if (!$result_flag) {
exit(pg_last_error());
}
echo "<br />" . $select_sql . "<br />";
$result = pg_query($select_sql);
if (!$result) {
exit(pg_last_error());
}
for ($i = 0; $i < pg_num_rows($result); $i++) {
$rows = pg_fetch_array($result, null, PGSQL_ASSOC);
print "id=" . $rows["id"];
print ",message=" . $rows["message"] . "<br />";
}
$close_flag = pg_close($connection);
if ($close_flag) {
echo "<br />Disconnected successfully.<br />";
}
動作確認結果
https://rhel91.example.com/info.php
↓
OK!
https://rhel91.example.com/
↓
OK!
もう一度、https://rhel91.example.com/
(リロード)
↓
OK!
まとめ
OSインストール直後からの作業まとめです。
# hostnamectl set-hostname rhel91.example.com
# mount /dev/cdrom /media
# rpm -i /media/AppStream/Packages/httpd-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/httpd-core-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/redhat-logos-httpd-90.4-1.el9.noarch.rpm \
/media/AppStream/Packages/httpd-filesystem-2.4.53-7.el9.noarch.rpm \
/media/AppStream/Packages/httpd-tools-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/apr-1.7.0-11.el9.x86_64.rpm \
/media/AppStream/Packages/apr-util-1.6.1-20.el9.x86_64.rpm \
/media/AppStream/Packages/apr-util-bdb-1.6.1-20.el9.x86_64.rpm
# rpm -i /media/AppStream/Packages/php-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/php-cli-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/php-pgsql-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/php-common-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/libpq-13.5-1.el9.x86_64.rpm \
/media/AppStream/Packages/php-pdo-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
# rpm -i /media/AppStream/Packages/postgresql-13.7-1.el9_0.x86_64.rpm \
/media/AppStream/Packages/postgresql-private-libs-13.7-1.el9_0.x86_64.rpm
# rpm -i /media/AppStream/Packages/postgresql-server-13.7-1.el9_0.x86_64.rpm
# rpm -i /media/AppStream/Packages/php-fpm-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm \
/media/AppStream/Packages/nginx-filesystem-1.20.1-13.el9.noarch.rpm
# rpm -i /media/AppStream/Packages/mod_ssl-2.4.53-7.el9.x86_64.rpm
# cd /home/admin
# openssl genrsa -out server.key 2048
# openssl req -new -key server.key -out server.csr
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Aichi
Locality Name (eg, city) [Default City]:Toyota
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:rhel91.example.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
# echo "subjectAltName=DNS:*.example.com,IP:192.168.12.12" > san.txt
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -extfile san.txt
# mkdir /etc/httpd/conf/ssl.key /etc/httpd/conf/ssl.crt
# cp server.key /etc/pki/tls/private/localhost.key
# cp server.crt /etc/pki/tls/certs/localhost.crt
# chmod 400 /etc/pki/tls/private/localhost.key
# chmod 400 /etc/pki/tls/certs/localhost.crt
# vi /etc/httpd/conf.d/ssl.conf
#ServerName www.example.com:443
ServerName rhel91.example.com:443
# vi /etc/php.ini
date.timezone = Asia/Tokyo
# firewall-cmd --add-service=https --permanent
# firewall-cmd --reload
# setsebool -P httpd_can_network_connect 1
# /usr/sbin/apachectl configtest
Syntax OK
# systemctl start httpd
# systemctl start php-fpm
# su - postgres
$ initdb
$ exit
# systemctl start postgresql
# su - postgres
$ createdb hello
$ psql -d hello
hello=# CREATE TABLE hello_table (
id SERIAL,
message VARCHAR,
PRIMARY KEY(id)
);
hello=# \q
$ exit
# vi /var/www/html/info.php
# chown apache /var/www/html/info.php
<?php
phpinfo();
# vi /var/www/html/index.php
# chown apache /var/www/html/index.php
<?php
$connection = pg_connect("host=localhost dbname=hello user=postgres password=");
if (!$connection) {
exit(pg_last_error());
}
echo "Successful connection.<br />";
$select_sql = "SELECT id, message FROM hello_table";
echo "<br />" . $select_sql . "<br />";
$result = pg_query($select_sql);
if (!$result) {
exit(pg_last_error());
}
for ($i = 0; $i < pg_num_rows($result); $i++) {
$rows = pg_fetch_array($result, null, PGSQL_ASSOC);
echo "id=" . $rows["id"];
echo ",message=" . $rows["message"] . "<br />";
}
$insert_sql =
"INSERT INTO hello_table(message) VALUES ('hello php and postgresql!')";
echo "<br />" . $insert_sql . "<br />";
$result_flag = pg_query($insert_sql);
if (!$result_flag) {
exit(pg_last_error());
}
echo "<br />" . $select_sql . "<br />";
$result = pg_query($select_sql);
if (!$result) {
exit(pg_last_error());
}
for ($i = 0; $i < pg_num_rows($result); $i++) {
$rows = pg_fetch_array($result, null, PGSQL_ASSOC);
print "id=" . $rows["id"];
print ",message=" . $rows["message"] . "<br />";
}
$close_flag = pg_close($connection);
if ($close_flag) {
echo "<br />Disconnected successfully.<br />";
}
おまけ(CentOS9)
rpm のところで、以下のファイル名が異なっていて、読み替えが必要でした。 それ以外は、RHEL9.1と同じ要領でできました。
/media/AppStream/Packages/redhat-logos-httpd-90.4-1.el9.noarch.rpm
↓/media/AppStream/Packages/centos-logos-httpd-90.4-1.el9.noarch.rpm
/media/AppStream/Packages/php-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
↓/media/AppStream/Packages/php-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
/media/AppStream/Packages/php-cli-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
↓/media/AppStream/Packages/php-cli-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
/media/AppStream/Packages/php-pgsql-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
↓/media/AppStream/Packages/php-pgsql-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
/media/AppStream/Packages/php-common-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
↓/media/AppStream/Packages/php-common-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
/media/AppStream/Packages/php-pdo-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
↓/media/AppStream/Packages/php-pdo-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
/media/AppStream/Packages/postgresql-13.7-1.el9_0.x86_64.rpm
↓/media/AppStream/Packages/postgresql-13.7-1.el9.x86_64.rpm
/media/AppStream/Packages/postgresql-private-libs-13.7-1.el9_0.x86_64.rpm
↓/media/AppStream/Packages/postgresql-private-libs-13.7-1.el9.x86_64.rpm
/media/AppStream/Packages/postgresql-server-13.7-1.el9_0.x86_64.rpm
↓/media/AppStream/Packages/postgresql-server-13.7-1.el9.x86_64.rpm
/media/AppStream/Packages/php-fpm-8.1.8-1.module+el9.1.0+15877+c3862210.x86_64.rpm
↓/media/AppStream/Packages/php-fpm-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
以下の部分以外はRHEL9.1と全く同じ手順でした。
# rpm -i /media/AppStream/Packages/httpd-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/httpd-core-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/centos-logos-httpd-90.4-1.el9.noarch.rpm \
/media/AppStream/Packages/httpd-filesystem-2.4.53-7.el9.noarch.rpm \
/media/AppStream/Packages/httpd-tools-2.4.53-7.el9.x86_64.rpm \
/media/AppStream/Packages/apr-1.7.0-11.el9.x86_64.rpm \
/media/AppStream/Packages/apr-util-1.6.1-20.el9.x86_64.rpm \
/media/AppStream/Packages/apr-util-bdb-1.6.1-20.el9.x86_64.rpm
# rpm -i /media/AppStream/Packages/php-8.1.8-1.module_el9+158+97f99411.x86_64.rpm \
/media/AppStream/Packages/php-cli-8.1.8-1.module_el9+158+97f99411.x86_64.rpm \
/media/AppStream/Packages/php-pgsql-8.1.8-1.module_el9+158+97f99411.x86_64.rpm \
/media/AppStream/Packages/php-common-8.1.8-1.module_el9+158+97f99411.x86_64.rpm \
/media/AppStream/Packages/libpq-13.5-1.el9.x86_64.rpm \
/media/AppStream/Packages/php-pdo-8.1.8-1.module_el9+158+97f99411.x86_64.rpm
# rpm -i /media/AppStream/Packages/postgresql-13.7-1.el9.x86_64.rpm \
/media/AppStream/Packages/postgresql-private-libs-13.7-1.el9.x86_64.rpm
# rpm -i /media/AppStream/Packages/postgresql-server-13.7-1.el9.x86_64.rpm
# rpm -i /media/AppStream/Packages/php-fpm-8.1.8-1.module_el9+158+97f99411.x86_64.rpm \
/media/AppStream/Packages/nginx-filesystem-1.20.1-13.el9.noarch.rpm
# rpm -i /media/AppStream/Packages/mod_ssl-2.4.53-7.el9.x86_64.rpm
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。