PlantUML サーバーの Docker コンテナをオンデマンドで起動する
tl;dr
- VSCode の PlantUML 拡張は便利だがデフォルトでは遅い (JVM 起動や各種 class ファイルのロードに時間がかかる?)
- PlantUML サーバーをローカルで起動することで高速化可能
- PlantUML のようなたまにしか使わないサービスを常時起動させておくのはなんとなく嫌
- 本記事では特定のポートにアクセスがあった時点で PlantUML を起動するための設定方法を記す
使うもの
- systemd
- docker
手順1: PlantUML Docker サービスを systemd サービス化する
systemctl
コマンドで PlantUML サーバーを起動できるようにします。
以下では TCP 51000番ポートを PlantUML サーバーへ割り当てます。
# unit ファイルの作成 $ sudo -E systemctl edit --force --full docker-plantuml.service
エディタが開くので以下を入力。
[Unit] Description=PlantUML Server Container After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 Restart=always ExecStartPre=-/usr/bin/docker stop %n ExecStartPre=-/usr/bin/docker rm %n ExecStartPre=/usr/bin/docker pull plantuml/plantuml-server ExecStart=/usr/bin/docker run --rm --name %n -p 51000:8080 plantuml/plantuml-server ExecStartPost=/usr/bin/wget --quiet --method HEAD --waitretry 0.1 --tries 600 --retry-connrefused http://localhost:51000 [Install] WantedBy=multi-user.target
参考にしたサイト では nc -z $host $port
でサービス起動を待ち合わせていましたが、 PlantUML サーバーの場合は TCPポートへ connect(2)
できるようになってから (コンテナが起動してから?) HTTP サーバーが応答を返せるようになるまで10秒弱程度のタイムラグがあるようなので、 wget(1)
でポーリングするようにしています。
手順2: ソケット接続時に docker-plantuml
サービスを起動する
systemd には socket activation という特定のポートへの接続があった時にサービスを起動するような仕組みがあります。 この仕組みを使うためにはは、起動されるサービス側が socket activateion に対応している必要があり、 残念ながら Docker は対応していません。
socket activation に対応したプロキシである systemd-socket-proxyd
を利用し、
特定のポートへの接続と Docker の listen(2)
しているポートへの接続を仲介することで、
特定の TCP ポートに接続があった時に Docker コンテナを起動させることができます。
以下では、 TCP 50000 番ポートへ connect(2)
された場合に、 PlantUML のサービス (TCP 510000番) へ転送するように設定しています。
$ sudo -E systemctl edit --force --full docker-plantuml-proxy.socket
エディタが開くので以下を入力。
[Socket] ListenStream=50000 [Install] WantedBy=sockets.target
$ sudo -E systemctl edit --force --full docker-plantuml-proxy.service
エディタが開くので以下を入力。
[Unit] Requires=docker-plantuml.service After=docker-plantuml.service [Service] ExecStart=/usr/lib/systemd/systemd-socket-proxyd 127.0.0.1:51000
最後に、 docker-plantuml-proxy.socket
を有効化 & 起動してください。
$ sudo systemctl enable docker-plantuml-proxy.socket $ sudo systemctl start docker-plantuml-proxy.socket
手順3: VSCode の設定
以下のように設定すればOK!
{ "plantuml.render": "PlantUMLServer", "plantuml.server": "http://localhost:50000/" }
手順4: 動作確認
VSCode で PlantUML ファイルを開きプレビューすると、 PlantUML サーバーが起動してレンダリングされるはずです。