[Linux] 建立自訂 Systemd 服務教學與範例(Python)

Linux 建立自訂 Systemd 服務教學與範例

部屬方式

本次範例程式使用FastAPI,
檔名為main.py

import platform
import os
os_type = platform.system()
if os_type == 'Linux':
    # print('in Linux')
    os.chdir('/home/ubuntu/Dev')
import sys
sys.path.append("/home/ubuntu/.local/lib/python3.8/site-packages")
from fastapi import FastAPI
import uvicorn


app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

if __name__ == "__main__":
    uvicorn.run("main:app", host='0.0.0.0', port=8080, workers=1, reload=True)

Linux 建立自訂 Systemd 服務教學與範例

  1. 到/etc建立或rc.local並輸入下列內容(如果沒有的話自行建立)
  • 更改檔案路徑
  • python執行檔路徑, 有些是/bin/python, 請自行更改(若想包成docker就寫執行docker容器的指令)
#!/bin/sh -e

cd /home/ubuntu/Dev/myPython

/usr/bin/python3 main.py

exit 0

確定輸入的python路徑正確, 使程式正常運行:

$ /usr/bin/python3 data_collector_main.py

然後將執行權限添加到 /etc/rc.local 文件。

$ sudo chmod +x /etc/rc.local
  1. 到/etc/systemd/system建立rc-local.service服務
$ nano /etc/systemd/system/rc-local.service

如果是依照rc.local則直接複製下方內容,無須修正
(有修改過rc.local檔名的話, 請自行將下方的4處修改為自己的檔名, 分別為下方的1,4,9,17行)

[Unit]
Description=/etc/rc.local Compatibility
Documentation=man:systemd-rc-local-generator(8)
ConditionFileIsExecutable=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
Environment="DJANGO_SETTINGS_MODULE=Macdonald_Server.settings.production"
TimeoutSec=0
RemainAfterExit=yes
GuessMainPID=no

[Install]
WantedBy=multi-user.target
Alias=rc-local.service
  1. python的庫位置
$ pip3 show fastapi
  1. 添加PATH, 路徑請自行更改
$ export PATH=$PATH:/home/nadi_19/.local/lib/python3.6/site-packages
  1. 開啟執行權限
$ chmod +x /home/nadi_19/NADI/ShowCase/server_ms_showcase/data_collector/data_collector_main.py
  1. 重新載入 Systemd 設定檔
$ sudo systemctl daemon-reload
  1. 啟動自訂的 echo 伺服器
$ sudo systemctl start rc-local.service
  1. 查看 echo 伺服器狀態
$ sudo systemctl status rc-local.service

成功啟動訊息如下:

root@ShowCase19-1:/home/nadi_19/NADI/ShowCase/server_ms_showcase/data_collector# systemctl status rc-local
● rc-local.service - /etc/rc.local Compatibility
   Loaded: loaded (/etc/systemd/system/rc-local.service; enabled; vendor preset: enabled)
  Drop-In: /lib/systemd/system/rc-local.service.d
           └─debian.conf
   Active: active (exited) since Wed 2022-07-20 11:15:40 UTC; 1min 27s ago
     Docs: man:systemd-rc-local-generator(8)
  Process: 31493 ExecStart=/etc/rc.local start (code=exited, status=0/SUCCESS)
  1. 使服務能夠在啟動時自動啟動
$ sudo systemctl enable rc-local.service

輸入完後重新開機, 測試看看是否service都有自己run起來!

  1. 指令補充

下方的service-name都是指rc-local.service這隻檔案。

  • 檢視服務的當前狀態
    無論它是否正在執行,都可以在終端中使用以下命令語法:
$ systemctl status [service-name]
  • 啟動服務,請使用以下語法
$ systemctl start [service-name]
  • 停止正在執行的服務
$ systemctl stop [service-name]
  • 使服務能夠在機器啟動時自動啟動
$ systemctl enable [service-name]
  • 禁用服務,使其無法在啟動時自動啟動:
$ systemctl disable [service-name]
  • 重新載入服務
$ systemctl reload [service-name]
  • 重新載入
    或重新啟動服務(它重新載入服務,並且如果重新載入不可用,那麼它將重新啟動服務。)
$ sudo systemctl reload-or-restart [service-name]
  • 檢查服務是否啟用
$ sudo systemctl is-active [service-name]

服務正常並啟用則返回:activating

  • 檢查是否已啟用服務以在系統啟動時自動啟動
$ sudo systemctl is-enabled [service-name]

啟用則返回:enabled

補充

  1. 若是出現Condition check resulted in /etc/rc.local Compatibility being skipped.

將執行權限添加到 /etc/rc.local 文件。

$ sudo chmod +x /etc/rc.local
  1. 找不到xxx.local檔案
    如果在確認etc是否有xxx.local,如果沒有的話請將自己補上, 或是.service檔案內的xx.local檔名打錯了。
  2. 執行多個service
    目前是建立多個xx.local和xx-local.service,
    未來若有更好的方式, 我會來修正現在的方式(如果我有記得的話)

發佈留言