用 systemd 托管 Python 脚本:从手动运行到开机自启
很多人写完一个 Python 小服务(比如定时抓数据、一个 Flask 接口),第一反应是在终端里 nohup python app.py &。能跑,但问题不少:进程挂了没人拉起,服务器重启后要手动再开,日志散落在 nohup.out 里不好查。其实 Linux 自带的 systemd 就能把这些事一次解决。
一、准备脚本
假设脚本放在 /opt/demo/app.py,用虚拟环境 /opt/demo/venv。先手动跑一遍确认没问题:
/opt/demo/venv/bin/python /opt/demo/app.py
二、编写 unit 文件
新建 /etc/systemd/system/demo.service:
[Unit]
Description=Demo Python Service
After=network.target
[Service]
User=www-data
WorkingDirectory=/opt/demo
ExecStart=/opt/demo/venv/bin/python app.py
Restart=on-failure
RestartSec=5
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.target
几个关键点:User 不要用 root,降低风险;Restart=on-failure 让进程异常退出后 5 秒自动重启;PYTHONUNBUFFERED=1 让 print 的内容实时进入日志,否则可能因为缓冲迟迟看不到输出。
三、启用与管理
sudo systemctl daemon-reload
sudo systemctl enable --now demo
systemctl status demo
enable 负责开机自启,--now 表示立刻启动。之后停止、重启分别是 systemctl stop demo 和 systemctl restart demo。
四、看日志
systemd 会把标准输出收进 journald:
journalctl -u demo -f
加 -f 实时跟踪,加 --since "1 hour ago" 只看最近一小时,排查问题比翻 nohup.out 方便得多。
五、常见坑
1. 路径一律写绝对路径,systemd 不会读取你 shell 里的 PATH。
2. 修改 unit 文件后必须 daemon-reload,否则改动不生效。
3. 如果脚本需要读 .env,可以用 EnvironmentFile=/opt/demo/.env,比把密钥写进 unit 文件更安全。
4. 权限报错时先检查 User 对 WorkingDirectory 是否有读写权限。
小结:几行配置,就让一个"随手跑"的脚本变成有自动重启、开机自启、集中日志的正式服务。下次部署小工具时,不妨直接从写一个 .service 文件开始。
- 点赞
- 收藏
- 关注作者
评论(0)