VPS 安裝部署與安全指南
本份完整指南涵蓋在通用 VPS(虛擬專用伺服器)上部署 InsForge 以供正式環境使用、以安全最佳實務強化你的伺服器,以及透過安全的更新與回復流程長期維護。適用範圍:本指南與雲端服務商無關,適用於任何 Linux VPS——建議使用 Ubuntu/Debian——不論提供商是 DigitalOcean、Hetzner、Linode、Vultr、OVH,或是裸機伺服器。如需特定雲端平台的指南(AWS EC2、GCP、Azure、Render),請參閱本節中的其他指南。
📋 目錄
先決條件
開始之前,請確認你已具備以下條件:- 一台執行 Ubuntu 22.04 LTS 或 Ubuntu 24.04 LTS 的 VPS(Debian 12 同樣適用)
- 伺服器的 root 或 sudo 權限
- 一個已註冊的網域名稱(建議用於正式環境)
- 對 Linux 命令列與 SSH 有基本了解
第一部分 — 部署
1. 伺服器需求
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU |
| RAM | 2 GB | 4 GB+ |
| Storage | 20 GB SSD | 40 GB+ SSD |
| OS | Ubuntu 22.04+ | Ubuntu 24.04 LTS |
| Network | Public IPv4 | Public IPv4 + IPv6 |
💡 提示:若正式環境有多位使用者,建議從 4 GB 記憶體開始。使用 docker stats 監控用量,並依需求進行垂直擴充。
InsForge 由以下 4 項協同運作的服務組成:
| Service | Description | Internal Port |
|---|---|---|
| PostgreSQL | Primary database | 5432 |
| PostgREST | Auto-generated REST API layer | 3000 (mapped to 5430) |
| InsForge | Node.js backend + dashboard | 7130 |
| Deno | Serverless functions runtime | 7133 |
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 驗證所有服務皆正常運作
running 或 healthy 狀態:
4.4 測試健康檢查端點
5. 環境變數設定
編輯你的.env 檔案,為正式環境設定 InsForge:
5.1 必要變數
在上線正式環境之前,以下變數必須從預設值修改:⚠️ 重要:JWT_SECRET與ENCRYPTION_KEY應使用不同的值。若未設定ENCRYPTION_KEY,InsForge 會退回使用JWT_SECRET——但之後若再輪替JWT_SECRET,將會永久性地損毀所有已儲存的密鑰(API 金鑰、OAuth 權杖等)。
5.2 資料庫變數
5.3 連接埠變數
InsForge 使用的預設連接埠:💡 若這些連接埠與你 VPS 上其他服務衝突,可以自行修改。
5.4 部署功能所需的變數
以下變數僅在你打算使用 InsForge 的部署功能(透過控制台部署專案)時才需要設定。若你不需要部署功能,可以跳過本節。⚠️ 注意:這些變數(AWS_S3_BUCKET、AWS_REGION、AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY、PROJECT_ID、MAX_FILE_SIZE)來自根目錄下的.env.example設定。它們並不存在於deploy/docker-compose/.env.example中,而deploy/docker-compose/docker-compose.yml也不會將它們傳遞給insforge容器,因此在你的.env中設定它們,對此正式環境 compose 檔案不會有任何作用。若要使用它們,請將每一項加入你docker-compose.yml中insforge服務的environment區塊。
5.5 選用變數
6. 反向代理設定
反向代理位於 InsForge 之前,負責 TLS 終止、HTTP/2,並提供不含連接埠號的簡潔網址。方案 A:Nginx(建議)
6.1 安裝 Nginx
6.2 建立站台設定
insforge.yourdomain.com 替換為你實際的網域:
6.3 啟用該站台
方案 B:Caddy(自動 HTTPS)
Caddy 是更簡單的替代方案,能自動處理 TLS 憑證。安裝 Caddy
設定 Caddy
7. HTTPS / TLS 設定
若你在第 6 步選擇了 Caddy,TLS 已自動處理完畢,請直接跳至第二部分。
7.1 安裝 Certbot(適用於 Nginx)
7.2 取得 SSL 憑證
- 透過 HTTP 挑戰驗證網域擁有權
- 從 Let’s Encrypt 取得已簽署的憑證
- 自動更新你的 Nginx 設定以提供 HTTPS 服務
- 設定 HTTP → HTTPS 重新導向
7.3 驗證自動續簽
Let’s Encrypt 憑證每 90 天到期一次。Certbot 會安裝一個用於自動續簽的 systemd 計時器:7.4 為 HTTPS 更新 InsForge 環境設定
取得憑證後,更新你的.env 以使用 HTTPS 網址:
第二部分 — 安全
8. 連接埠管理
應對外開放的連接埠(透過反向代理)
| Port | Protocol | Purpose |
|---|---|---|
| 22 | TCP | SSH (restrict source IP) |
| 80 | TCP | HTTP → HTTPS redirect |
| 443 | TCP | HTTPS (reverse proxy) |
應對外部關閉的連接埠
以下連接埠僅用於 Docker 內部服務間通訊,絕不應對外公開:| Port | Service | Why Close It |
|---|---|---|
| 5432 | PostgreSQL | Direct DB access — use docker exec instead |
| 5430 | PostgREST | Internal REST layer — proxied through InsForge |
| 7130 | InsForge | API + dashboard, accessed via reverse proxy on 443, not directly |
| 7131 | (unused) | Published by compose (AUTH_PORT), but no process listens on it |
| 7133 | Deno | Internal 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: 前綴:
⚠️ 停用 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 停用密碼驗證
在確認以金鑰為基礎的驗證運作正常後: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_SECRET與ENCRYPTION_KEY使用不同的值 - 使用
openssl rand -base64 32產生密鑰 - 將你的
.env檔案備份至安全的離線位置
不應做 ❌
- 將
.env提交至版本控制系統 - 讓多個變數重複使用同一組密鑰
- 在正式環境中使用預設密碼(
change-this-password、postgres) - 透過未加密的管道分享密鑰
第三部分 — 更新與維護
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 排程
17.3 異地備份(建議)
為了災難復原,請將備份複製到外部位置:18. 監控與健康檢查
18.1 檢查服務狀態
18.2 檢視日誌
18.3 健康檢查端點
從外部監控健康檢查端點。以下是一個簡單的 cron 檢查: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 憑證無法續簽
連接埠衝突
資料庫連線問題
🆘 需要協助?
- 文件:https://docs.insforge.dev
- Discord 社群:https://discord.com/invite/MPxwj5xVvW
- GitHub Issues:https://github.com/insforge/insforge/issues