Vinc3nt's Life

使用 Zeabur 部署 Umami 分析工具:從 Docker Compose 到 PaaS 的實作經驗

2024-12-04
develop
blog
zeabur
umami
docker
docker-compose
paas
iac
postgresql
最後更新:2025-01-26
12分鐘
2378字

近年來,我非常認同基礎設施即代碼(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。

default

設置 Zeabur

來到 Zeabur 首頁,我們可以使用 Github 帳號註冊登入。

default

下面的 Template 是由其他人分享的一鍵部署專案,其中包含 Umami。 雖然可以直接使用,但我希望能更了解其運作方式並進行客製化調整,因此選擇建立新的專案。

default

決定服務所在的區域

default

Developer Plan 只能選 AWS 和華為雲,我選擇 AWS 東京區域。

理論上來說,在 AWS 亞洲區域,東京會比香港便宜:

default AWS EC2 香港收費

default AWS EC2 東京收費

點選後,Zeabur 會提示我們要加入信用卡,跟著引導完成流程即可。

最後,來到 Project 頁面,查看剛剛建立的專案。

default

研究 Umami 的 Docker Compose

Umami 官方有提供 Docker Compose 檔案,我們來看一下官方的配置檔

1
---
2
version: '3'
3
services:
4
umami:
5
image: ghcr.io/umami-software/umami:postgresql-latest
6
ports:
7
- "3000:3000"
8
environment:
9
DATABASE_URL: postgresql://umami:umami@db:5432/umami
10
DATABASE_TYPE: postgresql
11
APP_SECRET: replace-me-with-a-random-string
12
depends_on:
13
db:
14
condition: service_healthy
15
restart: always
21 collapsed lines
16
healthcheck:
17
test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"]
18
interval: 5s
19
timeout: 5s
20
retries: 5
21
db:
22
image: postgres:15-alpine
23
environment:
24
POSTGRES_DB: umami
25
POSTGRES_USER: umami
26
POSTGRES_PASSWORD: umami
27
volumes:
28
- umami-db-data:/var/lib/postgresql/data
29
restart: always
30
healthcheck:
31
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
32
interval: 5s
33
timeout: 5s
34
retries: 5
35
volumes:
36
umami-db-data:

官方提供的 Docker Compose 檔案看起來相當簡潔,無需額外指令。然而,由於 Zeabur 目前尚不支援 Docker Compose,我們需要將其拆解成個別服務進行部署。

部署資料庫 (PostgreSQL)

Zeabur 可以快速部署常見的資料庫,我們使用它來部署 PostgreSQL。

點選 Add Service 後,進行以下操作:

default

default

default

在 Networking 頁面中,可以查詢到該服務的公網域名 / IP 以及專案內部的私有域名 / IP。

default

使用客戶端測試連線:

default

在 SQL Client 中,創建資料庫:

1
-- 建立新資料庫 umami
2
CREATE DATABASE umami;

依照零信任原則,其實應該設置 Umami 專用使用者,並且限制權限。不過這是我自己用的私人服務,我也會確保任何敏感資料不外流,這裡僅提供設置內容和過程。詳情請見設置 Umami 專用的 PostgreSQL 使用者

部署 Umami

Zeabur 雖然能部署容器,但它並不完全符合 Dockerfile 格式,而是使用一種叫做 prebuild 設定檔。詳情參考 customize-prebuilt

我們要將 Docker Compose 文件裡的 Umami,改寫成 prebuild 文件,並且適當地修改 PostgreSQL 相關的參數。 下面是我的配置,如果要拿去使用,要記得修改變數數值。

1
name = "Umami"
2
3
[source]
4
image = "ghcr.io/umami-software/umami:postgresql-latest"
5
6
[[ports]]
7
id = "web"
8
port = 3000
9
type = "HTTP"
10
11
[env]
12
DATABASE_URL = { default = "<your-postgresql-connection-string>" }
13
DATABASE_TYPE = { default = "postgresql" }
14
APP_SECRET = { default = "<your-app-secret>" }
15
TRACKER_SCRIPT_NAME = { default = "<your-script-name>" }

設置 TRACKER_SCRIPT_NAME 參數是為了避開 uBlock 等屏蔽軟體誤殺的情況。詳情參考 environment-variables

在 Networking 頁面中,點擊 Public 以生成域名:

default

訪問該域名,就能看到 Umami 登入畫面:

default

配置 Umami

第一次登入,預設帳號密碼為 admin/umami,登入後記得修改密碼。

進入 Settings -> 網站,新增自己的部落格域名。

點擊 Edit,來到 Tracking code 分頁。

default

複製下面的 script,貼到部落格的 <head>...</head> 區塊。

default

到部落格隨便點幾個頁面,來看結果。

default

自定義域名

來到 Networking,這次我們選擇產生 custom domain。

default

Zeabur 會給出 DNS 記錄的內容,我們需要到自己的域名管理後台添加進去。

default

使用 Cloudflare 管理域名時,添加 DNS 記錄時記得關�� DNS Proxy 模式,我們僅需要將流量導到 Zeabur DNS 伺服器,剩下的 DNS 解析由 Zeabur 自行處理。

持久化儲存測試

由 Zeabur 配置的 PostgreSQL,初始化就將 PostgreSQL data 掛載成 volumes。我們可以來測試一下。

default

將專案內的兩個服務重新啟動。

default

再次查詢資料庫,內容依然存在。

default

額外設定

以下的這些設定和操作雖然不是必要的,但能夠大幅提升部署流程的順暢度、系統的可用性以及整體的安全性。建議在有餘力的情況下進行設置。

健康檢查

Zeabur 也提供健康檢查功能,類似 AWS Target group。然而,它不像 Docker 允許使用 CMD-SHELL 自定義檢查指令,這點稍嫌不足。

default

設置 Umami 專用的 PostgreSQL 使用者

使用 SQL 客戶端連線到 PostgreSQL 後,執行以下指令:

1
-- 建立使用者
2
CREATE USER umami WITH PASSWORD '<your_password>';
3
4
-- 賦予使用者操作特定資料庫的權限
5
---- 賦予資料庫的連線權限:
6
GRANT CONNECT ON DATABASE umami TO umami;
7
---- 賦予 public schema 的使用權限:
8
GRANT USAGE ON SCHEMA public TO umami;
9
---- 賦予該使用者對表的讀寫權限:
10
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO umami;
11
---- 確保未來新建的表自動繼承權限:
12
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO umami;
13
14
-- 限制使用者只能操作該資料庫
15
REVOKE ALL ON DATABASE postgres FROM umami;
6 collapsed lines
16
REVOKE ALL ON DATABASE template1 FROM umami;
17
18
-- 查看 umami 使用者的詳細權限:
19
SELECT grantee, privilege_type, table_schema, table_name
20
FROM information_schema.role_table_grants
21
WHERE grantee = 'umami';

在 Umami 的 prebuild 設定中,將環境變數 DATABASE_URL 的連線字串更新為新建立的使用者帳號密碼。完成設定後,重新啟動服務即可讓新的資料庫權限設定生效。

備份資料庫

Zeabur 提供備份功能,但目前僅在資料庫服務中看到這個選項。我希望未來能增加 volumes 的匯出功能,期待官方能實現這個特性。

來到 PostgreSQL -> Backup 頁面,點擊 Backup。

default

下載備份檔並查看內容:

default

可以看到這是 SQL 的 dump 檔案。

除了可以手動備份外,也能設定每天定時備份。這樣我們就有了簡易的災難恢復機制。

製作模板

Zeabur 雖然不支援 Docker Compose 檔案,但其提供的 template 功能可以達到類似的效果。

我們可以到 Project Settings -> General 頁面,匯出該專案的 template 檔案。

default

在 Zeabur 的專案設定中,我們可以自訂服務的圖示和說明文字(參考上面建立的 PostgreSQL Overview 頁面)。之後,也能透過 Zeabur CLI 來部署、發布和更新自定義的模板。

不過可惜的是,Zeabur 沒有提供 private template,而 template 會儲存參數的實際數值。因此,如果想將發布的 template 作為私人使用,需要記得在部署完後修改 token 或密碼,否則可能造成嚴重的資安漏洞。

設定預算

如果想要避免超收費用,可以到 Project Settings -> Budget 設定每月預算。

default

不過要注意,超出預算後,專案就會被暫停。所以重要服務放在這裡時,預算的上限應設大一些。

總結

總體而言,Zeabur 的使用體驗與我的預期略有落差,起初我以為可以直接運用 Kubernetes manifest 或 Docker Compose 檔案進行部署,但考量到成本因素,我還是願意接受一些便利性上的妥協。

之後會再花點時間,把評論系統也搞起來,部署到 Zeabur 上。

謝謝你看到這裡,我們下次見。

參考

本文標題:使用 Zeabur 部署 Umami 分析工具:從 Docker Compose 到 PaaS 的實作經驗
文章作者:Vincent Lin
發布時間:2024-12-04