0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Node.js で作ったDiscord Bot を24時間動かす方法 — systemd で常駐させる

0
Posted at

Discord のボイスチャンネルに人が集まったら Slack に通知する Bot を作りました。

vc-mihari-img-preview (1).png

この記事では、その Bot を systemd で常駐させて24時間動かす方法を書きます。プログラムの詳細は GitHub に置いてあるので、よければ見てください。

GitHubのリンク

はじめに

node.jsはjavascriptの実行環境であり、これを使うことで簡単にプログラムを動作させることができます。しかし、ただnode ~.jsと実行するだけでは、そのターミナルを開いているときしか実行されません。
そこで、systemdを用いることで、24時間365日動かす方法を説明していきます。

他の候補との比較

代表的な3つを比べます。

方法 ログアウトで消えない 再起動で復活 クラッシュで復活 追加インストール
node bot.js のまま × × × 不要
Docker 要(Docker)
systemd 不要(標準搭載)

node bot.js をそのまま実行

一番素朴な方法です。プログラムを書いたら誰もが最初にやる動かし方ですが、ターミナルを閉じたり SSH を切ったりすると止まります。サーバーを再起動しても上がってこず、クラッシュしても復帰しません。常駐には向きません。

Docker

アプリを実行環境ごとコンテナに閉じ込めて動かす仕組みです。コンテナには実行に必要なものが全部入っているので、どのマシンに持っていっても同じように動きます。

ただし今回は、1台のサーバーで Bot を常駐させたいだけで、いろいろな環境に持ち運びたいわけではありません。Docker の一番の強みを使わないので、この用途ではあまり役には立たないでしょう。さらに、Docker 自体のインストールも必要になります。

systemd

今回使った方法です。Linux に最初から入っている仕組みなので追加インストールが要りません。ログアウトでも再起動でもクラッシュでも復帰し、ログも自動で集約されます。Linux サーバーで常駐 Bot を1個動かすなら、これが一番手軽だと思います。

具体例

systemd に常駐させたいプログラムを教えるには、「ユニットファイル」という設定ファイルを書きます。今回は次のような vc-mihari.service を用意しました。

[Unit]
Description=vc-mihari - Discord voice channel headcount to Slack
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/vc-mihari
ExecStart=/usr/bin/node --env-file=.env bot.js
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

各行が何をしているかを見ていきます。

[Unit] セクション(サービスの説明と起動順序)

  • Description= … サービスの説明。systemctl status などで表示される名前です。
  • After=network-online.target … ネットワークが使えるようになった後に起動する、という順序の指定です。この Bot は Discord に接続するので、ネットワークより先に起動すると失敗します。
  • Wants=network-online.target … ネットワークの準備を要求します。After= と組で使います。

[Service] セクション(何をどう動かすか)

  • Type=simple … 起動したプロセスがそのまま本体、という一番基本の型です。
  • User=your-user … このユーザーの権限でプロセスを動かします。
  • WorkingDirectory=/path/to/vc-mihari … このディレクトリに移動してからコマンドを実行します。--env-file=.env.env はここからの相対パスで探されます。
  • ExecStart= … 実際に実行するコマンドです。node を絶対パス(/usr/bin/node)で書いている点に注意してください。
  • Restart=always … プロセスが死んだら必ず再起動します。
  • RestartSec=10 … 再起動するまで10秒待ちます。

[Install] セクション(自動起動の設定)

  • WantedBy=multi-user.targetsystemctl enable したときに、通常のサーバー起動状態でこのサービスを有効にする、という指定です。これがあることで、サーバーを再起動しても自動で立ち上がります。

UserWorkingDirectoryExecStart のパスは自分の環境に合わせて書き換えてください。node のパスは which node で確認できます。

ここで説明したのは一部だけです。各項目にはもっと多くの選択肢があり、詳しくは man systemd.serviceman systemd.unit で読めます。

実行例

書いたユニットファイルを systemd に設置して、動かしていきます。

起動方法

ユニットファイルを systemd が読む場所(/etc/systemd/system/)にコピーします。

sudo cp vc-mihari.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now vc-mihari
  • cp … ユニットファイルを所定の場所に置きます。
  • daemon-reload … 新しく置いた(または変更した)ユニットファイルを systemd に読み直させます。これを忘れると変更が反映されません。
  • enable --now … サービスを有効化して、同時に起動します。enable は「サーバー起動時に自動で立ち上げる設定」、--now は「今すぐ起動する」という意味です。この2つは別で、start だと今回だけ起動、enable だけだと次回起動時から、になります。

確認方法

ちゃんと動いているかを確認します。

systemctl status vc-mihari
journalctl -u vc-mihari -f
  • systemctl status vc-mihari … サービスの状態を表示します。active (running) と緑色で出れば動いています。設定ミスなどで起動に失敗していると failed と赤字で表示されます。
  • journalctl -u vc-mihari -f … このサービスのログを表示します。-u でユニットを指定し、-f で新しいログが出るたびに追記表示します(tail -f と同じ動きです。Ctrl+C で抜けても、サービスは止まりません)。

ログについては後の「ログ」の節でもう少し詳しく触れます。

終了方法

止め方には2種類あります。

1つ目

sudo systemctl stop vc-mihari       # 今動いているプロセスを止める
  • stop … 今動いているサービスを止めます。ただしこれは一時停止で、サーバーを再起動すると自動で立ち上がってきます。

2つ目

sudo systemctl disable vc-mihari    # 自動起動をやめる
  • disable … 自動起動を無効にします。今動いているプロセスはそのままです。

完全に止めたいなら両方必要です。

まとめて行う disable --now もあります。

sudo systemctl disable --now vc-mihari

さらにサービス自体を消すなら、ユニットファイルを削除して読み直します。

sudo systemctl disable --now vc-mihari
sudo rm /etc/systemd/system/vc-mihari.service
sudo systemctl daemon-reload

まとめ

いかがでしたでしょうか。
.serviceの書き方やsystemctl関連のコマンドは覚えにくく、見るだけでもいまいちわかりにくいので、保存用としてこの記事を書きました。これを読んでくれた方のなんらかの助けになれば嬉しいです。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?