PHPにはビルトインウェブサーバが付属していますので、WEB用のPHPスクリプトをちょっとテストするのに便利です。ただ、ある程度継続して使い続けるためには、サービスとして登録する必要があります。そんな時にどうするかという話です。
想定環境
- PHPのWebアプリのテスト、ローカルポータルサイトの構築などの目的
- LAN内のLinuxサーバ、またはLinuxPC上に設置(グローバルに公開しない)
ローカルにかつ一時的に利用することを想定しています。恒常的なサービスにする場合は記事末を見てください。
手順
- .serviceファイルを用意する
- .serviceファイルを/lib/sysem/systemdにコピーする
- サービスを有効化する
- サービスを起動する
.serviceファイルは、ウェブサーバで起動するPHPスクリプトとペアにして、同じディレクトリ内に置いておくと管理のために便利です。
.serviceファイル
.serviceファイルはリスト2のように記述します。「{ }」内には具体的な値が入ります。なお、筆者はDebianを使っていますので、サービスの実行ユーザをwww-dataにしています(お使いのOSの習慣に従って、適宜変更してください)。
[Unit]
Description = {Description}
[Service]
ExecStart = /usr/bin/php -S {HOSTNAME}:{PORT} {SCRIPTPATH}
User = www-data
Group = www-data
[Install]
WantedBy = default.target
{HOSTNAME}
ウェブサーバをPC上で起動する場合は
localhost あるいは 127.0.0.1
にしてください。これにより、LAN内であっても他のホストからのアクセスができません。LAN内の別ホスト上で起動する場合は
プライベートアドレス あるいは そのアドレスを指すローカルホスト名
にします。
{PORT}
Webサービスであることを明示的に示すためには、ポートは
8080 〜 8089
を使うのが良いでしょう。他のサービスと重複しなければ何でも良いのですが、特権ポート(1023以下)は避けた方が無難です。
{SCRIPTPATH}
ビルトインウェブサーバにより起動されるPHPスクリプト名です。必ずフルパスで指定してください。
{DESCRIPTION}
「systemctl status」コマンド等の結果として表示されるサービスの名前です。.serviceファイルのベース名(拡張子を取り除いた部分)を使うのが無難でしょう。
サービスの登録と起動
筆者はリスト2のようなスクリプトを使っています。「register-service」と名付けてパスの通っている場所に保存しています。このスクリプトは、.serviceファイルが置かれたディレクトリをカレントにしないと実行できないようになっています。これは、あくまでも一時的なサービスであることを強調するためです。
01: #!/usr/bin/env bash
02: NAME=$1
03: # 第1引数でサービスの名前を定義する
04: if [ "${NAME}" == "" ]; then
05: echo "Service name required."
06: exit 1
07: fi
08: NAME=${NAME%.service}
09: SNAME=${NAME}.service
10: # カレントディレクトリに定義ファイルが存在するか
11: if [ ! -f "${SNAME}" ]; then
12: echo "${SNAME} not found."
13: exit 1
14: fi
15: LDIR=/lib/systemd/system
16: # 同じ名前のserviceが存在するか
17: if [ -e ${LDIR}/${SNAME} ]; then
18: echo "Service ${NAME} already exists."
19: exit 1
20: fi
21: # .serviceファイルをコピーする
22: sudo cp ${PWD}/${SNAME} ${LDIR}/${SNAME}
23: # serviceを有効化する
24: sudo systemctl enable ${NAME}
25: # serviceを起動する
26: sudo systemctl start ${NAME}
例えば、「php8081.service」を登録する場合には、そのファイルの存在するディレクトリをカレントにして
$ register-service php8081
などと実行します。一般のサービスへできるだけ影響を与えないように、.serviceファイルの存在するディレクトリで実行します。
サービスの削除
一時的なサービスですので、いつかは削除します。その際、サービスをdisableする前に、stopしなければならないことに注意してください。サービスが起動中にdisableしてしまうと、ゾンビのようなサービスが残ってしまいます(リスト3)。
$ sudo systemctl status php8081
● php8081.service
Loaded: not-found (Reason: Unit php8081.service not found.)
Active: active (running) since Mon 2020-07-27 00:35:21 JST; 2min 49s ago
...
7月 27 00:36:36 chiimama systemd[1]: php8081.service: Current command vanished from the unit file,
execution of the command list won't be resumed.
筆者は、サービスを間違いなく削除するために、リスト4のスクリプトを利用しています。
14: (ここまでリスト2と同じ)
15: # serviceを停止する
16: sudo systemctl stop ${NAME}
17: # serviceを無効化する
18: sudo systemctl disable ${NAME}
19: # .serviceファイルを削除する
20: sudo rm ${LDIR}/${SNAME}