DevOps / 基礎設施2026

GCP 零成本自架基礎設施

在 GCP 免費方案 e2-micro VM 上以 $0/月運行 6 個生產 Docker 服務,透過 IPv6 專用網路、Cloudflare Tunnel、WARP 代理與 Socat 解決 $3.65/月的 IPv4 費用問題。

GCP 零成本自架基礎設施

專案概述

gcp-free-stack 是一個個人基礎設施專案兼工程日誌,記錄如何在 GCP e2-micro 免費方案上以 $0/月運行多個生產級 Docker 服務。2024 年 GCP 開始對外部 IPv4 地址收費(約 $3.65/月),本專案系統性評估各替代方案(Cloud NAT 要 $4.67/月,反而更貴),最終確立解決方案:IPv6 專用 VM + Cloudflare Tunnel 公開入口 + Cloudflare WARP SOCKS5 代理解決 Docker 拉取映像問題 + Socat TCP 轉發讓容器可存取 WARP 代理 + Cloudflare Worker 作為 IPv4 通知轉發閘道。六個服務——Portainer、Uptime Kuma、Umami(網站分析)、IT-Tools、Homer(服務儀表板)、Dash.(系統監控)——全部在 1 vCPU / 1 GB RAM VM 上以 Docker Compose 運行。

技術挑戰與解決方案

IPv6 專用主機無法拉取 Docker 映像

移除外部 IPv4 地址(消除 $3.65/月費用)後,docker pull 指令失敗,因為 Docker Hub、GHCR 等映像倉庫僅支援 IPv4,VM 無法路由到這些端點。

解決方案:
安裝 Cloudflare WARP 並設定為代理模式(SOCKS5 在 127.0.0.1:4000),而非 VPN 模式。透過 daemon.json 設定 Docker daemon 使用 WARP SOCKS5 代理。使用 Socat(systemd 服務)將 TCP 0.0.0.0:4001 轉發至 127.0.0.1:4000,讓 Docker bridge 網路上的容器也能存取代理。

Uptime Kuma 無法連線監控目標或發送通知

Uptime Kuma 在容器中運行,需要連線 IPv4 監控目標(外部網站)並向 Discord Webhook 發送告警——但這些端點都是 IPv4,VM 沒有直接的 IPv4 出口。

解決方案:
以 network_mode: host 運行 Uptime Kuma,讓它直接使用主機網路堆疊(存取 127.0.0.1:4000 的 WARP 及原生 IPv6)。對於通知 Webhook(Discord 僅支援 IPv4),部署 Cloudflare Worker 接收 Uptime Kuma 透過 IPv6 發送的 Webhook,再轉發至 IPv4 的 Discord 端點。

沒有公開 IP 的 SSH 存取

移除外部 IPv4 地址後,標準 SSH 入口也一併消失——如何在不付費取得公開地址的情況下遠端管理 VM?

解決方案:
使用 GCP Identity-Aware Proxy(IAP)隧道搭配 gcloud compute ssh --tunnel-through-iap。IAP 透過 Google 基礎設施隧道傳輸 SSH 流量,不需要公開 IP 且無額外費用。並撰寫了完整的 macOS gcloud CLI 設定指南。

系統架構

公開入口:Cloudflare Tunnel(cloudflared,QUIC/HTTP2)終止 TLS 並轉發至本地容器埠。VM 網路:GCP 雙棧子網路,僅外部 IPv6(無 IPv4),透過 GCP IAP 隧道 SSH 存取。IPv4 橋接:Cloudflare WARP 代理模式(SOCKS5 :4000)——使用代理模式而非 VPN 模式,避免影響系統路由表。容器代理:Socat systemd 服務(TCP 0.0.0.0:4001 → 127.0.0.1:4000)將 WARP 暴露給 Docker 容器。通知轉發:Cloudflare Worker 將 IPv6 來源的 Webhook 請求代理至 IPv4 的 Discord/Slack 端點。容器:Docker Compose,Uptime Kuma 使用 host 網路模式以獲得原生 IPv6 堆疊和 WARP SOCKS5 存取。OS 調優:針對 1 GB RAM 環境擴大 QUIC 所需的核心 Socket 緩衝區。

學習與心得

這個專案深化了我對雲端網路在基礎設施成本邊界的取捨理解。診斷 docker pull 在 IPv6 專用主機上失敗的原因(映像倉庫僅支援 IPv4),並用 WireGuard 式 SOCKS5 代理解決問題,讓我獲得多層網路橋接的實戰經驗。我也學到 WARP 必須使用代理模式而非 VPN 模式——VPN 模式會修改系統路由表導致 SSH 斷線。使用 Cloudflare Worker 作為無伺服器 IPv4/IPv6 轉換層轉發通知 Webhook,是一個優雅且零成本的架構決策。

技術棧

容器調度

DockerDocker ComposePortainer

網路層

Cloudflare TunnelCloudflare WARPSocatCloudflare Workers

監控與可觀測性

Uptime KumaUmamiDash.

部署

GCP e2-microGCP IAPUbuntusystemd