在這種架構下,Kamal 會自動幫你跑起一個 Traefik (Kamal 1.x) 或 Kamal Proxy (Kamal 2.x) 的容器,它會充當你的「內建反向代理」。
這是一份針對「無 Nginx 傳統架構,純 Kamal 部署」的部落格教學範本:
🚀 拋棄 Nginx!使用 Kamal 直接在 Ubuntu 部署 Rails 應用
很多人習慣在 Linux 上裝 Nginx,但如果你使用 Kamal,其實你完全可以不需要在主機(Host)安裝 Nginx。Kamal 會自動管理負載平衡與請求轉發。
🏗️ 簡化後的架構
流量路徑:
使用者 (Browser) -> 埠號 80/443 (Ubuntu Host) -> Kamal Proxy / Traefik (Docker) -> Rails App (Container)
1. 純 Kamal 的 deploy.yml 設定
在沒有外部 Nginx 的情況下,Kamal 需要直接接管主機的 80 (HTTP) 與 443 (HTTPS) 埠號。
# config/deploy.yml
service: my-rails-app
image: your-docker-hub-user/my-rails-app
# 伺服器 IP
servers:
web:
hosts:
- 123.123.123.123
labels:
# 如果你使用 Kamal 1 (Traefik),這裡設定網域名稱
traefik.http.routers.my-app.rule: Host(`your-domain.com`)
# 埠號對應
proxy:
# 將主機的 80 埠直接對應到容器
host_port: 80
app_port: 3000
# 如果要跑 HTTPS (Kamal 2 內建支援)
ssl: true
host: your-domain.com
env:
clear:
RAILS_FORCE_SSL: "true" # 強制所有流量走 SSL
RAILS_SERVE_STATIC_FILES: "true" # 讓 Rails 容器處理 CSS/JS
2. 沒了 Nginx,SSL 憑證怎麼辦?
這是大家最擔心的問題。在「無 Nginx」架構下,你有兩個主流方案:
方案 A:使用 Cloudflare (最簡單)
將你的網域託管在 Cloudflare,並開啟「小橘雲」(Proxy)。
-
優點:Cloudflare 幫你處理 SSL,你的伺服器只需要收 80 埠的流量(選 Flexible 模式)或使用 Cloudflare 憑證。
-
做法:在
deploy.yml中只開放 80 埠,所有安全防護交給 Cloudflare。
方案 B:Kamal 2 內建的 Let's Encrypt
如果你使用最新版的 Kamal 2,它內建了自動申請 Let's Encrypt 憑證的功能。
-
做法:在
proxy設定中開啟ssl: true,Kamal 會自動幫你搞定一切,你完全不用進去伺服器敲指令。
3. 常見問題:為什麼直接部署會失敗?
當你不在 Ubuntu 裝 Nginx 時,最常遇到這幾個坑:
問題 可能原因 解決方法 80 埠被佔用 你可能之前裝過 Nginx 且沒關乾淨。sudo systemctl stop nginx 並 sudo systemctl disable nginx。
404 Not Found
Traefik 的 Label 設定錯誤。
檢查 deploy.yml 中的 Host(...) 括號與引號是否正確。
連不上伺服器
Ubuntu 的防火牆 (UFW) 沒開。
sudo ufw allow 80/tcp 與 sudo ufw allow 443/tcp。
看不到靜態檔案
Rails 預設不處理 /public。
確保環境變數 RAILS_SERVE_STATIC_FILES 為 true。
💡 為什麼你該考慮「無 Nginx」部署?
-
環境乾淨:你的 Ubuntu 主機不需要安裝一大堆套件(Nginx, Certbot, etc.),只要有 Docker 就能跑。
-
橫向擴展:當你有兩台伺服器時,Kamal 的設定可以完全複製,不需要去每台伺服器手動設定 Nginx。
-
版本控制:所有的基礎建設設定都在
deploy.yml裡,這就是真正的 Infrastructure as Code (IaC)。
給讀者的建議:
如果你只有「一台」伺服器且要跑「多個」不同的網站,裝一個 Nginx 當總管會比較方便;但如果你這台伺服器是專門為了這份 Rails 專案而生,直接用 Kamal 是最優雅的解法。
這篇針對「無 Nginx」的內容,更貼合 Kamal 的原生設計。