はじめに
複数のサービスを自作して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
を作成する。
#!/usr/bin/env python3 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