从零到生产:我如何在 VPS 上部署我的 App 而不失去理智
Source: Dev.to
请提供您希望翻译的正文内容,我会在保持原始格式、Markdown 语法和技术术语不变的前提下,将其翻译为简体中文。
前提
每个开发者都有这样的时候:你已经构建了让自己自豪的东西,它在你的笔记本电脑上可以运行,朋友们在等着,用户们也准备好了……然后有人问:“好,但人们到底怎么使用它?”
那个问题把我拉进了一个整整一天的兔子洞——从午夜购买 VPS,到盯着远程服务器上闪烁的光标,再到最终在带有正确 https:// 的实时域名的浏览器中看到我的应用加载。这就是那个故事。
为什么选择 VPS?
把 VPS(虚拟专用服务器)想象成租一套公寓,而不是住酒店房间。
- 共享主机(Heroku、Railway 等) – 酒店:舒适、托管,但你要和陌生人共墙,规则不是你定的。
- VPS – 公寓:这是你的空间,你可以掌控一切,但管道维修要自己负责。
我选择了 OVHcloud。他们的入门级 VPS 方案在价格上具有竞争力——尤其是与同等规格的 AWS 或 DigitalOcean 相比。我订购了一台 Ubuntu 24.04 的 VPS,几分钟内就收到了带有 SSH 凭证的邮件。
提示: 选择数据中心地区时,选离大多数用户最近的地方。延迟是感知性能的隐形杀手。如果你的用户在拉各斯,就不要把服务器放在俄勒冈。
首次登录
当收到包含 VPS IP 和 root 凭据的邮件时,你会有一种像拿到空公寓钥匙的感觉。你走进去,环顾四周,发现那里还什么都没有——没有家具,没有装饰,只有你的工具和抱负。所以你首先要做的就是登录。
ssh root@YOUR_VPS_IP
更新系统
apt update && apt upgrade -y
Source: …
锁定服务器
为什么?
当你的服务器被创建的那一刻起,它已经成为自动化机器人扫描开放端口的目标。你的服务器位于公共互联网——而公共互联网并不友好。在你安装任何依赖或编写任何配置文件之前,需要先锁定谁可以与机器通信。可以把它想象成在新房子周围建一道围栏。
安装并配置 UFW
UFW(Uncomplicated Firewall)是 Ubuntu 对更复杂的 iptables 防火墙规则的友好包装。其理念是:默认拒绝所有,然后只打开必要的端口。
# Install UFW
apt install ufw -y
# Deny ALL incoming connections by default
ufw default deny incoming
# Allow all outgoing (your server needs to reach the internet)
ufw default allow outgoing
# Always allow SSH first — if you forget this and enable the firewall,
# you will lock yourself out permanently. Don't be that person.
ufw allow 22/tcp
# Allow HTTP and HTTPS for the web
ufw allow 80/tcp
ufw allow 443/tcp
# Allow port 3000 for Coolify's dashboard
ufw allow 3000/tcp
# Enable the firewall
ufw enable
检查规则:
ufw status verbose
类比: UFW 就像是你公寓楼入口的保安。他只让已明确允许的住户(端口)进入,其他人全部拒之门外。每一个未打开的端口就相当于对外部世界不存在的门。
添加 Fail2ban 主动防护
UFW 是被动的——它只阻止门的开启。那对付那些主动尝试猜测进入方式的人怎么办?SSH 暴力破解攻击是真实存在的。某处有人在对互联网上的每个 IP 发动机器人,尝试 admin/admin、root/password、root/123456 等组合,分钟级别上千次。如果没有防护,你的服务器只能坐等被攻击。
Fail2ban 监视日志并在 IP 失败次数过多时临时封禁——就像一个把重复违规者踢出的保镖。
apt install fail2ban -y
创建本地配置(切勿直接编辑默认文件——更新时会被覆盖):
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
nano /etc/fail2ban/jail.local
找到 [sshd] 部分并进行配置:
[sshd]
enabled = true
port = ssh
maxretry = 5
bantime = 3600
findtime = 600
启用并启动服务:
systemctl enable fail2ban
systemctl start fail2ban
查看已被封禁的 IP:
fail2ban-client status sshd
类比: 如果 UFW 是围绕你房子的墙,Fail2ban 就是门铃摄像头——当有人敲门超过五次,它会自动报警并叫警察。
你的服务器现在已经加固。它拥有围栏和保镖。任何不该进来的人都被挡在外面。
使用 Coolify 部署应用
现在到了有趣的部分——实际上把东西放到这台服务器上。你可以走艰难的路:手动安装 Nginx,编写配置文件,自己管理 Docker,凌晨 2 点与 SSL 证书搏斗。或者你可以安装 Coolify,它通过浏览器 UI 为你完成所有这些工作。
Coolify 是一个开源的、自托管的平台即服务(PaaS),它抽象掉底层管道(Docker、Nginx、SSL、CI/CD),并提供一个简洁的仪表盘来部署应用、数据库和工作者。
(本指南的其余部分继续介绍 Coolify 的安装、应用部署、SSL 设置以及部署后的技巧。)
Coolify – 您的自托管 “Heroku”
把 Coolify 看作是 Heroku 或 Railway 风格的平台,但您拥有服务器、数据,并直接向 VPS 提供商付费。它处理:
- 部署
- SSL 证书
- 环境变量
- 数据库
- 反向代理
全部通过简洁的网页 UI 完成。
1️⃣ Installation (One‑Liner)
wget -q https://get.coollabs.io/coolify/install.sh -O install.sh
sudo bash install.sh
The installer will:
- 安装 Docker(Coolify 在容器中运行所有内容)
- 部署 Coolify 自己的容器
- 在 3000 端口 启动服务
2️⃣ 首次运行 – 设置向导
打开浏览器并访问:
http://YOUR_VPS_IP:3000
您将看到 Coolify 设置向导。创建您的管理员账户,即可开始使用。
类比:
Coolify = 购买一块土地并自行建造购物中心(完全控制)。
Heroku = 在别人的购物中心租用摊位(方便但受限)。
3️⃣ 添加数据库
每个生产环境的应用都需要持久化的数据存储。
- 导航:
Databases → PostgreSQL → New - 选择一个版本(PostgreSQL 15 或 16)
- 为它命名并点击 Deploy
Coolify 在 Docker 中创建数据库。复制 内部连接字符串:
postgresql://postgres:your_password@YOUR_VPS_IP:5432/postgres
为什么选择 PostgreSQL 而不是 SQLite?
SQLite 是基于文件的数据库——适合开发,但在重新部署时文件会消失。PostgreSQL 是一个正式的、持久的、支持并发的服务器。
Source: …
4️⃣ 部署后端 (API)
4.1 创建新应用
- 菜单:
Applications → New - 连接你的 GitHub 仓库
- 选择 backend 目录
- 选择 Nixpacks 作为构建包(自动检测 Node.js)
4.2 设置环境变量
| 变量 | 值 |
|---|---|
NODE_ENV | production |
DATABASE_URL | postgresql://postgres:your_password@YOUR_VPS_IP:5432/postgres |
JWT_SECRET | 一个非常长的随机字符串 |
FRONTEND_URL | https://pos.yourdomain.com |
PORT | 3000 |
生成强大的 JWT 密钥(切勿提交到 Git):
openssl rand -hex 32
4.3 分配域名并部署
- 域名:
https://api.yourdomain.com - 点击 Deploy
Coolify 将会:
- 从 GitHub 拉取代码
- 使用 Nixpacks 构建
- 在 Docker 容器中运行
- 通过 Traefik(内置反向代理)暴露服务
- 自动申请免费的 Let’s Encrypt SSL 证书
当 /health 返回响应时,API 已上线。
5️⃣ 部署前端 (React/Vite)
5.1 创建另一个应用
Applications → New(same repo)- 选择 frontend 目录
- 构建包:Static / Vite
5.2 环境变量
VITE_API_URL=https://api.yourdomain.com
5.3 域名与重写规则
- 域名:
https://pos.yourdomain.com - Static site config – 添加重写规则,使 SPA 始终返回
index.html:
/* → /index.html
部署并查看日志。当看到 “Build successful” 时,即可完成。
6️⃣ DNS – 将域名指向 VPS
您的服务仍然只能通过 IP 地址访问。请在您的 DNS 提供商处添加 A 记录(示例使用 Namecheap):
| 主机 | 值(VPS IP) | TTL |
|---|---|---|
api | YOUR_VPS_IP | 自动 |
pos | YOUR_VPS_IP | 自动 |
DNS 传播可能需要长达 48 小时,但通常在几分钟内即可完成。
7️⃣ 验证一切
打开一个全新的(非隐身)标签页:
https://pos.yourdomain.com
-
带锁的登录页面 → 已上线。
-
Coolify 错误 / 502 → 故障排除:
- 检查后端健康状态:
https://api.yourdomain.com/health - 在 Coolify 中查看应用日志(
App → Logs) - 验证环境变量(尤其是
DATABASE_URL)
- 检查后端健康状态:
调试生产环境 意味着阅读日志,而不是
console.log,每一次更改都会触发重新部署。
8️⃣ Security Extras (UFW & Fail2Ban)
- UFW → 在启用防火墙之前配置允许的端口。
- Fail2Ban → 阻止重复的恶意尝试(它的名字字面意思是“让机器人失败直到被封禁”)。
先设置防火墙,然后再安装 Fail2Ban;否则你会把自己锁在外面。
TL;DR 检查清单
- 安装 Coolify(单行命令)
- 运行向导 → 管理员账户
- 创建 PostgreSQL 数据库 → 复制连接字符串
- 部署后端 → 设置环境变量,域名
api.yourdomain.com - 部署前端 → 设置
VITE_API_URL,域名pos.yourdomain.com,添加重写规则 - 添加 DNS A 记录 为
api与pos→ 指向 VPS IP - 验证 SSL(挂锁)和健康检查端点
- 配置 UFW 与 Fail2Ban 以提升安全
您现在拥有一个完全自托管、可投入生产的平台——您在 VPS 上的专属 “Heroku”。 🚀
✅ 服务器设置与部署检查清单
| 步骤 | 描述 |
|---|---|
| 1 | 购买了 VPS(OVHcloud)— Ubuntu 24.04 |
| 2 | 更新了软件包 – apt update && apt upgrade |
| 3 | 配置了 UFW – 默认拒绝,打开端口 22、80、443、3000 |
| 4 | 安装了 Fail2ban – maxretry 5、bantime 1h |
| 5 | 安装了 Coolify v4 – 通过 :3000 访问 |
| 6 | 通过 Coolify 部署了 PostgreSQL |
| 7 | 部署了后端(Node.js / Nixpacks),并设置所需的环境变量 |
| 8 | 部署了前端(React / Vite / 静态),并使用 SPA 重写规则 |
| 9 | 配置了 DNS A 记录(Namecheap) |
| 10 | 通过 Let’s Encrypt 验证了 SSL(Coolify 中自动完成) |
| 11 | 测试了线上端点 |
结果: 从空白服务器到上线应用,整个过程只用一天。这不是魔法——只是在于了解操作顺序。