Linux系统部署Python项目持续运行配置
在 Linux 系统中,要让 Python 项目持续运行并在服务器重启后自动恢复,可以通过以下几种方法实现:
方法 1:使用 systemd
服务(推荐)
systemd
是 Linux 系统标准的服务管理工具,支持开机自启、进程监控、日志管理等功能。
步骤:
-
创建服务文件
新建一个服务配置文件(如myapp.service
)到/etc/systemd/system/
:sudo nano /etc/systemd/system/myapp.service
-
编写服务配置
添加以下内容(根据实际路径修改):[Unit] Description=My Python Application After=network.target [Service] User=your_username # 指定运行用户 WorkingDirectory=/path/to/your/project # 项目根目录 # 启动命令。如果项目依赖虚拟环境,需在 `ExecStart` 中指定虚拟环境的 Python 路径(eg:/home/oliver/myenv/bin/python3 app.py) app.py在WorkingDirectory配置的目录下 ExecStart=/usr/bin/python3 main.py Restart=always # 崩溃后自动重启 RestartSec=5 # 重启间隔(秒) Environment="PYTHONUNBUFFERED=1" # 避免日志缓冲 [Install] WantedBy=multi-user.target
注意:最好把脚本中的所有注释删除掉,有时会导致解析失败,运行失败
-
启用并启动服务
sudo systemctl daemon-reload sudo systemctl enable myapp.service # 开机自启 sudo systemctl start myapp.service # 立即启动
-
查看状态和日志
sudo systemctl status myapp.service journalctl -u myapp.service -f # 实时查看日志
方法 2:使用 supervisord
supervisord
是一个进程管理工具,适合需要监控多进程的场景。
步骤:
-
安装 Supervisor
sudo apt-get install supervisor # Debian/Ubuntu sudo yum install supervisor # CentOS/RHEL
-
创建配置文件
新建配置文件到/etc/supervisor/conf.d/myapp.conf
:[program:myapp] command=/usr/bin/python3 /path/to/your/project/main.py directory=/path/to/your/project user=your_username autostart=true autorestart=true stderr_logfile=/var/log/myapp.err.log stdout_logfile=/var/log/myapp.out.log
-
更新并启动服务
sudo supervisorctl update sudo supervisorctl start myapp
-
查看状态
sudo supervisorctl status
方法 3:使用 cron
任务
通过 @reboot
定时任务实现开机自启(简单但功能有限)。
步骤:
-
编辑 cron 任务
crontab -e
-
添加启动命令
@reboot /usr/bin/python3 /path/to/your/project/main.py > /path/to/logfile.log 2>&1
方法 4:使用 screen
/tmux
(临时方案)
仅适合临时测试,不推荐生产环境:
# 启动一个后台会话
screen -dmS myapp python3 /path/to/main.py
# 查看会话
screen -ls
方法 5:容器化部署(Docker)
通过 Docker 容器部署,结合 --restart always
策略。
步骤:
-
编写 Dockerfile
FROM python:3.9 WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . CMD ["python3", "main.py"]
-
构建并运行容器
docker build -t myapp . docker run -d --name myapp --restart always myapp
关键注意事项
- 日志管理
确保程序输出日志到文件(如logging
模块配置),避免日志丢失。 - 虚拟环境
如果使用虚拟环境,需在服务配置中指定完整路径(如/path/to/venv/bin/python3
)。 - 依赖管理
使用requirements.txt
管理依赖:pip freeze > requirements.txt
选择适合场景的方案,通常推荐 systemd
或 supervisord
用于生产环境。
我采用的是第一种方式systemd,配置过程常见问题:
根据你提供的 systemctl status
输出,服务启动失败的原因是 status=217/USER
,这通常与服务配置中的用户权限问题相关。以下是详细排查和修复步骤:
1. 错误原因分析
status=217/USER
表示 systemd 在尝试以指定用户(User=
字段)运行服务时失败,可能原因包括:- 配置的
User=
字段指定的用户不存在。 - 服务文件或脚本路径对目标用户无权限访问。
- 目标用户没有执行权限或环境变量问题。
- 配置的
2. 检查服务文件配置
确认你的服务文件 /etc/systemd/system/myapp.service
中的以下关键配置:
[Service]
User=your_username # 确保此处用户真实存在(如 oliver)
WorkingDirectory=/home/oliver/deploy/navigation/navigation_site # 目录必须存在且用户有权访问
ExecStart=/usr/bin/python3 /home/oliver/deploy/navigation/navigation_site/app.py # 路径必须正确
验证用户是否存在
# 检查用户是否存在(替换 your_username)
id your_username
# 如果用户不存在,创建用户:
sudo useradd your_username
检查目录权限
# 确保用户对项目目录有权限
sudo chown -R your_username:your_username /home/oliver/deploy/navigation
sudo chmod -R 755 /home/oliver/deploy/navigation
3. 手动测试脚本
以目标用户身份直接运行命令,验证脚本是否能正常启动:
sudo -u your_username /usr/bin/python3 /home/oliver/deploy/navigation/navigation_site/app.py
- 如果手动运行失败,说明问题在脚本本身(如依赖缺失、Python 环境错误等)。
- 手动运行成功后,再通过 systemd 启动服务。
4. 检查日志详情
通过 journalctl
查看完整日志,定位具体错误:
journalctl -u myapp.service --since "5 minutes ago" -f
重点关注以下日志线索:
- 权限被拒绝(Permission denied)。
- 文件或目录不存在(No such file or directory)。
- Python 模块导入错误(ModuleNotFoundError)。
5. 常见修复场景
场景 1:虚拟环境问题
如果项目依赖虚拟环境,需在 ExecStart
中指定虚拟环境的 Python 路径:
ExecStart=/path/to/venv/bin/python3 /home/oliver/deploy/navigation/navigation_site/app.py
场景 2:依赖缺失
确保依赖已安装到目标用户环境:
sudo -u your_username pip3 install -r /home/oliver/deploy/navigation/requirements.txt
场景 3:环境变量问题
在服务文件中显式声明环境变量:
[Service]
Environment="PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Environment="PYTHONPATH=/home/oliver/deploy/navigation"
6. 更新配置后重启服务
sudo systemctl daemon-reload
sudo systemctl restart myapp.service
sudo systemctl status myapp.service
7. 备用方案:临时移除用户配置
如果问题仍存在,可暂时移除 User=
字段(以 root 身份运行),测试是否是用户权限问题:
[Service]
# User=your_username # 注释此行
WorkingDirectory=...
ExecStart=...
总结
- 核心问题:用户权限或路径配置错误。
- 关键命令:手动运行脚本、检查日志、修复权限。
- 如果问题仍未解决,请提供
journalctl
日志的完整输出。