近年來,我非常認同基礎設施即代碼(IaC)的理念,而容器化正是實現這一理念的有效方式。Docker 能夠簡化應用的打包和分發,而 Kubernetes 提供了強大的編排和自動化管理功能,讓部署和運維更具彈性。因此,我嘗試將手頭的服務和專案轉換為 Dockerfile,並部署在 Docker 伺服器或 Kubernetes 環境中。
在自己搭建的部落格中,過去我曾經使用 Google Analytics 來查看流量數據,但實際操作起來仍然相當不方便。因此,經過一段時間的蒐集與分析,我最終選擇了 Umami 這個開源的分析工具來解決這個問題,並決定自行部署。相比 Google Analytics,Umami 提供更簡單的使用介面、完全的數據掌控權,並且對於隱私有更好的保護,這些都是我看重的優勢。
雖然我對 AWS 服務比較熟悉,但在 AWS ECS 上部署 Docker 應用的成本較高。由於目前只是小流量的應用,因此我尋找了性價比更高的替代方案,最終選擇了 Zeabur。
Zeabur 介紹
Zeabur 是一個專為開發者設計的 PaaS(平台即服務),能夠簡化服務部署的流程。相比其他競品如 Render、Railway 和 Fly.io,Zeabur 不僅功能相似,而且由台灣人開發,擁有友好的中文介面,還支援預算提醒功能,讓我不會因為一時不察而刷爆信用卡,對於個人用戶來說非常貼心。
想要正常部署容器應用,Developer Plan (開發者方案)是收費最低的選擇。Zeabur 的每月收費分為兩個部分:訂閱費用和資源用量費用。 對於 Developer Plan,低於訂閱費($5)的資源用量是免費的,超出部分則會收取相應的資源用量費用。
Zeabur 其實還很佛心的,提供一個完全免費的台灣 GCP 服務,不用綁信用卡,裡面的服務會在 24 小時候會刪除。所以可以先試用過,確定這個服務符合你的需求,在付費購買穩定方案。
如果你也想試試,歡迎使用我的 referral code
,你能額外多獲得一個月的 Developer Plan,我也能得到一些 credits。
設置 Zeabur
來到 Zeabur 首頁,我們可以使用 Github 帳號註冊登入。
下面的 Template 是由其他人分享的一鍵部署專案,其中包含 Umami。 雖然可以直接使用,但我希望能更了解其運作方式並進行客製化調整,因此選擇建立新的專案。
決定服務所在的區域
Developer Plan 只能選 AWS 和華為雲,我選擇 AWS 東京區域。
理論上來說,在 AWS 亞洲區域,東京會比香港便宜:
AWS EC2 香港收費
AWS EC2 東京收費
點選後,Zeabur 會提示我們要加入信用卡,跟著引導完成流程即可。
最後,來到 Project 頁面,查看剛剛建立的專案。
研究 Umami 的 Docker Compose
Umami 官方有提供 Docker Compose 檔案,我們來看一下官方的配置檔:
1---2version: '3'3services:4 umami:5 image: ghcr.io/umami-software/umami:postgresql-latest6 ports:7 - "3000:3000"8 environment:9 DATABASE_URL: postgresql://umami:umami@db:5432/umami10 DATABASE_TYPE: postgresql11 APP_SECRET: replace-me-with-a-random-string12 depends_on:13 db:14 condition: service_healthy15 restart: always21 collapsed lines
16 healthcheck:17 test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"]18 interval: 5s19 timeout: 5s20 retries: 521 db:22 image: postgres:15-alpine23 environment:24 POSTGRES_DB: umami25 POSTGRES_USER: umami26 POSTGRES_PASSWORD: umami27 volumes:28 - umami-db-data:/var/lib/postgresql/data29 restart: always30 healthcheck:31 test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]32 interval: 5s33 timeout: 5s34 retries: 535volumes:36 umami-db-data:
官方提供的 Docker Compose 檔案看起來相當簡潔,無需額外指令。然而,由於 Zeabur 目前尚不支援 Docker Compose,我們需要將其拆解成個別服務進行部署。
部署資料庫 (PostgreSQL)
Zeabur 可以快速部署常見的資料庫,我們使用它來部署 PostgreSQL。
點選 Add Service
後,進行以下操作:
在 Networking 頁面中,可以查詢到該服務的公網域名 / IP 以及專案內部的私有域名 / IP。
使用客戶端測試連線:
在 SQL Client 中,創建資料庫:
1-- 建立新資料庫 umami2CREATE DATABASE umami;
依照零信任原則,其實應該設置 Umami 專用使用者,並且限制權限。不過這是我自己用的私人服務,我也會確保任何敏感資料不外流,這裡僅提供設置內容和過程。詳情請見設置 Umami 專用的 PostgreSQL 使用者
部署 Umami
Zeabur 雖然能部署容器,但它並不完全符合 Dockerfile 格式,而是使用一種叫做 prebuild 設定檔。詳情參考 customize-prebuilt。
我們要將 Docker Compose 文件裡的 Umami,改寫成 prebuild 文件,並且適當地修改 PostgreSQL 相關的參數。 下面是我的配置,如果要拿去使用,要記得修改變數數值。
1name = "Umami"2
3[source]4image = "ghcr.io/umami-software/umami:postgresql-latest"5
6[[ports]]7id = "web"8port = 30009type = "HTTP"10
11[env]12DATABASE_URL = { default = "<your-postgresql-connection-string>" }13DATABASE_TYPE = { default = "postgresql" }14APP_SECRET = { default = "<your-app-secret>" }15TRACKER_SCRIPT_NAME = { default = "<your-script-name>" }
設置
TRACKER_SCRIPT_NAME
參數是為了避開 uBlock 等屏蔽軟體誤殺的情況。詳情參考 environment-variables。
在 Networking 頁面中,點擊 Public 以生成域名:
訪問該域名,就能看到 Umami 登入畫面:
配置 Umami
第一次登入,預設帳號密碼為 admin/umami
,登入後記得修改密碼。
進入 Settings -> 網站,新增自己的部落格域名。
點擊 Edit,來到 Tracking code 分頁。
複製下面的 script,貼到部落格的 <head>...</head>
區塊。
到部落格隨便點幾個頁面,來看結果。
自定義域名
來到 Networking,這次我們選擇產生 custom domain。
Zeabur 會給出 DNS 記錄的內容,我們需要到自己的域名管理後台添加進去。
使用 Cloudflare 管理域名時,添加 DNS 記錄時記得關�� DNS Proxy 模式,我們僅需要將流量導到 Zeabur DNS 伺服器,剩下的 DNS 解析由 Zeabur 自行處理。
持久化儲存測試
由 Zeabur 配置的 PostgreSQL,初始化就將 PostgreSQL data 掛載成 volumes。我們可以來測試一下。
將專案內的兩個服務重新啟動。
再次查詢資料庫,內容依然存在。
額外設定
以下的這些設定和操作雖然不是必要的,但能夠大幅提升部署流程的順暢度、系統的可用性以及整體的安全性。建議在有餘力的情況下進行設置。
健康檢查
Zeabur 也提供健康檢查功能,類似 AWS Target group。然而,它不像 Docker 允許使用 CMD-SHELL
自定義檢查指令,這點稍嫌不足。
設置 Umami 專用的 PostgreSQL 使用者
使用 SQL 客戶端連線到 PostgreSQL 後,執行以下指令:
1-- 建立使用者2CREATE USER umami WITH PASSWORD '<your_password>';3
4-- 賦予使用者操作特定資料庫的權限5---- 賦予資料庫的連線權限:6GRANT CONNECT ON DATABASE umami TO umami;7---- 賦予 public schema 的使用權限:8GRANT USAGE ON SCHEMA public TO umami;9---- 賦予該使用者對表的讀寫權限:10GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO umami;11---- 確保未來新建的表自動繼承權限:12ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO umami;13
14-- 限制使用者只能操作該資料庫15REVOKE ALL ON DATABASE postgres FROM umami;6 collapsed lines
16REVOKE ALL ON DATABASE template1 FROM umami;17
18-- 查看 umami 使用者的詳細權限:19SELECT grantee, privilege_type, table_schema, table_name20FROM information_schema.role_table_grants21WHERE grantee = 'umami';
在 Umami 的 prebuild 設定中,將環境變數 DATABASE_URL 的連線字串更新為新建立的使用者帳號密碼。完成設定後,重新啟動服務即可讓新的資料庫權限設定生效。
備份資料庫
Zeabur 提供備份功能,但目前僅在資料庫服務中看到這個選項。我希望未來能增加 volumes 的匯出功能,期待官方能實現這個特性。
來到 PostgreSQL -> Backup 頁面,點擊 Backup。
下載備份檔並查看內容:
可以看到這是 SQL 的 dump 檔案。
除了可以手動備份外,也能設定每天定時備份。這樣我們就有了簡易的災難恢復機制。
製作模板
Zeabur 雖然不支援 Docker Compose 檔案,但其提供的 template 功能可以達到類似的效果。
我們可以到 Project Settings -> General 頁面,匯出該專案的 template 檔案。
在 Zeabur 的專案設定中,我們可以自訂服務的圖示和說明文字(參考上面建立的 PostgreSQL Overview 頁面)。之後,也能透過 Zeabur CLI 來部署、發布和更新自定義的模板。
不過可惜的是,Zeabur 沒有提供 private template,而 template 會儲存參數的實際數值。因此,如果想將發布的 template 作為私人使用,需要記得在部署完後修改 token 或密碼,否則可能造成嚴重的資安漏洞。
設定預算
如果想要避免超收費用,可以到 Project Settings -> Budget 設定每月預算。
不過要注意,超出預算後,專案就會被暫停。所以重要服務放在這裡時,預算的上限應設大一些。
總結
總體而言,Zeabur 的使用體驗與我的預期略有落差,起初我以為可以直接運用 Kubernetes manifest 或 Docker Compose 檔案進行部署,但考量到成本因素,我還是願意接受一些便利性上的妥協。
之後會再花點時間,把評論系統也搞起來,部署到 Zeabur 上。
謝謝你看到這裡,我們下次見。