在 Linux 服务器上运行 Python 应用程序(如 app.py
)时,如果直接在终端中运行该命令,一旦关闭 SSH 客户端或终端会话,应用程序也会随之终止,导致站点无法访问。为了确保您的站点始终运行,即使在关闭 SSH 会话后,您可以采取以下几种方法:
- 使用
systemd
创建系统服务 - 使用
nohup
命令 - 使用
screen
或tmux
会话管理器
下面将详细介绍这些方法,推荐优先使用 systemd
,因为它更加稳定和易于管理。
方法一:使用 systemd
创建系统服务(推荐)
systemd
是现代 Linux 发行版中用于管理系统和服务的初始化系统。通过创建一个 systemd
服务单元文件,您可以将 Python 应用程序配置为系统服务,确保它在后台持续运行,并在系统重启时自动启动。
步骤 1:准备工作
-
确认应用路径和虚拟环境
假设您的 Python 应用程序位于
/home/oliver/deploy/navigation/navigation_site/app.py
,虚拟环境位于/home/oliver/myenv/
。 -
确保虚拟环境已正确配置
激活虚拟环境并确保所有依赖包已安装:
source /home/oliver/myenv/bin/activate pip install -r /home/oliver/deploy/navigation/navigation_site/requirements.txt deactivate
步骤 2:创建 systemd
服务文件
-
创建服务文件
使用文本编辑器(如
vi
或vim
)创建一个新的systemd
服务文件,例如myapp.service
:sudo vi /etc/systemd/system/myapp.service
-
编辑服务文件内容
在文件中添加以下内容,请根据您的实际情况修改路径和用户:
[Unit] Description=My Python Application After=network.target[Service] User=oliver Group=oliver WorkingDirectory=/home/oliver/deploy/navigation/navigation_site Environment="PATH=/home/oliver/myenv/bin" ExecStart=/home/oliver/myenv/bin/python app.py Restart=always RestartSec=5[Install] WantedBy=multi-user.target
解释各部分含义:
-
[Unit]
Description
:服务的描述。After
:指定服务启动的顺序,这里设置为在网络服务启动后启动。
-
[Service]
User
和Group
:指定运行服务的用户和组,建议使用非root
用户。WorkingDirectory
:应用程序的工作目录。Environment
:设置环境变量,这里指定虚拟环境的PATH
。ExecStart
:启动服务的命令,使用虚拟环境中的 Python 解释器运行app.py
。Restart
:服务异常退出时自动重启,always
表示无论退出状态如何都重启。RestartSec
:重启前的等待时间(秒)。
-
[Install]
WantedBy
:指定服务在哪个目标下启动,multi-user.target
是常见的系统运行级别。
-
步骤 3:重新加载 systemd
配置
sudo systemctl daemon-reload
步骤 4:启动并启用服务
-
启动服务
sudo systemctl start myapp.service
-
启用服务开机自启
sudo systemctl enable myapp.service
步骤 5:检查服务状态
sudo systemctl status myapp.service
预期输出示例:
● myapp.service - My Python ApplicationLoaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: disabled)Active: active (running) since Thu 2024-04-27 10:00:00 UTC; 1min agoMain PID: 12345 (python)Tasks: 1 (limit: 1153)CGroup: /system.slice/myapp.service└─12345 /home/oliver/myenv/bin/python app.py
步骤 6:查看服务日志
使用 journalctl
查看服务的日志输出:
sudo journalctl -u myapp.service -f
-f
参数表示实时跟踪日志输出。
注意事项
-
确保应用程序监听正确的网络接口和端口
在
app.py
中,确保您的应用程序绑定到0.0.0.0
而不是127.0.0.1
,这样外部请求才能访问。if __name__ == "__main__":app.run(host="0.0.0.0", port=8000)
-
配置防火墙
确保服务器的防火墙允许访问您的应用程序所监听的端口(如
8000
)。sudo firewall-cmd --permanent --add-port=8000/tcp sudo firewall-cmd --reload
方法二:使用 nohup
命令
nohup
命令可以在后台运行命令,并忽略挂起信号(如关闭 SSH 会话)。虽然这种方法简单,但不如 systemd
方便进行管理和监控。
步骤
-
激活虚拟环境
source /home/oliver/myenv/bin/activate
-
运行应用程序并使用
nohup
nohup python /home/oliver/deploy/navigation/navigation_site/app.py > app.log 2>&1 &
解释:
nohup
:忽略挂起信号。> app.log 2>&1
:将标准输出和标准错误重定向到app.log
文件。&
:将进程放入后台运行。
-
查看运行中的进程
ps aux | grep app.py
-
停止应用程序
找到进程 ID(PID),然后使用
kill
命令停止:kill PID
方法三:使用 screen
或 tmux
会话管理器
screen
和 tmux
都是终端复用工具,允许您在一个终端会话中创建多个子会话,并在会话之间切换。即使关闭 SSH 会话,子会话仍然在后台运行。
使用 tmux
的步骤
-
安装
tmux
sudo yum install tmux -y # CentOS 7 sudo dnf install tmux -y # CentOS 8+
-
创建并进入新的
tmux
会话tmux new -s myapp
-
激活虚拟环境并运行应用程序
source /home/oliver/myenv/bin/activate python /home/oliver/deploy/navigation/navigation_site/app.py
-
分离
tmux
会话按下
Ctrl + B
,然后按D
键。 -
查看当前的
tmux
会话tmux ls
-
重新连接到
tmux
会话tmux attach -t myapp
-
停止应用程序
在
tmux
会话中,使用Ctrl + C
停止应用程序。
总结与推荐
为了确保您的 Python 应用程序在 Linux 服务器上持续运行,建议优先使用 systemd
创建系统服务。这种方法不仅稳定,而且便于管理和监控。以下是推荐的步骤概览:
- 创建
systemd
服务文件,配置正确的工作目录、用户、环境变量和启动命令。 - 重新加载
systemd
配置,启动并启用服务。 - 检查服务状态,确保应用程序正常运行。
- 查看服务日志,监控应用程序输出和错误。
使用 systemd
的优点包括:
- 自动重启:服务异常退出时会自动重启。
- 开机自启:服务器重启后服务会自动启动。
- 集中管理:使用
systemctl
管理所有服务,统一查看状态和日志。
如果您对 systemd
不熟悉,或者在设置过程中遇到问题,可以考虑使用 nohup
或 tmux
作为临时解决方案,但长期来看,systemd
是更为稳健的选择。
附加建议
-
使用生产级 WSGI 服务器
如果您的应用程序是基于 Flask、Django 或其他 WSGI 框架,建议使用生产级 WSGI 服务器(如
gunicorn
或uWSGI
),并结合nginx
作为反向代理,以提高性能和安全性。示例使用
gunicorn
:pip install gunicorn gunicorn --workers 3 --bind 0.0.0.0:8000 app:app
将
gunicorn
命令添加到systemd
服务文件中。 -
配置反向代理(可选)
使用
nginx
作为反向代理,将外部请求转发到您的 Python 应用程序,提高安全性和性能。安装
nginx
:sudo yum install nginx -y # CentOS 7 sudo dnf install nginx -y # CentOS 8+
配置
nginx
:编辑
/etc/nginx/conf.d/myapp.conf
,添加以下内容:server {listen 80;server_name your_domain_or_IP;location / {proxy_pass http://127.0.0.1:8000;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;} }
启动并启用
nginx
:sudo systemctl start nginx sudo systemctl enable nginx
-
设置防火墙规则
确保服务器的防火墙允许访问应用程序和
nginx
所监听的端口(如80
和443
)。sudo firewall-cmd --permanent --add-service=http sudo firewall-cmd --permanent --add-service=https sudo firewall-cmd --reload
-
使用 HTTPS 保障安全
使用
Let's Encrypt
为您的站点配置免费的 SSL 证书,确保数据传输的安全性。安装
certbot
和配置 SSL:sudo yum install epel-release -y sudo yum install certbot python3-certbot-nginx -y sudo certbot --nginx
按照提示完成 SSL 证书的申请和配置。
如果您在设置过程中遇到任何问题或需要进一步的帮助,请随时提供详细信息,我将进一步协助您!