はじめに
複数のサービスを自作してsystemdで管理するときに、作成するユニットファイルの中身が大体同じということがある。
こういう場合はユニットファイルのテンプレート化が有効なので、そのやり方をメモしておく。
動作確認は簡単にしたいので、ここではWebサーバのポート番号を変数化したユニットファイルを作成することにした。
環境
$ cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Ubuntu 18.04.4 LTS"
$ python3 --version
Python 3.6.9
事前準備
いろいろWebサーバを探してみたものの、ポート番号を引数に渡して起動できる手頃なWebサーバが見当たらなかったので、自前で作成することにした。
まずは、以下の内容で/opt/test-web-server/test-web-server.py
を作成する。
from sys import argv
from http.server import BaseHTTPRequestHandler
from http.server import HTTPServer
class ServerAddressHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'text/plain')
self.end_headers()
text = 'server_address = ' + str(self.server.server_address) + '\r\n'
self.wfile.write(text.encode('utf-8'))
if __name__ == '__main__':
port = int(argv[1])
httpd = HTTPServer(('0.0.0.0', port), ServerAddressHandler)
httpd.serve_forever()
このファイルに実行権限をつけておく。
$ chmod a+x /opt/test-web-server/test-web-server.py
動作確認のために、待受ポートの10080
を引数に指定して、このWebサーバを起動する。
$ /opt/test-web-server/test-web-server.py 10080
別のターミナルからcurl
でWebサーバにアクセスすると、待ち受けているIPアドレスとポート番号を取得できる。
$ curl http://localhost:10080
server_address = ('0.0.0.0', 10080)
これで事前準備は完了。
起動したWebサーバを停止しておく。
ユニットファイルの作成と、ひとつめのサービスの登録
次の内容でファイル/etc/systemd/system/test-web-server@.service
を作成する。
[Unit]
Description=Test Web Server with port %i
[Service]
Type=simple
ExecStart=/opt/test-web-server/test-web-server.py %i
[Install]
WantedBy=multi-user.target
具体化されたサービスの作成方法は、コマンドラインを見た方が分かりやすい。
例えば、ポート番号10080
で待ち受けるサービスを登録するには以下のようにする。
$ sudo systemctl enable --now test-web-server@10080
Created symlink /etc/systemd/system/multi-user.target.wants/test-web-server@10080.service → /etc/systemd/system/test-web-server@.service.
つまり、ユニットファイルのファイル名、すなわちサービス名の@
以降が変数%i
に割り当てられる。
ここで登録したサービスの状態を確認するには、同様にサービス名の@
以降に10080
を指定してsystemctl status
を実行すればよい。
$ systemctl status test-web-server@10080
● test-web-server@10080.service - Test Web Server with port 10080
Loaded: loaded (/etc/systemd/system/test-web-server@.service; indirect; vendor preset: enabled)
Active: active (running) since Sat 2020-02-08 17:29:13 JST; 5min ago
Main PID: 4632 (python3)
Tasks: 1 (limit: 4637)
CGroup: /system.slice/system-test\x2dweb\x2dserver.slice/test-web-server@10080.service
└─4632 python3 /opt/test-web-server/test-web-server.py 10080
2月 08 17:29:13 ubuntu1804 systemd[1]: Started Test Web Server with port 10080.
想定通り%i
が10080
に置き換わっていることが分かる。
では、curl
を実行してWebサーバの動作確認をしてみる。
$ curl http://localhost:10080
server_address = ('0.0.0.0', 10080)
事前準備の時と同様に、待ち受けているIPアドレスとポート番号が正しく表示された。
ふたつめのサービスの登録
次はポート番号20080
で待ち受ける、ふたつめのサービスを登録してみる。
$ sudo systemctl enable --now test-web-server@20080
Created symlink /etc/systemd/system/multi-user.target.wants/test-web-server@20080.service → /etc/systemd/system/test-web-server@.service.
確認のため、名前がtest-web-server@
から始まるサービスをリストする。
$ systemctl list-units -t service 'test-web-server@*'
UNIT LOAD ACTIVE SUB DESCRIPTION
test-web-server@10080.service loaded active running Test Web Server with port 10080
test-web-server@20080.service loaded active running Test Web Server with port 20080
(以下略)
想定通り、ポート番号が10080
のサービスと20080
のサービスが表示されている。
では、curl
を実行してWebサーバの動作確認をしてみる。
$ curl http://localhost:10080
server_address = ('0.0.0.0', 10080)
$ curl http://localhost:20080
server_address = ('0.0.0.0', 20080)
ポート番号が10080
のWebサーバも、20080
のWebサーバも正しく動作していることが分かる。
参考
man sytstemd.service
man systemd.unit