systemd 五分钟上手:把 Python 脚本变成常驻服务
很多人写完一个 Python 脚本(监控采集、定时同步、Web 服务)后,都会遇到同一个问题:SSH 一断,进程就没了。于是有人用 nohup,有人用 screen、tmux,但这些都只是"临时续命"。在 Linux 服务器上,更正规的答案是 systemd——它本来就是大多数现代发行版的初始化系统,用它把脚本注册成服务,能免费获得崩溃自动重启、开机自启和统一日志管理。这篇文章用五分钟带你走完整个流程。
第一步:写一个最小 Unit 文件
假设脚本在 /opt/myapp/main.py,虚拟环境在 /opt/myapp/.venv。新建 /etc/systemd/system/myapp.service:
[Unit]
Description=My Python Worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/.venv/bin/python main.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
几个关键点:After=network-online.target 保证网络就绪后再启动,适合需要访问外部 API 的脚本;Restart=on-failure 表示异常退出时自动拉起,RestartSec=5 避免 crash loop 疯狂重启。注意 ExecStart 必须写绝对路径,systemd 不会继承你的 shell 环境。
第二步:让配置生效
sudo systemctl daemon-reload # 修改 unit 文件后必须执行
sudo systemctl enable --now myapp
enable --now 一条命令完成"设置开机自启 + 立即启动"。查看状态用 systemctl status myapp,绿色的 active (running) 就说明成功了。
第三步:看日志
systemd 默认把 stdout/stderr 收进 journald,不用再自己写日志文件:
journalctl -u myapp -f # 实时跟踪
journalctl -u myapp --since "1 hour ago"
排查"为什么我的服务起不来",九成的情况 journalctl 里就有答案——比如 Python 路径写错、权限不足。如果想限制日志占用磁盘,可以配置 SystemMaxUse 或直接写文件:在 [Service] 里加 StandardOutput=append:/var/log/myapp/out.log。
常见踩坑
- 改了 unit 文件没生效:忘了
daemon-reload,这是新手出现频率最高的错误。 - 环境变量丢失:cron 和 systemd 都不会加载
~/.bashrc。需要的话在 unit 里写Environment="KEY=value",或用EnvironmentFile=/etc/myapp.env。 - 权限问题:生产环境别用 root 跑,加上
User=appuser更安全;涉及 80/443 端口的可以用AmbientCapabilities=CAP_NET_BIND_SERVICE。 - 定时任务别硬套 service:如果只是想每天凌晨跑一次,用 systemd timer 或
crontab更合适,Type=oneshot的 service 配OnCalendar即可。
小结
把脚本交给 systemd 管理,换来的是:进程不再随会话消失、崩溃五秒内自动恢复、重启后自动上线、日志集中可查。整套配置只有一个几十行的 ini 文件,却解决了 nohup 方案的所有痛点。下一次部署常驻脚本时,不妨先写 myapp.service 再说。
- 点赞
- 收藏
- 关注作者
评论(0)