Skip to main content

建立 Hugo + code-server + GitHub 自動 Deploy

雖然有八九成都係 Gemini 教嘅,不過都寫個筆記記低先。


Raspberry Pi 部署 code-server + Hugo 作開發環境

首先用 docker 建立一個 code-server 並預先安裝好 Hugo。Cloudflare Tunnel 請按需要加入。

 1services:
 2 # code-server IDE
 3 ide:
 4   build: .
 5   container_name: hugo-ide
 6   environment:
 7     - PUID=1000
 8     - PGID=1000
 9     - TZ=Asia/Hong_Kong
10     - PASSWORD=your_ide_login_password
11     - SUDO_PASSWORD=your_root_password
12   volumes:
13     - ./config:/config
14     - ./project:/config/workspace
15   ports:
16     - 10443:8443       # 映射 container port 8443 到 宿主機的 port 10443
17   restart: unless-stopped
18
19 # Preview 用 webserver (Nginx)
20 preview:
21   image: nginx:alpine
22   container_name: hugo-preview
23   volumes:
24     - ./project/my-site/public:/usr/share/nginx/html:ro # <<-- Preview 用的 Hugo output 存放處
25   ports:
26     - 10080:80       # 映射 container port 80 到 宿主機的 port 10080
27   restart: unless-stopped
28
29 # Couldflare Tunnel
30 tunnel:
31   image: cloudflare/cloudflared:latest
32   container_name: cloudflare-tunnel
33   command: tunnel --no-autoupdate run --token your_token_string
34   restart: unless-stopped
 1 # 階段 1: 借用官方 Hugo Extended 執行檔
 2 FROM klakegg/hugo:ext-alpine AS hugo-provider
 3 
 4 # 階段 2: 建立你的 Code-Server (雲端 IDE)
 5 FROM linuxserver/code-server:latest
 6 
 7 
 8 # 自動偵測架構並安裝最新版 Hugo Extended
 9 RUN apt-get update && apt-get install -y wget curl jq && \
10     # 1. 攞最新版號
11     LATEST_HUGO=$(curl -s https://api.github.com/repos/gohugoio/hugo/releases/latest | jq -r '.tag_name' | sed 's/v//') && \
12     # 2. 偵測系統架構 (Pi 4/5 通常係 arm64)
13     ARCH=$(dpkg --print-architecture) && \
14     if [ "$ARCH" = "arm64" ]; then HUGO_ARCH="arm64"; else HUGO_ARCH="arm"; fi && \
15     # 3. 下載對應的 .deb 檔
16     wget "https://github.com/gohugoio/hugo/releases/download/v${LATEST_HUGO}/hugo_extended_${LATEST_HUGO}_linux-${HUGO_ARCH}.deb>
17     # 4. 安裝
18     dpkg -i "hugo_extended_${LATEST_HUGO}_linux-${HUGO_ARCH}.deb" && \
19     rm "hugo_extended_${LATEST_HUGO}_linux-${HUGO_ARCH}.deb" && \
20     apt-get clean
21 
22 
23 # Install GIT
24 RUN apt-get install -y git && apt-get clean
25 WORKDIR /config/workspace

執行 docker compose 建立 image

docker compose up -d --build

Lightsail 建立 Webhosting 環境

同樣使用 docker compose 建一個有幾個 webhosting server 嘅 container,加上 NPM 做分流

 1services:
 2  # 核心:流量分流與 SSL 管理
 3  npm:
 4    image: 'jc21/nginx-proxy-manager:latest'
 5    restart: always
 6    ports:
 7      - '80:80'
 8      - '81:81'
 9      - '443:443'
10    volumes:
11      - ./npm/data:/data
12      - ./npm/letsencrypt:/etc/letsencrypt
13
14  # 網站 1: Landing Page (www)
15  landing-site:
16    image: nginx:alpine
17    restart: always
18    volumes:
19      - ./html/landing:/usr/share/nginx/html
20
21  # 網站 2: Hugo Blog (blog)
22  blog-site:
23    image: nginx:alpine
24    restart: always
25    volumes:
26      - ./html/blog:/usr/share/nginx/html
27
28  # 網站 3: App Portfolio (myjob)
29  job-site:
30    image: nginx:alpine
31    restart: always
32    volumes:
33      - ./html/job:/usr/share/nginx/html

執行 docker compose 建立 image

docker compose up -d

GitHub 自動 deploy

1. 建立 Workflow

喺你嘅 project folder 開一檔案 .github/workflows/deploy.yml,加入以下內容:

 1name: Deploy to Lightsail
 2
 3on:
 4  push:
 5    branches: [ main ] # 當你 push 去 main branch 嗰陣觸發
 6
 7jobs:
 8  build-and-deploy:
 9    runs-on: ubuntu-latest
10    steps:
11      - name: Checkout code
12        uses: actions/checkout@v4
13        with:
14          submodules: recursive
15
16      - name: Setup Hugo
17        uses: peaceiris/actions-hugo@v3
18        with:
19          hugo-version: 'latest'
20          extended: true
21
22      - name: Build Website
23        run: hugo --minify
24
25      - name: Deploy to Lightsail
26        uses: easingthemes/ssh-deploy@main
27        with:
28          SSH_PRIVATE_KEY: ${{ secrets.LIGHTSAIL_SSH_KEY }}
29          REMOTE_HOST: ${{ secrets.LIGHTSAIL_IP }}
30          REMOTE_USER: ubuntu
31          # 呢度填你 Lightsail 嗰面 Webstack 讀取網頁檔案嘅 Folder 路徑
32          TARGET: /home/ubuntu/webstack/sites/my-hugo-site/
33          SOURCE: "public/"

2. GitHub 設定 Secrets

為咗令 GitHub Actions 可以入到你部 Lightsail,你要去 GitHub Repo 嘅 Settings -> Secrets and variables -> Actions,加下面呢幾粒「掣」:

LIGHTSAIL_IP: 你的 Lightsail Static IP。

LIGHTSAIL_SSH_KEY: 呢個係 Lightsail 嗰粒 .pem 檔 嘅內容。
(如果你冇咗 .pem,好可能要重新 gen 過新 key,因為個 file 應該只會出現一次。)

LIGHTSAIL_USERNAME: 通常係 ubuntu。


實際運作

呢度有兩種方式:

  1. 經 Cloudflare Access
  2. 利用 VSCode

1. 經 Cloudflare Access

首先 Container 要有裝 Cloudflare Tunnel,然後到 Cloudflare 嘅 connector 入面,加返兩個 published application,service set 去 container 嘅 port:

my-cloud-ide.xxx.com -> http://ide:8443

my-cloud-ide-preview.xxx.com -> http://ide:1313

之後用 browser 去 my-cloud-ide.xxx.com,輸入返 docker-compose 入面嘅 password 就可以入到去。

2. 利用 VS Code Remote

呢度又有兩個連線情況:

  1. 經 Cloudflare Tunnel
  1. 直接連線

雖然最初我嘅諗法係直接進入 container 入面,但係試左好耐都解決唔到連線問題,AI 話係 port 問題,最後解決方法都係佢話係最常用嘅方法,就係先用 VSCode SSH 連接宿主機,再用 VSCode 嘅 Attach to container 功能。


1. 經 Cloudflare Tunnel

首先要係 client 機 download Cloudflared,放到一個位置,例如 C:\bin\Cloudflared.exe。然後到 C:\Users\[UserName]\.ssh\ 搵個叫 config 嘅 file。如果冇呢個 folder 或者 file 就手動建立出黎。config file 內容如下:

Host my-cloud-ssh.yourdomain.com
    ProxyCommand C:\bin\Cloudflared.exe access ssh --hostname %h
    User 你的家中電腦用戶名

返回 VSCode,噤左下角嘅 >< (Connect to host),上邊條 textbox 彈出黎問你用咩 connect,揀 SSH,再揀你個 host。之後入 password,OK 之後左下會幾到 SSH: your-host

成功連線後,可以再噤一下下角嘅 SSH: your-host,揀 Attach to Running Container,然後揀你個 ide container,之後就會連線入去。

但入到去之後係用 root login,如果要同 browser 使用一致,可能要用返 code-server default 嘅 user abc 去登入,要改 VSCode 嘅 config。

噤一下上面個 textbox,揀 Show and Run Command,搵 Dev Containers: Open Attached Container Config File,加入新嘅 value:

"remoteUser": "abc"

然後重新連線一次就可以。


2. 直接連線

基本上同上面係差不多,SSH config 改成直接連線到你嘅宿主機:

Host 10.1.123.123
    HostName 10.1.123.123
    User 你的家中電腦用戶名

其他完全一樣。

但係有個位要留意,改 remoteName:abc 後可能會繼續以 root 登入,如果係咁就要喺以 root 身份連線到 container 時,喺 terminal 剷左以下 folder 等佢重新讀取設定: rm -rf ~/.vscode-server

重開 VSCode 再連一次線就 OK。