FrankenPHP を Debian 12 bookworm にインストール
この記事はインフラ初心者が纏めているため、あまり信用しないでください。この記事を参考にセットアップしたことによって被った損害・損失に対し、いかなる場合でも一切の責任を負いませんのでご了承ください。あくまでも自己責任でお願いします🙇♂️
本記事では、Debian のインストールと設定は完了しているものとする。最終的に目指す構成は以下の通り。
- OS: Debian 12 bookworm
- web サーバー + PHP: FrankenPHP (Caddy + PHP8.3) - 本記事
- データベース: MariaDB
ファイアウォールの設定
80番ポートと443番ポートを開放する。
$ ufw limit 'WWW Full' && sudo ufw reload && sudo ufw status
Rule added
Rule added (v6)
Status: active
To Action From
-- ------ ----
SSH LIMIT Anywhere
WWW Full LIMIT Anywhere
SSH (v6) LIMIT Anywhere (v6)
WWW Full (v6) LIMIT Anywhere (v6)
ステータスが active で、WWW Full がリストにあれば完了。
一度追加したルールを削除する
追加した削除したルールを削除する場合は、以下のコマンドを実行する。
$ sudo ufw delete limit SSH && sudo ufw reload
個別に削除する場合は
$ ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] SSH LIMIT IN Anywhere
[ 2] SSH (v6) LIMIT IN Anywhere (v6)
上記で表示された番号を指定する。
$ ufw delete 2 && sudo ufw reload
FrankenPHP をインストール
一般的に web サイト公開環境といえば、Nginx + PHP-FPM が多いと思います。しかし、環境構築とメンテナンスのハードルが高いので、FrankenPHP に期待している。
インストールする場所へ Path を通す
/usr/local/sbin
への Path を通す。
$ vi ~/.bashrc
下記を追記。
+ export PATH=/usr/local/sbin:$PATH
変更内容を反映させる。
$ source ~/.bashrc
バイナリーを Github からダウンロードして配置
$ wget https://github.com/dunglas/frankenphp/releases/download/v1.2.2/frankenphp-linux-x86_64 && \
sudo mv ~/frankenphp-linux-x86_64 /usr/local/sbin/frankenphp && \
sudo chmod +x /usr/local/sbin/frankenphp && \
/usr/local/sbin/frankenphp -v
FrankenPHP の設定
ここからの作業は Nginx や Apache と同じような一般的な作業。
ユーザーの設定を変更
FrankenPHP 用のユーザーを作成し www-data グループに所属させる。
※ 下記の例では作業用ユーザー debian も一緒に www-data グループに所属させている。
$ sudo useradd -mU -s /usr/sbin/nologin -d /opt/caddy caddy && \
sudo usermod -aG www-data caddy && \
sudo usermod -aG www-data debian
公開ディレクトリを作成
web サイト公開ディレクトリの権限を変更し、www-data グループに所属していれば追加・更新・削除を行えるようにする。
$ sudo mkdir /var/www && \
sudo chown -R caddy:www-data /var/www && \
sudo chmod -R 2775 /var/www && \
sudo find /var/www -type d -exec sudo chmod 2775 {} \; && \
sudo find /var/www -type f -exec sudo chmod 2664 {} \; && \
exit
サーバーからログアウトしているはずなので、再度ログインする。
Caddyfile を設定
FrankenPHP の web サーバーは Go 言語で書かれた Caddy が使用されている。設定ファイルの書き方は Caddy と同じ。
$ sudo vi /etc/caddy/Caddyfile
(encode) {
encode zstd br gzip
php_server
}
(header-cache-control) {
@static {
file
path *.css *.js *.jpeg *.jpg *.png *.gif *.webp *.avif *.svg *.eot *.ttf *.woff *.woff2
}
header @static Cache-Control "public, max-age=691200"
}
(header-security) {
header Referrer-Policy no-referrer-when-downgrade
header X-Content-Type-Options nosniff
header X-Download-Options noopen
header X-Frame-Options SAMEORIGIN
header X-XSS-Protection "1; mode=block"
}
(header-cors) {
@origin header Origin {args[0]}
header @origin Access-Control-Allow-Origin "{args[0]}"
header @origin Access-Control-Allow-Methods "GET,POST,PUT,DELETE,OPTIONS"
}
(header-https) {
header Content-Security-Policy "default-src https: data: 'unsafe-eval' 'unsafe-inline';"
header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
header X-SSL-Status https
}
(createlog) {
log {
hostnames {args[0]}
output file /opt/caddy/log/access-{args[0]}.log {
roll_size 1gb
roll_keep 5
roll_keep_for 7d
}
output file /opt/caddy/log/error-{args[0]}.log {
level ERROR
roll_size 1gb
roll_keep 5
roll_keep_for 7d
}
}
}
{
frankenphp
order php_server before file_server
http_port 80
https_port 443
auto_https disable_redirects
}
http:// {
root * /var/www/exmaple.com/public
import header-cache-control
import header-security
import header-cors 192.168.10.20
import encode
}
exmaple.com:80,
exmaple.com:443 {
redir https://www.exmaple.com{uri} permanent
import header-cache-control
import header-security
import header-cors exmaple.com
import encode
}
www.exmaple.com:80,
www.exmaple.com:443 {
root * /var/www/exmaple.com/public
import header-cache-control
import header-security
import header-cors www.exmaple.com
import header-https
import encode
import createlog www.exmaple.com
}
FrankenPHP をサービスに登録
$ sudo vi /etc/systemd/system/frankenphp.service
以下をペースト。
# frankenphp.service
#
# For using Caddy with a config file.
#
# Make sure the ExecStart and ExecReload commands are correct
# for your installation.
#
# See https://caddyserver.com/docs/install for instructions.
#
# WARNING: This service does not use the --resume flag, so if you
# use the API to make changes, they will be overwritten by the
# Caddyfile next time the service is restarted. If you intend to
# use Caddy's API to configure it, add the --resume flag to the
# `caddy run` command or use the caddy-api.service file instead.
[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target
[Service]
Type=notify
User=caddy
Group=www-data
ExecStart=/usr/local/sbin/frankenphp run --environ --config /etc/caddy/Caddyfile
ExecReload=/bin/kill -USR1 $MAINPID
ExecStop=/usr/local/sbin/frankenphp stop
Restart=on-failure
RestartSec=5s
TimeoutStopSec=5s
LimitNOFILE=65536
LimitNPROC=64
PrivateTmp=true
PrivateDevices=true
ProtectSystem=full
ReadWriteDirectories=/opt/caddy
Environment=CADDYPATH=/opt/caddy
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
FrankenPHP をサービスに登録。
$ sudo systemctl enable frankenphp && \
sudo systemctl start frankenphp && \
sudo systemctl status frankenphp
これで web サイトが公開されているはず。
PHP.ini を作成
自身で FrankenPHP のバイナリをビルドした場合を除き、php.ini の設置場所は /lib
以下になっている。FrankenPHP 側で php.ini は準備されていないから自前で用意。
$ sudo vi /lib/php.ini
/run/mysqld/mysqld.sock
の箇所は環境に合わせて変更。
MariaDB の場合は /etc/mysql/mariadb.cnf
で確認できる。
[PHP]
engine = On
short_open_tag = Off
precision = 14
output_buffering = 4096
implicit_flush = Off
serialize_precision = -1
zend.enable_gc = On
expose_php = Off
max_execution_time = 30
max_input_time = 60
memory_limit = 128M
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
error_log = /var/log/php_errors.log
display_errors = Off
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = On
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = Off
request_order = "GP"
auto_globals_jit = On
post_max_size = 4M
upload_max_filesize = 4M
max_file_uploads = 20
default_mimetype = "text/html"
file_uploads = On
allow_url_fopen = Off
default_socket_timeout = 60
open_basedir = /var/www
[Date]
date.timezone = "Asia/Tokyo"
[mbstring]
mbstring.language = Japanese
mbstring.detect_order = ASCII,ISO-2022-JP,UTF-8,eucJP-win,SJIS-win
mbstring.encoding_translation = Off
mbstring.substitute_character = none
mbstring.func_overload = 0
[mail function]
SMTP = localhost
smtp_port = 25
sendmail_path = /usr/sbin/sendmail -t -i
mail.add_x_header = On
[Session]
session.save_handler = files
session.save_path = "/tmp/php/session"
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.cookie_lifetime = 0
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 1
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5
[Pdo_mysql]
pdo_mysql.default_socket = /run/mysqld/mysqld.sock
[MySQLi]
mysqli.default_socket = /run/mysqld/mysqld.sock
[OPcache]
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8M
opcache.max_accelerated_files=4000
opcache.revalidate_freq=0
opcache.fast_shutdown=1
[apcu]
apc.enabled=1
apc.enable_cli=1
apc.shm_size=64M
apc.ttl=3600
apc.gc_ttl=3600
apc.user_ttl=7200
apc.cache_by_default=1
apc.filters=.*\.php
apc.stat=1
apc.serializer=php
apc.use_request_time=1
apc.include_once_override=0
[Memcached]
;extension=memcached.so
Discussion