はじめに
ARM で PHP8.1 をセルフビルドして、Nginx と共に動かす方法です。
DNF コマンドで PHP を入れると古い、あるいはパッケージが取得できない場合に当記事の方法が有効です。
Raspberry Pi も同様の手順で出来るはずです。
環境
- OCI Oracle Cloud / Ampere A1
- Oracle Linux 8 (CentOS, Fedora など RHEL 系ならどれでも可)
建てるもの
- Nginx
- PHP 8.1
- MySQL
実際に建てる
リポジトリ有効化
# dnf repolist all
repo id repo name status
ol8_MySQL80 MySQL 8.0 for Oracle Linux 8 (aarch64) enabled
ol8_MySQL80_connectors_community MySQL 8.0 Connectors Community for Oracle Linux 8 (aarch64) enabled
ol8_MySQL80_tools_community MySQL 8.0 Tools Community for Oracle Linux 8 (aarch64) enabled
ol8_aarch64_userspace_ksplice Ksplice aware userspace packages for Oracle Linux 8 (aarch64) disabled
ol8_addons Oracle Linux 8 Addons (aarch64) enabled
ol8_appstream Oracle Linux 8 Application Stream (aarch64) enabled
ol8_baseos_latest Oracle Linux 8 BaseOS Latest (aarch64) enabled
ol8_codeready_builder Oracle Linux 8 CodeReady Builder (aarch64) - Unsupported enabled
ol8_developer Oracle Linux 8 Development Packages (aarch64) disabled
ol8_developer_EPEL Oracle Linux 8 EPEL Packages for Development (aarch64) enabled
ol8_developer_UEKR6 Developer Preview of UEK Release 6 (aarch64) disabled
ol8_distro_builder Oracle Linux 8 Distro Builder (aarch64) - Unsupported disabled
ol8_ksplice Ksplice for Oracle Linux 8 (aarch64) enabled
ol8_kvm_appstream Oracle Linux 8 KVM Application Stream (aarch64) disabled
ol8_oci_included Oracle Software for OCI users on Oracle Linux 8 (aarch64) enabled
ol8_u2_baseos_base Oracle Linux 8.2 BaseOS (aarch64) disabled
ol8_u3_baseos_base Oracle Linux 8.3 BaseOS (aarch64) disabled
ol8_u4_baseos_base Oracle Linux 8.4 BaseOS (aarch64) disabled
# dnf config-manager --enable ol8_developer_EPEL
# dnf config-manager --enable ol8_codeready_builder
# dnf upgrade
Oracle Linux 以外の RHEL 系を使っている場合も、同様の手順で
EPEL と PowerTools または codeready-builder のリポジトリを有効化します。
Nginx をインストール
インストール
# dnf -y install nginx
# vi /usr/lib/systemd/system/nginx.service
nginx.service
[Service]
Type=forking
LimitNOFILE=65535 // 修正
# systemctl daemon-reload
SELinux の修正
- .teファイルを作成する
- .teファイルから.modファイルを作成する
- .modファイルからバイナリの.ppファイルを作成する
- .ppファイルをsemoduleに読み込ませてSELinuxのポリシーに追加する
# vi nginx-passenger.te
nginx-passenger.te
module nginx-passenger 1.0;
require {
type var_run_t;
type user_home_dir_t;
type httpd_t;
type user_home_t;
type httpd_tmp_t;
type httpd_tmpfs_t;
type passenger_exec_t;
type postgresql_port_t;
type httpd_log_t;
type httpd_sys_content_t;
type postfix_etc_t;
type var_log_t;
type root_t;
type etc_runtime_t;
type fusefs_t;
type default_t;
type http_cache_port_t;
type unreserved_port_t;
type unconfined_t;
type admin_home_t;
type system_mail_t;
type httpd_sys_rw_content_t;
class process execmem;
class capability { fowner sys_resource fsetid sys_ptrace };
class tcp_socket name_connect;
class shm { associate getattr read unix_read unix_write write destroy };
class file { execute setattr read create execute_no_trans write ioctl open append map };
class capability2 block_suspend;
class process ptrace;
class process setrlimit;
class file { ioctl write execute setattr read rename create open execute_no_trans getattr lock};
class lnk_file { read getattr write open };
class dir { write search read create open getattr add_name };
class sock_file write;
}
#============= httpd_t ==============
allow httpd_t httpd_tmp_t:file execute;
allow httpd_t httpd_tmpfs_t:file execute;
allow httpd_t httpd_log_t:file setattr;
allow httpd_t passenger_exec_t:dir { search getattr };
allow httpd_t self:capability sys_ptrace;
allow httpd_t self:process ptrace;
allow httpd_t self:process execmem;
allow httpd_t self:capability2 block_suspend;
allow httpd_t user_home_t:file { execute execute_no_trans read open write };
allow httpd_t var_run_t:file { read write };
allow httpd_t postfix_etc_t:file { read getattr open };
allow httpd_t root_t:dir write;
allow httpd_t root_t:dir add_name;
allow httpd_t root_t:file create;
allow httpd_t root_t:file { open read write };
allow httpd_t root_t:file lock;
allow httpd_t etc_runtime_t:file write;
allow httpd_t fusefs_t:file { getattr read open write };
allow httpd_t fusefs_t:dir { read write };
allow httpd_t user_home_t:lnk_file { read write open };
allow httpd_t default_t:lnk_file { read write open };
allow httpd_t default_t:file { read write open };
allow httpd_t http_cache_port_t:tcp_socket name_connect;
allow httpd_t unreserved_port_t:tcp_socket name_connect;
allow httpd_t admin_home_t:file getattr;
allow system_mail_t httpd_sys_rw_content_t:file { read write };
allow httpd_t unconfined_t:shm { unix_read unix_write associate getattr read write destroy };
allow httpd_t self:process setrlimit;
allow httpd_t var_log_t:file open;
allow httpd_t root_t:file map;
allow httpd_t var_run_t:sock_file write;
# checkmodule -M -m -o nginx-passenger.mod nginx-passenger.te
# semodule_package -o nginx-passenger.pp -m nginx-passenger.mod
# semodule -i nginx-passenger.pp
PHP8.1 をビルドしてインストールする
# dnf install -y gcc-c++ libxslt-devel sqlite-devel bzip2-devel gd-devel oniguruma-devel libzip-devel openssl-devel curl-devel libsodium libsodium-devel libicu-devel
# mkdir -p /root/pkg
# cd /root/pkg
# wget --no-check-certificate https://www.php.net/distributions/php-8.1.6.tar.gz
# tar zxvf php-8.1.6.tar.gz
# cd php-8.1.6
# ./configure --prefix=/usr/local/php-8.1.6 \
--with-config-file-path=/etc \
--enable-soap --with-zlib-dir --with-iconv \
--enable-mbstring --with-zip --enable-exif \
--enable-gd --with-external-gd --with-zlib \
--with-webp --with-jpeg --with-bz2 \
--with-libxml --enable-gd-jis-conv \
--with-freetype --with-xpm \
--enable-sockets --with-openssl \
--with-gettext --enable-sigchild \
--enable-opcache --enable-fpm \
--with-fpm-user=nginx --with-fpm-group=nginx \
--with-pdo_mysql --with-curl --enable-exif \
--enable-bcmath --enable-mbstring=all \
--enable-pcntl --enable-intl --with-sodium \
--enable-mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd
~ 略 ~
+--------------------------------------------------------------------+
| License: |
| This software is subject to the PHP License, available in this |
| distribution in the file LICENSE. By continuing this installation |
| process, you are bound by the terms of this license agreement. |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point. |
+--------------------------------------------------------------------+
Thank you for using PHP.
# make;make install
~ 略 ~
Build complete.
Don't forget to run 'make test'.
Installing shared extensions: /usr/local/php-8.1.6/lib/php/extensions/no-debug-non-zts-20210902/
Installing PHP CLI binary: /usr/local/php-8.1.6/bin/
Installing PHP CLI man page: /usr/local/php-8.1.6/php/man/man1/
Installing PHP FPM binary: /usr/local/php-8.1.6/sbin/
Installing PHP FPM defconfig: /usr/local/php-8.1.6/etc/
Installing PHP FPM man page: /usr/local/php-8.1.6/php/man/man8/
Installing PHP FPM status page: /usr/local/php-8.1.6/php/php/fpm/
Installing phpdbg binary: /usr/local/php-8.1.6/bin/
Installing phpdbg man page: /usr/local/php-8.1.6/php/man/man1/
Installing PHP CGI binary: /usr/local/php-8.1.6/bin/
Installing PHP CGI man page: /usr/local/php-8.1.6/php/man/man1/
Installing build environment: /usr/local/php-8.1.6/lib/php/build/
Installing header files: /usr/local/php-8.1.6/include/php/
Installing helper programs: /usr/local/php-8.1.6/bin/
program: phpize
program: php-config
Installing man pages: /usr/local/php-8.1.6/php/man/man1/
page: phpize.1
page: php-config.1
/root/pkg/php-8.1.6/build/shtool install -c ext/phar/phar.phar /usr/local/php-8.1.6/bin/phar.phar
ln -s -f phar.phar /usr/local/php-8.1.6/bin/phar
Installing PDO headers: /usr/local/php-8.1.6/include/php/ext/pdo/
Imagick をビルドしてインストールする
# dnf install -y ImageMagick-devel autoconf
# wget --no-check-certificate https://pecl.php.net/get/imagick-3.7.0.tgz
# tar zxvf imagick-3.7.0.tgz
# cd imagick-3.7.0/
# /usr/local/php-8.1.6/bin/phpize
Configuring for:
PHP Api Version: 20210902
Zend Module Api No: 20210902
Zend Extension Api No: 420210902
# ./configure --with-php-config=/usr/local/php-8.1.6/bin/php-config
creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h
# make; make install
~ 略 ~
----------------------------------------------------------------------
Libraries have been installed in:
/home/opc/imagick-3.7.0/modules
If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
- add LIBDIR to the `LD_LIBRARY_PATH' environment variable
during execution
- add LIBDIR to the `LD_RUN_PATH' environment variable
during linking
- use the `-Wl,--rpath -Wl,LIBDIR' linker flag
- have your system administrator add LIBDIR to `/etc/ld.so.conf'
See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
Build complete.
Don't forget to run 'make test'.
Installing shared extensions: /usr/local/php-8.1.6/lib/php/extensions/no-debug-non-zts-20210902/
Installing header files: /usr/local/php-8.1.6/include/php/
拡張を追記する
# ls -al /usr/local/php-8.1.6/lib/php/extensions/no-debug-non-zts-20210902/
total 5112
drwxr-xr-x. 2 root root 42 Sep 16 07:52 .
drwxr-xr-x. 3 root root 39 Sep 11 10:06 ..
-rwxr-xr-x. 1 root root 1621448 Sep 16 07:52 imagick.so
-rwxr-xr-x. 1 root root 3609728 Sep 11 10:06 opcache.so
# cp /root/pkg/php-8.1.6/php.ini-production /etc/php.ini
# vi /etc/php.ini
php.ini
// ▼ コメント解除して変更
extension_dir = "/usr/local/php-8.1.6/lib/php/extensions/no-debug-non-zts-20210902/"
date.timezone = Asia/Tokyo
expose_php = Off
post_max_size = 500M
upload_max_filesize = 200M
memory_limit = 512M
[opcache]
zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=192
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.revalidate_path=1
opcache.dups_fix=1
opcache.enable_file_override=1
opcache.enable_cli=0
// ▼ 追記
[imagick]
extension=imagick.so
PHP の設定を確認
# cd /usr/local/
# ln -s php-8.1.6 php
# cd /usr/local/php/bin
# ./php -v
PHP 8.1.6 (cli) (built: May 16 2022 06:09:27) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.6, Copyright (c) Zend Technologies
with Zend OPcache v8.1.6, Copyright (c), by Zend Technologies
OPcache の拡張が読み込めていれば完了。
Nginx と PHP の接続
Nginx を PHP-FPM を使って PHP と接続します。プロトコルには TCP を使います。
UDS を使う事もできますが、その場合はさらに SELinux に手を入れる必要があります。
# mkdir -p /var/log/php-fpm/
# cd /usr/local/php/etc
# cp php-fpm.conf.default php-fpm.conf
# vi php-fpm.conf
php-fpm.conf
// ▼ コメントアウトを解除して編集
pid = run/php-fpm.pid
error_log = /var/log/php-fpm/php-fpm.log
log_level = debug
daemonize = yes
include=/usr/local/php-8.1.6/etc/php-fpm.d/*.conf
# cd /usr/local/php/etc/php-fpm.d
# cp www.conf.default www.conf
# vi www.conf
www.conf
# ▼ デフォルト値のままでよい(異なっていれば編集)
[www]
user = nginx
group = nginx
listen = 9000
# ▼ 編集、またはコメントアウトを解除して編集
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 40
pm.max_requests = 500
access.log = /var/log/php-fpm/$pool.access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
slowlog = /var/log/php-fpm/$pool.log.slow
request_slowlog_timeout = 1
catch_workers_output = yes
php_admin_value[error_log] = /var/log/php-fpm/$pool.error.log
php_admin_flag[log_errors] = on
PHP-FPM をサービスに登録する
# cd /root/pkg/php-8.1.6/sapi/fpm
# cp php-fpm.service /etc/systemd/system/php-fpm.service
# vi /etc/systemd/system/php-fpm.service
php-fpm.service
// ▼ 修正
PIDFile=/usr/local/php/var/run/php-fpm.pid
ExecStart=/usr/local/php/sbin/php-fpm --nodaemonize --fpm-config /usr/local/php/etc/php-fpm.conf
// ▼ コメントアウト
#ProtectSystem=full
# systemctl daemon-reload
# systemctl enable php-fpm
# systemctl restart php-fpm
Nginx を PHP-FPM に接続する
# vi /etc/nginx/nginx.conf
RHEL 8 系(CentOS 8, Oracle Linux 8)ではない場合、ファイルパスは /etc/nginx/conf.d/default.conf である場合があります。
nginx.conf
http {
# ~ 略 ~
# ▼ 追記する
upstream backend {
ip_hash;
server localhost:9000;
keepalive 100;
}
server {
# ~ 略 ~
# ▼ 編集する
location / {
root /usr/share/nginx/index/html;
index index.html index.htm;
}
# ▼ 追記する
location ~ \.php$ {
fastcgi_pass backend; # upstream
proxy_set_header Host $http_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;
proxy_set_header X-NginX-Proxy true;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
proxy_redirect off;
fastcgi_intercept_errors on;
fastcgi_read_timeout 260;
fastcgi_send_timeout 260;
proxy_send_timeout 260;
proxy_read_timeout 260;
proxy_connect_timeout 260;
}
}
}
Firewall に穴をあける
# firewall-cmd --zone=public --permanent --add-port=80/tcp
# firewall-cmd --zone=public --permanent --add-port=443/tcp
# firewall-cmd --reload
- OCI の場合、VCN(仮想クラウドネットワーク)のセキュリティルールにも下記を追加すること
- TCP 80番
- TCP 443番
SELinux で許可する
# setsebool -P httpd_can_network_connect 1
# chcon -R -h -t httpd_sys_script_rw_t /usr/share/nginx/html/
動作テスト
- "nginx -t" は config ファイルのテストをするコマンド
- successful と表示されなければ随時修正すること
# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# systemctl enable --now nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.
- ファイルを作って実際にアクセス
# vi /usr/share/nginx/html/index.php
index.php
<?php
phpinfo();
グローバルIPアドレス/index.php にアクセスしてみて PHP INFO が表示されれば完了。
おまけ
MySQL
インストール
# dnf -y install mysql-server mysql mysql-devel
# systemctl enable --now mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
# vi /usr/lib/systemd/system/mysqld.service
mysqld.service
LimitNOFILE = 65535 // 修正
PHP.ini に mysql.sock のパスを書く
# vi /etc/php.ini
php.ini
[Pdo_mysql]
; Default socket name for local MySQL connects. If empty, uses the built-in
; MySQL defaults.
pdo_mysql.default_socket=/var/lib/mysql/mysql.sock
SELinux を修正
- .teファイルを作成する
- .teファイルから.modファイルを作成する
- .modファイルからバイナリの.ppファイルを作成する
- .ppファイルをsemoduleに読み込ませてSELinuxのポリシーに追加する
# vi mysql_selinux_allow.te
mysql_selinux_allow.te
module mysql_selinux_allow 1.0;
require {
type mysqld_t;
type mysqld_tmp_t;
type tmp_t;
type init_t;
class sock_file create;
class file unlink;
}
#============= init_t ==============
allow init_t mysqld_tmp_t:file unlink;
#============= mysqld_t ==============
allow mysqld_t tmp_t:sock_file create;
# checkmodule -M -m -o mysql_selinux_allow.mod mysql_selinux_allow.te
# semodule_package -o mysql_selinux_allow.pp -m mysql_selinux_allow.mod
# semodule -i mysql_selinux_allow.pp
# setsebool -P httpd_can_network_connect 1
# setsebool -P httpd_can_network_connect_db 1
UDS のためにソケットディレクトリを自動生成させる
vi /usr/lib/tmpfiles.d/php-fpm.conf
php-fpm.conf
d /run/php-fpm 0755 root root -
変更履歴
2021-11-10 初稿
2021-11-12 nginx-passenger.te を UDS 対応のものへ差し替え
2021-10-19 mysql.sock のパスを変更する旨を追記
2022-05-16 php 8.1.6 に書き換え、その他