跳转到主要内容

VPS 安装部署与安全指南

本综合指南涵盖了在通用 VPS(虚拟专用服务器)上部署 InsForge 用于生产环境、使用安全最佳实践加固你的实例,以及通过安全的更新和回滚流程对其进行长期维护。
适用范围:本指南与云服务商无关。它适用于任何 Linux VPS——推荐使用 Ubuntu/Debian——无论提供商是 DigitalOcean、Hetzner、Linode、Vultr、OVH,还是裸机服务器。有关特定云平台的指南(AWS EC2、GCP、Azure、Render),请参阅本节中的其他指南。

📋 目录


前提条件

开始之前,请确保你已具备以下条件:
  • 一台运行 Ubuntu 22.04 LTSUbuntu 24.04 LTS 的 VPS(Debian 12 同样适用)
  • 服务器的 root 或 sudo 权限
  • 一个已注册的域名(生产环境推荐)
  • 对 Linux 命令行和 SSH 有基本了解

第一部分 — 部署

1. 服务器要求

ResourceMinimumRecommended
CPU2 vCPU4 vCPU
RAM2 GB4 GB+
Storage20 GB SSD40 GB+ SSD
OSUbuntu 22.04+Ubuntu 24.04 LTS
NetworkPublic IPv4Public IPv4 + IPv6
💡 提示:对于有多用户的生产环境负载,建议从 4 GB 内存起步。使用 docker stats 监控使用情况,并根据需要进行垂直扩容。
InsForge 由以下 4 个协同运行的服务组成:
ServiceDescriptionInternal Port
PostgreSQLPrimary database5432
PostgRESTAuto-generated REST API layer3000 (mapped to 5430)
InsForgeNode.js backend + dashboard7130
DenoServerless functions runtime7133

2. 初始服务器设置

2.1 连接到你的 VPS

2.2 更新系统软件包

2.3 创建部署用户(非 root)

切勿以 root 身份运行生产服务。创建一个专用用户:

2.4 设置时区

2.5 启用自动安全更新


3. 安装 Docker 和 Docker Compose

3.1 安装 Docker 引擎

3.2 将部署用户添加到 Docker 组

3.3 验证 Docker 安装

⚠️ 安全提示:将用户添加到 docker 组会授予其在主机上等同于 root 的权限。对于专用的部署用户这是可以接受的,但不应对共享服务器上的通用账户这样做。

4. 使用 Docker Compose 部署 InsForge

4.1 下载生产环境的 Docker Compose 文件

4.2 启动 InsForge

4.3 验证所有服务是否正在运行

你应该会看到 4 个容器处于 runninghealthy 状态:

4.4 测试健康检查端点

预期响应:

5. 环境变量配置

编辑你的 .env 文件,为生产环境配置 InsForge:

5.1 必需变量

在投入生产之前,以下变量必须从默认值修改:
直接从终端生成安全的密钥:
⚠️ 重要JWT_SECRETENCRYPTION_KEY 应该使用不同的值。如果未设置 ENCRYPTION_KEY,InsForge 会回退使用 JWT_SECRET——但之后再轮换 JWT_SECRET 会永久性地损坏所有已存储的密钥(API 密钥、OAuth 令牌等)。

5.2 数据库变量

5.3 端口变量

InsForge 使用的默认端口:
💡 如果这些端口与你 VPS 上的其他服务冲突,可以修改它们。

5.4 部署功能所需变量

以下变量仅在你计划使用 InsForge 的部署功能(通过控制台部署项目)时才需要。如果你不需要部署功能,可以跳过本节。
⚠️ 注意:这些变量(AWS_S3_BUCKETAWS_REGIONAWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYPROJECT_IDMAX_FILE_SIZE)来自根目录下的 .env.example 设置。它们存在于 deploy/docker-compose/.env.example 中,并且 deploy/docker-compose/docker-compose.yml不会将它们传递给 insforge 容器,因此在你的 .env 中设置它们对该生产环境 compose 文件没有任何效果。要使用它们,请将每一个都添加到你 docker-compose.ymlinsforge 服务的 environment 块内。

5.5 可选变量

编辑完成后,重启服务以应用更改:

6. 反向代理设置

反向代理位于 InsForge 前面,负责 TLS 终止、HTTP/2,并提供不带端口号的干净 URL。

方案 A:Nginx(推荐)

6.1 安装 Nginx
6.2 创建站点配置
粘贴以下配置——将 insforge.yourdomain.com 替换为你的实际域名:
6.3 启用该站点

方案 B:Caddy(自动 HTTPS)

Caddy 是一个更简单的替代方案,可以自动处理 TLS 证书。
安装 Caddy
配置 Caddy
Caddy 会自动获取并续期 Let’s Encrypt 证书——无需额外操作。

7. HTTPS / TLS 设置

如果你在第 6 步中选择了 Caddy,TLS 已经自动处理完毕。请直接跳转到第二部分

7.1 安装 Certbot(用于 Nginx)

7.2 获取 SSL 证书

按照交互式提示操作。Certbot 将会:
  1. 通过 HTTP 质询验证域名所有权
  2. 从 Let’s Encrypt 获取签名证书
  3. 自动更新你的 Nginx 配置以提供 HTTPS 服务
  4. 设置 HTTP → HTTPS 重定向

7.3 验证自动续期

Let’s Encrypt 证书每 90 天过期一次。Certbot 会安装一个用于自动续期的 systemd 定时器:

7.4 为 HTTPS 更新 InsForge 环境变量

获取证书后,更新你的 .env 以使用 HTTPS 网址:
重启 InsForge 以应用更改:

第二部分 — 安全

8. 端口管理

应对外开放的端口(通过反向代理)

PortProtocolPurpose
22TCPSSH (restrict source IP)
80TCPHTTP → HTTPS redirect
443TCPHTTPS (reverse proxy)

应对公众关闭的端口

以下端口用于 Docker 内部服务间通信,绝不应暴露给公网:
PortServiceWhy Close It
5432PostgreSQLDirect DB access — use docker exec instead
5430PostgRESTInternal REST layer — proxied through InsForge
7130InsForgeAPI + dashboard, accessed via reverse proxy on 443, not directly
7131(unused)Published by compose (AUTH_PORT), but no process listens on it
7133DenoInternal serverless runtime
⚠️ 关键:默认的 docker-compose.yml 将端口绑定到 0.0.0.0(所有接口),而非 127.0.0.1。这意味着 Docker 会将服务直接暴露给互联网,完全绕过 UFW(Docker 直接操作 iptables)。你必须docker-compose.yml 中每一个发布的端口添加 127.0.0.1: 前缀:
如果没有这个前缀,互联网上的任何人都可以直接访问这些服务——包括使用默认凭据的 PostgreSQL。详情请参见第 9.2 节

9. 防火墙设置(UFW)

UFW(Uncomplicated Firewall)是在 Ubuntu 上管理 iptables 最简单的方式。

9.1 安装和配置 UFW

预期输出:
⚠️ 关键:务必在启用 UFW 之前先允许 SSH,否则你会把自己锁在服务器外面。

9.2 Docker 与 UFW 的注意事项

Docker 会直接操作 iptables,这可能绕过 UFW 规则。要防止这种情况: 方案 1 — 将端口绑定到 localhost(推荐): 在你的 docker-compose.yml 中,为端口加上 127.0.0.1: 前缀:
方案 2 — 禁用 Docker 的 iptables 管理
⚠️ 禁用 Docker 的 iptables 管理需要手动配置网络。对于大多数场景,推荐使用方案 1

9.3 将 SSH 限制到你的 IP(可选)

为了最大程度的安全性,将 SSH 访问限制到已知的 IP 地址:

10. 以非 root 用户运行服务

InsForge 的 Docker 镜像已经遵循了非 root 的最佳实践:
  • 生产环境 Dockerfile 设置了 USER node(UID 1000),因此容器内的应用进程以非 root 用户运行。
  • 系统级的 Docker 操作由 deploy 用户(在第 2.3 步中创建)管理,该用户通过 docker 组获得对 Docker 套接字的访问权限。
验证容器用户:
额外加固: docker-compose.yml 中为每个服务添加 security_opt,以防止权限提升:

11. SSH 加固

11.1 使用 SSH 密钥认证

11.2 禁用密码认证

在确认基于密钥的认证可以正常工作后:
设置以下内容:
重启 SSH:

11.3 安装 Fail2Ban

Fail2Ban 会自动封禁出现恶意行为(例如 SSH 暴力破解)的 IP:
添加或确保存在以下设置:

12. Docker 安全

12.1 保持 Docker 更新

12.2 限制容器资源(可选)

防止单个容器占用全部资源:

12.3 只读根文件系统(进阶)

为了进一步加固,可以将容器文件系统尽可能挂载为只读:
⚠️ 这需要经过测试——某些服务需要可写目录来存放缓存或临时文件。

12.4 限制 CORS 来源

默认情况下,后端允许所有来源。它会将请求的 Origin 请求头原样反射回响应中,并且对于函数代理响应,会设置 Access-Control-Allow-Origin: *。这对本地开发很方便,但对生产环境来说过于宽松。对于生产部署,请将允许的来源限制为你实际提供服务的域名(例如你的控制台和应用域名),这样其他网站就无法向你的 API 发起带凭据的跨域请求。

13. 密钥管理

应做 ✅

  • 将密钥存储在 .env 文件中,并设置 chmod 600 ~/insforge/.env
  • JWT_SECRETENCRYPTION_KEY 使用不同的值
  • 使用 openssl rand -base64 32 生成密钥
  • 将你的 .env 文件备份到安全的离线位置

不应做 ❌

  • .env 提交到版本控制系统
  • 为多个变量重复使用同一个密钥
  • 在生产环境中使用默认密码(change-this-passwordpostgres
  • 通过未加密的渠道分享密钥

第三部分 — 更新与维护

14. 更新前备份

更新前务必先备份。 这样如果出现任何问题,你都有恢复途径。

14.1 备份数据库

14.2 备份环境变量和卷

14.3 记录当前版本


15. 更新 InsForge

15.1 拉取最新镜像

15.2 应用更新

Ctrl+C 停止跟随日志。

15.3 验证更新

15.4 更新 Docker Compose 文件(如有需要)

有时新版本会包含对 docker-compose.yml 的更改。要获取这些更改:

16. 回滚流程

如果更新导致了问题,请按照以下步骤进行回退:

16.1 停止出问题的服务

16.2 恢复之前的 Docker Compose 文件

16.3 固定到指定的镜像版本

编辑 docker-compose.yml,将 latest 标签替换为之前的版本:
注意:目前 deploy/docker-compose 固定使用 v1.5.0,而项目目前已在 2.x 系列。请固定到你更新之前所运行的版本。

16.4 恢复数据库(如有需要)

只有当此次更新包含导致问题的数据库迁移时,才需要恢复数据库:

16.5 恢复环境变量文件(如有更改)


17. 自动化备份

设置一个 cron 任务以进行每日自动备份:

17.1 创建备份脚本

17.2 使用 Cron 设置计划任务

添加以下这一行以每天凌晨 3:00 进行备份:

17.3 异地备份(推荐)

为了灾难恢复,将备份复制到外部位置:

18. 监控与健康检查

18.1 检查服务状态

18.2 查看日志

18.3 健康检查端点

从外部监控健康检查端点。一个简单的基于 cron 的检查:
或者使用像 UptimeRobotBetterstack 这样的免费在线状态监控服务来监控 https://insforge.yourdomain.com/api/health

快速参考

常用命令

安全检查清单

  • 已创建部署用户(非 root)
  • 已启用 SSH 密钥认证
  • 已禁用 SSH 密码认证
  • 已禁用 root 登录
  • 已启用 UFW 防火墙(仅开放 22、80、443 端口)
  • Docker 端口已绑定到 127.0.0.1
  • 已安装并启用 Fail2Ban
  • JWT_SECRET 已从默认值修改(32 位以上)
  • 已设置 ENCRYPTION_KEY(与 JWT_SECRET 不同)
  • ROOT_ADMIN_PASSWORD 已从默认值修改
  • POSTGRES_PASSWORD 已从默认值修改
  • .env 文件权限已设置为 600
  • 已通过 Certbot 或 Caddy 启用 HTTPS
  • 已配置每日自动备份
  • 已启用无人值守的安全更新

故障排查

启用 UFW 后无法连接

如果你被锁在服务器外,请使用你的 VPS 提供商的网页控制台(带外访问)来执行:

Docker 绕过 UFW

Docker 会直接操作 iptables。请按照第 9.2 节中描述的方式,在 docker-compose.yml 中将端口绑定到 127.0.0.1

服务无法启动

SSL 证书无法续期

端口冲突

数据库连接问题


🆘 需要帮助?