用Trae Work开发的Python Flask项目,部署到Ubuntu 24.04 服务器的实操记录。
一、Ubuntu服务器系统准备
- 启用 SSH 服务:让管理电脑(Windows 11)通过SSH接入服务器进行操作。
sudo apt update #更新仓库
sudo apt install openssh-server #安装服务端
sudo systemctl status ssh #检查状态 - 服务器上的 SSH 服务安装好后,其它操作都可以在管理电脑上通过SSH进行。
二、配置管理电脑与服务器的连接
- 进入管理电脑的PowerShell窗口
win + R:powershell - 登录Ubuntu服务器(地址192.168.0.217,主机名SP-AI)
ssh sandal@192.168.0.217
提示符变成 sandal@SP-AI:~$ 表示已进入服务器 - 更新系统包(建议执行,需要几分钟)
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3 python3-venv python3-pip git curl wget
sudo reboot #重启一次服务器 - 配置 SSH 免密码登录
ssh-keygen -t ed25519 #本机生成密钥,一路回车不要设passphrase
ssh-copy-id sandal@192.168.0.217 #将公钥复制到服务器
#ssh-copy-id 命令需要PS另外安装,可以用 Get-Content 命令代替
Get-Content C:\id_ed25519.pub | ssh sandal@192.168.0.217 “cat >> ~/.ssh/authorized_keys” - 配置sudo 免密执行
sudo visudo #在末尾加入下述代码
sandal ALL=(ALL) NOPASSWD: /usr/bin/apt, /usr/bin/apt-get, /usr/bin/dpkg
三、传送项目文件到服务器
- 在服务器中创建项目目录
sudo mkdir -p /opt/spAnonymous
sudo chown -R $USER:$USER /opt/spAnonymous
cd /opt/spAnonymous - 简单做法,直接把整个目录传给服务器(局域网内)
scp -r F:\AI\jhAnonymous\ sandal@192.168.0.217:/opt/spAnonymous/ - .开头的隐藏文件有可能要单独传
scp F:\AI\jhAnonymous\.env sandal@192.168.0.217:/opt/spAnonymous/ - 标准做法,先打包压缩再传送再解压(局域网内)
tar -czf $env:TEMP\deploy.tar.gz .
scp $env:TEMP\deploy.tar.gz sandal@192.168.0.217:/opt/
tar -xzf /opt/deploy.tar.gz -C /opt/spAnonymous
rm /opt/deploy.tar.gz
sudo chown -R $USER:$USER /opt/spAnonymous #授权访问 - 常用做法是Git 推送(互联网,团队协作)
GitHub/GitLab + Ubuntu 拉取 - 安装 rsync 可传可同步
rsync -avz F:\AI\Trae4App\jhAnonymous\ sandal@192.168.0.217:/opt/spAnonymous/
四、创建本项目专用 Python 虚拟环境及配套依赖
- 创建虚拟环境
cd /opt/spAnonymous
python3 -m venv venv
source venv/bin/activate #激活虚拟环境
deactivate #退出虚拟环境与win的相同 - 升级 pip工具 + 安装依赖
(venv):python -m pip install –upgrade pip
(venv):pip install -r requirements.txt
(venv):pip list #检查是否依赖安装齐全 - WSGI 服务器的选择
windows系统里优选 Waitress
Linux系统里优选 Gunicorn
(venv) pip install gunicorn==22.0.0 #Gunicorn适于Linux
(venv) pip uninstall Waitress #Ubuntu里可以卸载Waitress - 编辑配置文件(非必须)
nano .env #如果没有就复制.env.example 来改
GUNICORN_BIND=127.0.0.1:5016 #用 Nginx 时只监听本地
GUNICORN_BIND=0.0.0.0:5016 #不用 Nginx 时对外 #二选一
head -c 5 config.json | xxd #检查文件确保其UTF8没有BOM - 临时目录权限设置(logs + temp_uploads)
cd /opt/spAnonymous
sudo mkdir -p logs temp_uploads #若无就创建
sudo chown -R $USER:$USER logs temp_uploads
chmod 755 temp_uploads logs #修改目录的权限
五、手工启动服务并测试
- 杀掉其它可能存在的 5016 端口的进程,免得影响测试
sudo fuser -k 5016/tcp 2>/dev/null - 新开SSH窗口来启动服务:
cd /opt/spAnonymous && source venv/bin/activate
python run_waitress.py
Ctrl + C #随时中止服务 - 回到原来的SSH窗口测试(四种方法):
curl -s -o /tmp/sp_index.html -w “首页: %{http_code} 大小: %{size_download}字节\n” http://127.0.0.1:5016/
curl -s http://127.0.0.1:5016/api/config | python3 -m json.tool
PS命令:Test-NetConnection 192.168.0.217 -Port 5016
管理电脑上用浏览器访问 http://192.168.0.217:5016 - 若测试服务崩了 / 卡住 / 端口占用(SSH 里执行)
ss -tlnp | grep 5016 #找 5016 的进程
sudo fuser -k 5016/tcp #或者直接杀掉进程
六、把本项目注册为Ubuntu的系统服务
- 创建服务文件(systemd unit)(文件名小写)(每服务一文件)
sudo nano /etc/systemd/system/spanonymous.service
#内容如下
[Unit]
Description=SP Anonymous Email Web Service
After=network.target
[Service]
Type=simple
User=sandal
Group=sandal
WorkingDirectory=/opt/spAnonymous
Environment=”PATH=/opt/spAnonymous/venv/bin”
#适用于windows系统 二选一
ExecStart=/opt/spAnonymous/venv/bin/python /opt/spAnonymous/run_waitress.py
#适用于Linux系统 二选一
ExecStart=/opt/spAnonymous/venv/bin/python /opt/spAnonymous/run_gunicorn.py
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target - 启动注册的服务
sudo systemctl daemon-reload #重新加载 systemd
sudo systemctl start spanonymous # 启动服务
sudo systemctl enable spanonymous#开机自启(生成symLink) - 日常维护命令:
sudo systemctl start spanonymous #启动
sudo systemctl stop spanonymous # 停止
sudo systemctl restart spanonymous # 重启
sudo systemctl status spanonymous # 看状态-重要
sudo journalctl -u spanonymous #看全部日志
sudo journalctl -u spanonymous –since today#查看今天日志
sudo journalctl -u spanonymous -n 50 #最近 50 行日志
sudo journalctl -u spanonymous.service -f #实时滚动日志
sudo systemctl disable spanonymous # 开机自动启动
tail -f logs/app.log #看自身日志 - 项目本身完工,根据 .env 的配置,可以用 http://127.0.0.1:5016访问
链路:用户请求 → WSGI 服务器(Gunicorn) → Python Web 应用(Flask)
七、安装Web 服务器(Nginx)做统一入口,确保安全、静态文件加速
- 现实架构(子路径)
用户 → Nginx (80/443) → /anymail/ → spAnonymous (Gunicorn, 127.0.0.1:5016) - 安装Nginx
sudo apt install -y nginx
nginx -v
sudo systemctl status nginx
http://192.168.0.217 #首次查看Nginx欢迎页面 - 创建Nginx首页,分流子路径到本项目
sudo tee /var/www/html/index.html << ‘EOF’
index.html 范本见文末 - 创建本项目虚拟主机的配置文件(子路径方案)
sudo nano /etc/nginx/sites-available/spanonymous.conf
spanonymous.conf 范本见文末 - 创建配置文件的符号链接
sudo ln -sf /etc/nginx/sites-available/spanonymous.conf /etc/nginx/sites-enabled/ - 检查语法,重启web服务器
sudo nginx -t #必须 “syntax is ok”
sudo systemctl reload nginx #重启web服务
ss -tlnp | grep -E ‘:(80|5016)’ #检查端口 - 查看服务器的状态
free -h && df -h && uptime #内存硬盘时间
nvidia-smi #显卡情况
http://192.168.0.217/anymail/ #终极测试就是实用
八、防火墙开放 5016 端口(非子路径时需要开放特定端口)
- sudo ufw status # 先看 ufw 开没开,局域网内服务器不必开启
- sudo ufw allow from 192.168.0.0/24 to any port 5016 comment “spAnonymous5016”
- sudo ufw reload
- sudo ufw status numbered #应能看到 5016 规则
九、/var/www/html/index.html 范本
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SP-AI Server</title>
<style>
body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
h1 { color: #333; }
ul { line-height: 2; }
a { color: #0066cc; text-decoration: none; }
a:hover { text-decoration: underline; }
</style>
</head>
<body>
<h1>SP-AI 服务器</h1>
<p>已部署服务:</p>
<ul>
<li><a href="/anymail/">银图集团举报邮件系统</a></li>
</ul>
<hr>
<p><small>Ubuntu 24.04 | Nginx | Gunicorn</small></p>
</body>
</html>
十、/etc/nginx/sites-available/spanonymous.conf 范本
server {
listen 80;
server_name 192.168.0.217;
# 默认首页
location / {
root /var/www/html;
index index.html;
}
# spAnonymous 子路径
location /anymail/ {
proxy_pass http://127.0.0.1:5016/;
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;
client_max_body_size 100M;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}
# 静态文件直接由 Nginx 提供(性能优化)
location /anymail/static/ {
alias /opt/spAnonymous/static/;
expires 7d;
access_log off;
}
# API 接口兜底:/api/ 代理到 Gunicorn(人机验证、提交、配置检查都走这里)
location /api/ {
proxy_pass http://127.0.0.1:5016/api/;
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;
client_max_body_size 100M;
proxy_connect_timeout 120s;
proxy_send_timeout 120s;
proxy_read_timeout 120s;
}
# 兜底:根路径的 /static/ 也代理到 Gunicorn
location /static/ {
proxy_pass http://127.0.0.1:5016/static/;
proxy_set_header Host $host;
}
}
