跳轉到主要內容

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,並提供不含連接埠號的簡潔網址。

方案 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 憑證無法續簽

連接埠衝突

資料庫連線問題


🆘 需要協助?