在做一个 AI + Excel 数据处理的 Flask 项目时,我遇到一个实际问题:
“我本地开发调好了,如何一条命令推送到服务器,并让服务器立即生效?”
这篇文章就是一份完整实践记录,涵盖了我踩过的坑、学到的经验,以及最终稳定运行的部署策略。
✅ 第一阶段:先把 Git 通起来
我项目的部署路径在云服务器上是这样的:
~/traeyuexin/YuexinAI
本地则是:
F:/traeyuexin/YuexinAI
1、本地 Git 初始化流程:
cd F:/traeyuexin/YuexinAI
git init
git config --global user.name "Aran Tu"
git config --global user.email "aran.tu@example.com"
2、添加远程地址:
git remote add origin root@X.XXX.XXX.XX:/root/traeyuexin/YuexinAI
⚠️ 注意:别写成 ssh://root@http://...
,只需 root@ip:/路径
即可。
3、首次提交 & 推送
git add .
git commit -m "首次提交"
git push origin master
🧰 云端接收 Git 推送
进入服务器目录:
cd ~/traeyuexin/YuexinAI
git config receive.denyCurrentBranch updateInstead
这一步至关重要,否则服务器不会让你覆盖当前代码。
❌ 我踩过的坑:用 nohup + Flask debug 模式,以为可以热更新
最初,我使用了这条命令让 Flask 在后台运行:
nohup python app.py > output.log 2>&1 &
由于我在 app.py
中写了:
python
app.run(debug=True)
所以每次我 git push
之后改了 .py
文件,居然真的“自动重启”了!我一度以为 Flask 真有热更新能力。
后来才知道:⚠️ 这是个“错觉”!
Flask 的
debug=True
会启用自动重启机制,但它是通过子进程实现的。
在nohup
下,这会造成“主进程不退出、子进程频繁重启”,非常不稳定。
✅ 第二阶段:正确做法是 post-receive + run.sh
于是我切换思路,走 “Git 推送 + 自动部署 + 安全重启” 的路线。
1、服务器端配置 Git 自动部署
进入 Git 钩子目录:
cd ~/traeyuexin/YuexinAI/.git/hooks
nano post-receive
内容如下:
#!/bin/bash
echo "📦 收到代码推送,开始自动部署..."
GIT_WORK_TREE=/root/traeyuexin/YuexinAI git checkout -f
cd /root/traeyuexin/YuexinAI
source venv/bin/activate
./run.sh
赋权:
chmod +x post-receive
2、run.sh 脚本(真正的部署关键)
#!/bin/bash
cd /root/traeyuexin/YuexinAI
source venv/bin/activate
# 杀掉旧进程,防止端口冲突或 zombie 进程
pkill -f "python app.py"
# 启动新服务
echo "🚀 正在启动 Flask..."
nohup python app.py > output.log 2>&1 &
这段脚本确保了:
- 每次部署前都干净地杀掉旧 Flask 服务;
- 用
nohup
启动 Flask,让它后台常驻运行; - 可通过
output.log
观察运行状态。
🔥 Flask 热更新的正确理解
模式 | 说明 | 是否推荐 |
---|---|---|
debug=True + python app.py | 开发环境热更新 | ✅ 开发用 |
nohup python app.py + debug=True | 有“假象热更新”,但不稳定 | ❌ 不推荐 |
Git push + post-receive + run.sh | 稳定安全、自动重启 | ✅ 强烈推荐 |
gunicorn + supervisor | 生产级部署 | ✅ 建议长期用 |
📁 我的 .gitignore
示例
gitignore
venv/
__pycache__/
*.pyc
*.log
.env
[本地] git push origin master
↓
[服务器]
post-receive 自动 checkout + run.sh
↓
停止旧服务 → 启动新服务 → 持久运行
现在我只需要:
git add .
git commit -m "优化了处理逻辑"
git push origin master
服务器立即更新代码、重启服务,完全无感知,部署秒生效。
✅ 第三阶段: gunicorn + nginx + supervisor
Flask 项目正式上线的推荐三件套:Gunicorn + Nginx + Supervisor,适用于 Ubuntu 系统(Debian 同样通用)。
YuexinAI/
│
├── app.py
├── static/
├── templates/
├── requirements.txt
├── venv/
└── gunicorn.conf.py (可选高级配置)
思路:
-
使用 Gunicorn 作为 WSGI 服务器,接管 Flask 应用
-
用 Nginx 反向代理、提供静态资源支持
-
借助 Supervisor 进行服务托管、自动重启和日志管理
-
最终达到:安全、可控、可恢复、适配高并发
# 安装 Gunicorn
pip install gunicorn
# 安装 nginx & supervisor
sudo apt update
sudo apt install nginx supervisor -y
cd /root/traeyuexin/YuexinAI
source venv/bin/activate
gunicorn -w 4 -b 127.0.0.1:8000 app:app
说明:
-w 4
:启动 4 个 worker 进程(建议 = CPU 核心数 * 2 + 1)-b 127.0.0.1:8000
:绑定本地地址端口app:app
:前者为 Python 文件名(app.py),后者为 Flask 对象名
浏览器访问不到是正常的,下一步配置 nginx。
sudo nano /etc/nginx/sites-available/yuexin
内容如下:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /static {
alias /root/traeyuexin/YuexinAI/static;
}
location /favicon.ico {
alias /root/traeyuexin/YuexinAI/static/favicon.ico;
}
}
然后启用配置:
sudo ln -s /etc/nginx/sites-available/yuexin /etc/nginx/sites-enabled
sudo nginx -t # 检查配置
sudo systemctl restart nginx
Supervisor 配置 Gunicorn 守护进程
sudo nano /etc/supervisor/conf.d/yuexin.conf
内容如下:
[program:yuexin]
directory=/root/traeyuexin/YuexinAI
command=/root/traeyuexin/YuexinAI/venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 app:app
autostart=true
autorestart=true
stderr_logfile=/var/log/yuexin.err.log
stdout_logfile=/var/log/yuexin.out.log
user=root
environment=PATH="/root/traeyuexin/YuexinAI/venv/bin",VIRTUAL_ENV="/root/traeyuexin/YuexinAI/venv"
启动服务:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start yuexin
查看运行状态:
sudo supervisorctl status
🔥 高级推荐(可选)
- 开启 https(用 Let's Encrypt)
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d your-domain.com
2. 配置 gunicorn.conf.py 文件
支持自动重载、日志分离、PID 文件管理等:
# gunicorn.conf.py
bind = "127.0.0.1:8000"
workers = 4
accesslog = '/var/log/yuexin.access.log'
errorlog = '/var/log/yuexin.error.log'
reload = False # 上线时建议 False
Supervisor command 改成:
command=/root/traeyuexin/YuexinAI/venv/bin/gunicorn -c gunicorn.conf.py app:app
- Gunicorn:生产级 WSGI 服务
- Nginx:统一入口 + 静态文件 + 反向代理
- Supervisor:自动启动 + 异常重启 + 日志持久化
最后的思考
部署从来不是一件简单事,尤其是当你想把开发体验延伸到云端时。
但一旦打通 Git 推送 + 自动更新 + 安全运行这条链路,你就再也回不去手动上传/重启的日子了。