Axum 部署实战:用 Nginx 反向代理把 Rust 后端送上生产环境
前几篇我们把服务做成了持久化、有认证、有日志、有健康检查的完整后端。但代码写好了不等于能上线,部署才是最后一道坎。
这篇文章基于前面的 todo_service,把它部署到 Linux 服务器上,用 systemd 做进程管理,Nginx 做反向代理和 HTTPS 终止,让它成为一个真正可对外服务的生产级应用。
部署架构
客户端 → Nginx (HTTPS / 静态资源 / 反向代理) → Axum (127.0.0.1:3000) → PostgreSQL
这样设计有几个好处:
- Nginx 处理 TLS,Axum 只跑 HTTP,逻辑简单
- Nginx 可以做限流、压缩、缓存、访问日志
- Axum 绑定本地回环地址,不直接暴露到公网
- systemd 负责自动重启和日志收集
第一步:编译生产版本
在本地或服务器上编译:
cargo build --release
产物在 target/release/todo_service。建议把这个二进制文件和配置文件一起放到一个固定目录:
sudo mkdir -p /opt/todo_service
sudo cp target/release/todo_service /opt/todo_service/
第二步:配置环境变量
在服务器上创建 .env 文件:
sudo nano /opt/todo_service/.env
内容示例:
DATABASE_URL=postgres://postgres:strong_password@localhost:5432/todo_db
JWT_SECRET=a_long_random_secret_here
RUST_LOG=todo_service=info,tower_http=info
注意权限:
sudo chown root:root /opt/todo_service/.env
sudo chmod 600 /opt/todo_service/.env
密钥和密码绝对不能公开,也不要提交到 Git。
第三步:创建 systemd 服务文件
systemd 是 Linux 上最标准的进程管理工具。创建服务文件:
sudo nano /etc/systemd/system/todo_service.service
内容:
[Unit]
Description=Todo Service
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=todo
Group=todo
WorkingDirectory=/opt/todo_service
ExecStart=/opt/todo_service/todo_service
EnvironmentFile=/opt/todo_service/.env
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
# 安全加固
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/todo_service/logs
[Install]
WantedBy=multi-user.target
创建专用用户:
sudo useradd --system --no-create-home todo
sudo chown -R todo:todo /opt/todo_service
启动服务:
sudo systemctl daemon-reload
sudo systemctl enable todo_service
sudo systemctl start todo_service
查看状态:
sudo systemctl status todo_service
查看日志:
journalctl -u todo_service -f
systemd 会自动处理崩溃重启、开机自启、日志收集,比手动 nohup 或 screen 可靠得多。
第四步:配置 Nginx 反向代理
安装 Nginx:
sudo apt install nginx # Debian/Ubuntu
sudo yum install nginx # CentOS
创建站点配置:
sudo nano /etc/nginx/sites-available/todo_service
内容:
server {
listen 80;
server_name api.example.com;
# 强制跳转 HTTPS(证书配置好后再启用)
# return 301 https://$host$request_uri;
location / {
proxy_pass http://127.0.0.1:3000;
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;
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
proxy_send_timeout 30s;
}
# 健康检查接口可以单独暴露给监控系统
location /health {
proxy_pass http://127.0.0.1:3000;
access_log off;
}
# 禁止外部访问 metrics
location /metrics {
deny all;
return 403;
}
}
启用站点:
sudo ln -s /etc/nginx/sites-available/todo_service /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
第五步:配置 HTTPS
用 Let’s Encrypt 免费证书最简单:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d api.example.com
certbot 会自动修改 Nginx 配置,加上 SSL 证书和自动续期。
如果想手动配置,Nginx 的 HTTPS 部分大致是这样:
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
第六步:数据库备份
数据比代码重要。PostgreSQL 备份很简单:
pg_dump -U postgres todo_db > /backup/todo_db_$(date +%Y%m%d).sql
加到 crontab 里每天自动执行:
crontab -e
0 3 * * * pg_dump -U postgres todo_db | gzip > /backup/todo_db_$(date +\%Y\%m\%d).sql.gz
再配合 find 删除 30 天前的旧备份:
find /backup -name "todo_db_*.sql.gz" -mtime +30 -delete
第七步:基础安全加固
- 防火墙只开放必要端口:
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
sudo ufw enable
- PostgreSQL 只监听本地:
在 postgresql.conf 里确认:
listen_addresses = 'localhost'
-
SSH 禁用密码登录,改用密钥认证。
-
定期更新系统:
sudo apt update && sudo apt upgrade -y
- Axum 不要绑定 0.0.0.0,绑
127.0.0.1:3000即可,流量全部走 Nginx。
部署后的验证清单
# 1. 检查服务状态
sudo systemctl status todo_service
# 2. 检查健康接口
curl http://127.0.0.1:3000/health
# 3. 检查 Nginx 反向代理
curl http://api.example.com/health
# 4. 检查 HTTPS
curl https://api.example.com/health
# 5. 测试注册登录
curl -X POST https://api.example.com/register \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"123456"}'
curl -X POST https://api.example.com/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"123456"}'
# 6. 检查日志
journalctl -u todo_service -n 50
后续可以继续优化
- 用 Docker + docker-compose 做容器化部署
- 接入 GitHub Actions 做 CI/CD 自动发布
- 用 Prometheus + Grafana 做指标可视化
- 接入 Loki 或 ELK 做集中日志
- 配置 Nginx 限流和 WAF 规则
- 多实例部署 + 负载均衡
Rust 后端部署其实很省心:一个静态链接的二进制文件,没有运行时依赖,丢到服务器上就能跑。配合 systemd 和 Nginx,已经能覆盖绝大多数中小规模的生产场景。代码写得稳,部署也稳,这才是 Rust 后端最舒服的地方。
- 点赞
- 收藏
- 关注作者
评论(0)