【VPS 进阶玩法精选 02】用 VPS 部署你自己的 API / 后端服务(Node / Python / Go 实战)

从零在便宜 VPS 上部署生产级后端:选系统、装运行环境、用 systemd/pm2 守护、Nginx 反代、HTTPS 与最小安全配置,附可复制命令。

专题连载:VPS 进阶玩法精选

本文是该系列第 2 篇。阅读该系列其他文章:

你写完了 API,本地用 curl 一测通了,下一步呢?把它丢到一台按月付费的 VPS 上,让它 7×24 跑着、崩溃能自己爬起来、带 HTTPS、还能看日志——这就是"生产级部署"。很多人卡在这一步,觉得要 Docker、K8s、CI/CD 一整套才叫部署。其实对绝大多数个人项目、小团队后端、给 App 或小程序当接口的服务来说,一台 1 核 1G 的 VPS + Nginx + 进程管理器就完全够用,成本每月几块钱到几十块钱。

这篇文章不聊虚的架构图,直接给你能复制粘贴的命令。我们覆盖三种最常见的后端栈:Node.js(用 pm2)、Python FastAPI(用 systemd + Gunicorn)、Go(编译成单文件,用 systemd)。无论你用哪一个,最终架构都是同一套:客户端 → Nginx(HTTPS、反代)→ 你的应用进程 → 数据库/缓存。Nginx 只干边缘活,应用进程专心处理业务。

延伸阅读

更多相关攻略推荐:Ollama AI系列(2):VPS上的AI推理与API应用Ollama AI系列(2):VPS上的AI推理与API应用ARM / Ampere 席卷 VPS:性价比真香还是兼容陷阱?【VPS 硬件选型指南 (内存 篇) 02】大内存 VPS 能干嘛?2026 独立站 PCI-DSS 自查清单:SAQ A 还是 A-E

一、先选系统和做基础加固

新手无脑选 Ubuntu 24.04 LTS。它的软件源新、社区教程多,2026 年绝大多数 VPS 商家都默认提供,命令在 RackNerdVultrContabo 上完全一致。CentOS 系已经式微,Debian 更稳但需要你更熟,建议先从 Ubuntu 上手。

服务器开机第一件事不是装环境,是防被人秒破。一台裸 VPS 联网几分钟内就会收到 SSH 暴破。三步挡掉大部分攻击:

  • 创建非 root 的 deploy 用户并给 sudo 权限,绝不长期用 root 操作。
  • 用 UFW 防火墙只放行 22/80/443,其余全关。应用监听的 3000、8000 端口一律不对外暴露。
  • 改 SSH 配置:禁止 root 登录、禁止密码登录,只允许密钥。
apt update && apt upgrade -y
adduser deploy
usermod -aG sudo deploy
rsync --archive --chown=deploy:deploy ~/.ssh /home/deploy

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

sudo nano /etc/ssh/sshd_config
# PermitRootLogin no
# PasswordAuthentication no
sudo systemctl restart sshd

避坑:改完 PasswordAuthentication no 之前,一定先确认 deploy 用户的密钥能登录,否则会把自己锁在门外。另外装一个 fail2ban,连续 5 次 SSH 失败就临时封 IP:sudo apt install fail2ban -y && sudo systemctl enable --now fail2ban

二、Node.js 后端:用 pm2 守护

别用系统自带源的 Node,版本老得离谱。生产环境装 NodeSource 的 LTS(2026 年主流是 22.x)。NVM 适合开发机,服务器上直接用 NodeSource 更省心。

curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
node -v

把代码推上去,装生产依赖:

cd /home/deploy
git clone https://github.com/yourorg/yourapi.git
cd yourapi
npm ci --omit=dev
npm run build

注意用 npm ci 而不是 npm install:它严格按 lockfile 安装,可复现,且 lockfile 和 package.json 不一致会直接报错,避免"我本地是好的"这种事故。密钥永远放 .envchmod 600,绝不要进 Git。

Node 是单线程的,直接 node server.js 一关终端进程就死,崩了也不会自启。pm2 解决这个问题:后台常驻、崩溃自启、开机自起,还能多开进程吃满多核。

sudo npm install -g pm2
pm2 start server.js --name yourapi -i max
pm2 save
pm2 startup

-i max 会按 CPU 核心数拉起对应数量的 worker,吞吐量随核数线性增长。最后一行 pm2 startup 会打印一段需要 root 执行的命令,照抄执行就能注册成 systemd 服务,重启后自动复活。发布新版时用 pm2 reload yourapi 做滚动重启,用户无感知;别用 pm2 restart,那是瞬间全杀,会有短暂中断。

三、Python FastAPI:用 systemd + Gunicorn

Python 3.12 一般随系统自带,但要隔离依赖,务必用 venv。FastAPI 的 dev server(uvicorn --reload)只能本地用,生产必须上 Gunicorn + Uvicorn Worker。

sudo apt install -y python3-venv python3-pip
mkdir -p /var/www/yourapi && cd /var/www/yourapi
python3 -m venv venv
source venv/bin/activate
pip install -U pip
pip install fastapi "uvicorn[standard]" gunicorn

Worker 数量经典公式:(2 × CPU 核数) + 1。1 核机器用 3 个,2 核用 5 个。纯异步 I/O 型 API 也可以 1 核 1 worker。写成 systemd 单元最稳,崩溃自启、开机自起、日志进 journald:

[Unit]
Description=FastAPI Application
After=network.target postgresql.service
Wants=postgresql.service

[Service]
Type=notify
User=deploy
Group=www-data
WorkingDirectory=/var/www/yourapi
Environment="PATH=/var/www/yourapi/venv/bin"
EnvironmentFile=/var/www/yourapi/.env
ExecStart=/var/www/yourapi/venv/bin/gunicorn main:app   --worker-class uvicorn.workers.UvicornWorker   --workers 4   --bind unix:/run/yourapi/gunicorn.sock   --timeout 120   --max-requests 1000
ExecReload=/bin/kill -s HUP $MAINPID
Restart=always
RestartSec=5
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/www/yourapi /var/log/yourapi

[Install]
WantedBy=multi-user.target

这里用 Unix socket 而不是 TCP 端口:本地通信省掉 TCP 开销,端口也不暴露给网络,防火墙配置更干净。--max-requests 1000 是内存泄漏的保险丝,每处理 1000 个请求 worker 就优雅重启一次;那个你控制不了的第三方依赖慢慢漏内存时,它能救你。ProtectSystem=strict 这类是白送的加固,限制进程能写的范围。

sudo mkdir -p /var/log/yourapi
sudo chown deploy:www-data /var/log/yourapi
sudo systemctl daemon-reload
sudo systemctl enable --now yourapi
sudo journalctl -u yourapi -f

四、Go 后端:编译成单文件,systemd 直接管

Go 最大的幸福是编译出单一静态二进制,没有解释器、没有依赖地狱。你的 VPS 上甚至可以不装 Go,在本地交叉编译好扔上去就行。

# 本地交叉编译出 linux 二进制
GOOS=linux GOARCH=amd64 go build -o yourapi ./cmd/server
scp yourapi deploy@your-server-ip:/var/www/yourapi/

Go 二进制自己就能监听端口、自己处理 TLS,但统一走 Nginx 反代更一致。用 systemd 守护最简单:

[Unit]
Description=Go API Service
After=network.target

[Service]
User=deploy
Group=deploy
WorkingDirectory=/var/www/yourapi
ExecStart=/var/www/yourapi/yourapi
EnvironmentFile=/var/www/yourapi/.env
Restart=always
RestartSec=3
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

Go 没有 Gunicorn 那种多 worker 概念,想多进程就在代码里用 goroutine 充分利用多核即可,部署侧几乎零配置。这也是为什么很多从 Node/Python 切到 Go 的人说"部署变简单了"。

五、Nginx 反代 + HTTPS

永远不要让应用直连公网。Nginx 在前端收 80/443,把请求转给本地应用,顺手把 TLS、gzip、静态文件、限流都做了。装好 Nginx,给每个服务建一个 server block:

sudo apt install nginx -y
sudo nano /etc/nginx/sites-available/yourapi
server {
    listen 80;
    server_name api.yourdomain.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        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_cache_bypass $http_upgrade;
    }
}

UpgradeConnection 两个头是给 WebSocket 用的,有实时功能必加。X-Forwarded-* 把真实客户端 IP 和协议透传给应用——不加的话日志里所有请求都显示来自 localhost,限流和审计全瞎。启用前先 sudo nginx -t 校验语法,避免一个 typo 把整站搞挂。

sudo ln -s /etc/nginx/sites-available/yourapi /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

HTTPS 用 Let's Encrypt 免费证书,Certbot 一键搞定,还会自动续期:

sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d api.yourdomain.com
sudo certbot renew --dry-run

最后那句 dry-run 一定要跑,确认自动续期脚本真的能工作,否则 90 天后证书过期你才发现接口全挂了。想给 API 加限流,在 http 段加 zone,server 段引用即可,例如每分钟每 IP 60 次请求、突发 20:limit_req_zone $binary_remote_addr zone=api:10m rate=60r/m; 再在 location 里 limit_req zone=api burst=20 nodelay;

证书签发后建议顺手开启 HTTP/2 和 gzip 压缩:HTTP/2 多路复用能显著减少移动端小请求的延迟,gzip 对 JSON 文本响应通常能压掉 70% 体积,带宽和首包时间都省。在 listen 443 那行加 http2 on;,在 server 段加 gzip on; gzip_types application/json text/plain; 即可,改完同样先 nginx -t 再 reload。如果你的接口前面还套了 Cloudflare,记得把加密模式设成 Full (strict),并在 Nginx 上用 Cloudflare 的源站证书,避免回源被中间人。Cloudflare 还能帮你挡掉大部分 L3/L4 的 DDoS,对小站点几乎是免费的安全增益。

六、进程管理与日志

三种栈的运维命令不同,记住对照表就不乱:

操作Node.js (pm2)Python / Go (systemd)
启动pm2 start server.js --name yourapisudo systemctl start yourapi
重启pm2 reload yourapisudo systemctl restart yourapi
看日志pm2 logs yourapisudo journalctl -u yourapi -f
开机自启pm2 startup && pm2 savesudo systemctl enable yourapi
资源监控pm2 monithtop / systemctl status

日志别无脑写文件,systemd 的 journald 已经帮你管了轮转和大小。要看实时输出就是 journalctl -u yourapi -f。pm2 的日志在 ~/.pm2/logs/。磁盘小的话记得给 journald 设个上限,编辑 /etc/systemd/journald.confSystemMaxUse=200Msudo systemctl restart systemd-journald

七、最小安全配置清单

  • 应用只监听 127.0.0.1:Node/Python/Go 全部 bind 到本地回环,外部只能走 Nginx,多一层缓冲和限流。
  • 防火墙只开 22/80/443:应用端口不对外,UFW 已配就别手痒放行。
  • .env 权限 600:密钥文件只 owner 可读,严防被其它用户或 Web 目录读到。
  • 非 root 用户运行:进程用 deploy 跑,被攻破时影响面小。
  • 加安全响应头:Nginx 里 add_header X-Content-Type-Options nosniffX-Frame-Options DENY,白送的防护。
  • 数据库别用默认端口裸奔:PostgreSQL/Redis 绑本地,需要远程时用 SSH 隧道或内网。
  • 定时备份别省:数据库每天 pg_dumpmysqldump 导出,压缩后传一份到对象存储或另一台机器,出事能回滚到 24 小时内。

最后提醒一句:再好的部署也挡不住"没备份"。一条误删的 SQL 或一次手滑的 rm -rf 比任何黑客都快。给 VPS 商家自带的快照功能也开一份,成本极低却能在系统级故障时整盘还原。安全是层层叠加的,本文给的是最小够用的地基,业务越大越要往上加监控告警、WAF 和异地容灾。

八、VPS 怎么选(结合本站优惠)

跑后端对配置要求不高,1 核 1G 起步就能扛不小的量。重点看三件事:线路延迟(面向国内用户优先 CN2 GIA,延迟 130–160ms 最稳)、是否有 KVM 和 NVMe(NVMe 比 SATA SSD 快 5~10 倍,建站和 TLS 握手吃单核性能)、商家口碑与续费价(警惕首年低价续费翻倍的套路)。

商家典型起步价亮点适合
RackNerd约 $10.28/年(768M/15G/2T)常年神车、支持支付宝/PayPal、KVM+RAID10 SSD预算极低、练手、轻量 API
Vultr$6/月(1G/1 核/25G)32 个全球机房、按小时计费、文档完善要选近用户机房、灵活伸缩
Contabo高配低价、大内存大存储同价位给的 vCPU/内存/流量更厚道内存吃紧的服务、数据库同机

RackNerd 的洛杉矶机房实际托管在 ColoCrossing,老牌 IDC 底子稳;Contabo 在 2026 年因 DRAM 涨价也调过价,但同价位给的资源依然厚道,适合想把数据库和后端放一台省钱的场景。Vultr 胜在全球机房多,给你的海外用户挑最近的节点延迟最低。

💡 延伸阅读:关于架构与基础设施的更多深潜指南,请前往 VPS 主题导读中心 (Hub) 获取全盘策略。