Service with Systemd

問題描述

最近在研究如何使用 Systemd 來管理服務,這邊紀錄一下。公司的 CI/CD 環境是由 GitHub Actions + Drone CI 腳本來管理,因此需要在 Drone CI 腳本中執行 Systemd 指令來啟動服務。其中有兩個服務出了問題, Faye 啟動了但無法使用,而 Sidekiq 則是無法啟動。
在經過一些測試以後發現,Faye 啟動後無法使用的問題是因為沒有設定 --port 參數,而 Sidekiq 啟動失敗的問題是因為 rvm 版本的問題。而這些都與設定 Systemd 的 service file 有關。

解決方法

  1. Faye 啟動後無法使用的問題是因為沒有設定 --port 參數,因此需要在 service file 中設定 ExecStart 的參數。

    1
    $ sudo vim /etc/systemd/system/faye.service
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [Unit]
    Description=Faye
    After=network.target

    [Service]
    Type=simple
    User=deploy
    WorkingDirectory=/home/deploy/apps/faye/current
    ExecStart=/home/deploy/.rvm/bin/rvm default do bundle exec faye --port 9292
    Restart=always
    RestartSec=10

    [Install]
    WantedBy=multi-user.target

    另一種做法,也就是我們公司的做法,是透過 puma 來執行 Faye ,因此是透過 faye.rb 來啟動 Faye。

    1
    ExecStart=/home/deploy/.rvm/bin/rvm default do bundle exec puma -C /home/deploy/<app_path>/faye.rb

    所以我們可以透過 faye.rb 來設定 faye 的 port ,在檔案中加入以下內容:

    1
    port 9292

    設定好以後重新載入 Systemd 並啟動服務:

    1
    2
    $ sudo systemctl daemon-reload
    $ sudo systemctl start faye
  2. Sidekiq 啟動失敗的問題是因為 rvm 版本的問題,因此需要在 service file 中檢查'ExecStart , WorkingDirectory 與設定 Environment 的參數。

    1
    $ sudo vim /etc/systemd/system/sidekiq.service
    1
    2
    3
    4
    5
    WorkingDirectory=/home/deploy/app/current

    ExecStart=/home/deploy/.rvm/gems/ruby-2.6.10/wrappers/bundle exec sidekiq -e production

    Environment=PATH=/home/deploy/.rvm/gems/ruby-2.6.10/bin:/home/deploy/.rvm/gems/ruby-2.6.10@global/bin:/home/deploy/.rvm/rubies/ruby-2.6.10/bin:/home/deploy/.rvm/bin:/home/deploy/.nvm/versions/node/v16.14.2/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/deploy/.local/bin:/home/deploy/bin

    設定好以後重新載入 Systemd 並啟動服務:

    1
    2
    $ sudo systemctl daemon-reload
    $ sudo systemctl start sidekiq
  3. 透過 Systemd 來管理服務,可以透過 systemctl 指令來查看服務的狀態,例如:

    1
    2
    $ sudo systemctl status faye
    $ sudo systemctl status sidekiq

    也可以透過 journalctl 指令來查看服務的 log ,例如:

    1
    2
    $ sudo journalctl -u faye
    $ sudo journalctl -u sidekiq

    也可以透過 systemctl 指令來啟動、停止、重啟服務,這邊就不贅述了。

參考資料

由於 CI/CD 有時候會需要使用 sudo 指令,因此需要在 /etc/sudoers 中設定 deploy 使用者可以使用 sudo 指令,例如:

1
deploy ALL=(ALL) NOPASSWD:ALL

或是透過 visudo 指令來設定:

1
$ sudo visudo
1
2
3
deploy ALL=(ALL) NOPASSWD:ALL
# 嚴謹一點的話可以這樣設定,只列出需要使用 sudo 指令的指令
deploy ALL=NOPASSWD: /usr/bin/systemctl start faye