跳至內容
把 Hugo 網站架設到 Codeberg 吧!

把 Hugo 網站架設到 Codeberg 吧!

October 25, 2026

Note

這篇沒有要教怎麼安裝 Git 和 Hugo,詳細內容可以參考 JN 大大的部落格架設教學系列 和 Ivon 大大的 Hugo + GitHub + Netlify 架設教學。

如果你是要部署到 GitHub 上,請直接過去看他們的內容,不用回頭了(?);如果你是要部署到 Codeberg 上,請在設定完 Hugo(或其他網頁生成器)和 Git 後再回來繼續喔!

這篇也已經同步到筆記區了喔!

前言

要公開一個網站,需要一臺可以長時間開機,而且能讓別人連入的電腦。部落格也需要一個可以讓別人連入的電腦,但如果你沒有辦法這樣做,這時候就需要靠別人的電腦來幫你,你可以:

  • 租一台雲端電腦,把部落格架在上面
  • 用 GitHub 或其他類似平台部署部落格

但我沒有錢,所以需要把網站部署在平臺上,所以我會選擇第二種方法。

但我要求有點多(?),因為 GitHub 開始把程式碼拿去當 AI 的訓練資料,如果我把部落格架在 GitHub 的話,我在部落格上的所有東西都會被當成訓練資料,我還不想變成 AI 的一部分!所以,有一個跟 GitHub 反著走的程式碼託管平臺,叫做 Codeberg。

Codeberg 是位於德國,由非營利組織 Codeberg e.V 架設的平臺,詳細的歷史請在 Wikipedia 上了解,這裡就不多提了。

好了,廢話講完了,該開始講解怎麼部署部落格到 Codeberg 了。

Codeberg 網頁部署有兩種方式,一種是直接上傳網頁檔案,另外一種是上傳部落格原始碼,後續用 Forgejo Action 建置網頁。

這次教的是用原始碼部署,個人不太建議上傳 html 檔,因為後續管理可能會有點麻煩,不過還是看自己狀況決定啦 :3

正片開始

首先,當然要先到 Codeberg 註冊帳號啦!

先到 Codeberg.org 右上的 Register 註冊帳號。如果看不懂英文,網頁底下也能換語言,但翻譯好像做得不是很完全就是了。

開 repo

登入之後,按右上的加號,建立 New repository。

輸入 Repository name,其他都不用動,直接按 Create repository 就好了。

名稱隨便打就好了,只要不要跟其他 repo 名字重複就好。

然後就有新的空 repo 囉!

推上去!

在你要推的資料夾,開終端機貼上指令,啟動 git:

git init

接著貼上 Codeberg 那邊 “Pushing an existing repository from the command line” 給的指令:

git remote add origin "repo 網址"
git push -u origin main

然後依照指示輸入 Codeberg 的帳號和密碼(密碼不會顯示),按下 enter 後就讓它上傳啦!

上傳完就會長這樣:

回去 repo 頁面,重新整理就會看到有東西在上面了。

設定部署

欸等等,不是上傳完就結束了!Codeberg 不知道你上傳這些東西之後要幹嘛,接下來要去設定部署網頁。

Tip

這步其實可以在上傳之前完成,不過為了方便說明,就分開處理啦!

這次是要設定自動部署,接下來要設定 workflow 給 Forgejo Action。

Workflow 有點像是個給電腦看的 to-do list 或食譜,告訴他下一步應該做什麼。

所以,在部落格的根目錄執行指令:

micro .forgejo/workflows/hugo.yaml

(我習慣用 micro 當純文字編輯器,你可以換成其他用起來順手的程式,像是 vim)

貼上以下內容:

name: Build and deploy
on:
  push:
    branches:
      - main
  workflow_dispatch:
concurrency:
  group: ${{ forgejo.workflow }}-${{ forgejo.ref }}
  cancel-in-progress: true
jobs:
  build_and_deploy:
    name: Build and deploy
    runs-on: codeberg-small
    env:
      # Define tool versions
      DART_SASS_VERSION: 1.101.0
      GO_VERSION: 1.26.4
      HUGO_VERSION: 0.164.0
      NODE_VERSION: 24.18.0

      # Set the build time zone
      TZ: Asia/Taipei

      # Set the Hugo base URL
      HUGO_BASEURL: https://${{ forgejo.event.repository.owner.username }}.codeberg.page/
    steps:
      - name: Checkout
        uses: actions/checkout@v7
        with:
          submodules: recursive
          fetch-depth: 0
          lfs: false

      - name: Create a local tools directory
        run: |
          mkdir -p "${HOME}/.local"

      - name: Install Dart Sass
        run: |
          echo "Installing Dart Sass ${DART_SASS_VERSION}..."
          curl -sfL --output-dir "${{ runner.temp }}" -O "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
          tar -C "${HOME}/.local" -xf "${{ runner.temp }}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
          echo "${HOME}/.local/dart-sass" >> "${FORGEJO_PATH}"

      - name: Install Go
        run: |
          if [[ -f "go.mod" ]]; then
            echo "Installing Go ${GO_VERSION}..."
            curl -sfL --output-dir "${{ runner.temp }}" -O "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz"
            tar -C "${HOME}/.local" -xf "${{ runner.temp }}/go${GO_VERSION}.linux-amd64.tar.gz"
            echo "${HOME}/.local/go/bin" >> "${FORGEJO_PATH}"
          fi

      - name: Install Hugo
        run: |
          echo "Installing Hugo ${HUGO_VERSION}..."
          curl -sfL --output-dir "${{ runner.temp }}" -O "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
          mkdir "${HOME}/.local/hugo"
          tar -C "${HOME}/.local/hugo" -xf "${{ runner.temp }}/hugo_${HUGO_VERSION}_linux-amd64.tar.gz"
          echo "${HOME}/.local/hugo" >> "${FORGEJO_PATH}"

      - name: Install Node.js
        run: |
          if [[ -f "package-lock.json" ]]; then
            echo "Installing Node.js ${NODE_VERSION}..."
            curl -sfL --output-dir "${{ runner.temp }}" -O "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-x64.tar.gz"
            tar -C "${HOME}/.local" -xf "${{ runner.temp }}/node-v${NODE_VERSION}-linux-x64.tar.gz"
            echo "${HOME}/.local/node-v${NODE_VERSION}-linux-x64/bin" >> "${FORGEJO_PATH}"
          fi

      - name: Log tool versions
        run: |
          echo "Logging tool versions..."
          command -v sass &> /dev/null && echo "Dart Sass: $(sass --version)" || echo "Dart Sass: not installed"
          command -v go &> /dev/null && echo "Go: $(go version)" || echo "Go: not installed"
          command -v hugo &> /dev/null && echo "Hugo: $(hugo version)" || echo "Hugo: not installed"
          command -v node &> /dev/null && echo "Node.js: $(node --version)" || echo "Node.js: not installed"

      - name: Configure Git
        run: |
          echo "Configuring Git..."
          git config --global core.quotepath false

      - name: Fetch full Git history
        run: |
          if [[ $(git rev-parse --is-shallow-repository) == true ]]; then
            echo "Fetching full Git history..."
            git fetch --unshallow
          fi

      - name: Initialize Git submodules
        run: |
          if [[ -f .gitmodules ]]; then
            echo "Initializing Git submodules..."
            git submodule update --init --recursive
          fi

      - name: Install Node.js dependencies
        run: |
          if [[ -f package-lock.json ]]; then
            echo "Installing Node.js dependencies..."
            npm ci
          fi

      - name: Cache restore
        id: cache-restore
        uses: actions/cache/restore@v6
        with:
          path: ${{ runner.temp }}/.cache/hugo
          key: hugo-${{ forgejo.run_id }}
          restore-keys: hugo-

      - name: Build
        run: |
          echo "Building the project..."
          hugo build \
            --gc \
            --minify \
            --cacheDir "${{ runner.temp }}/.cache/hugo"

      - name: Cache save
        uses: actions/cache/save@v6
        with:
          path: ${{ runner.temp }}/.cache/hugo
          key: ${{ steps.cache-restore.outputs.cache-primary-key }}

      - name: Deploy
        uses: actions/git-pages@v2
        with:
          site: ${{ env.HUGO_BASEURL }}
          token: ${{ forgejo.token }}
          source: public/

      - name: Print base URL
        run: |
          echo "Base URL: ${HUGO_BASEURL}"

網址設定

目標網址會在 你的名稱.codeberg.page/,如果你想把這個網址留給其他網頁的話,那就在 HUGO_BASEURL 改成這樣:

HUGO_BASEURL: https://${{ forgejo.event.repository.owner.username }}.codeberg.page/${{ forgejo.event.repository.name }}/

網址就會設定 你的名稱.codeberg.page/repo 名稱 了。

另外在部落格根目錄的 hugo.yaml(或 hugo.toml) 設定檔中,baseURL 也要調整成你的網址。

部署用主機

另外在 runs-on 的部署主機設定, Codeberg 有六臺部署電腦可以用(我之前看的時候是三臺),分別是 codeberg-tiny、codeberg-small、codeberg-medium,和各自再加上 -lazy。

要用 tiny, small 還是 medium,就根據你的部署工作量決定。如果你的部署工作不急,可以先讓別人跑的話,可以在後面加入 -lazy

從截圖裡面可以看到,這幾臺電腦平時都很忙,部署的時候需要排隊一下。

如果你受不了要排隊排很久的話,也可以考慮自架部署伺服器,不過這超過了我的能力範圍除非你還有其他部署工作要一起做,不然我覺得不需要另外架部署伺服器,而且有一定難度。

更新 repo

儲存完設定後要再重新上傳,在部落格根目錄開終端機:

git add -A
git commit -m "更新訊息 / 更新了什麼 / 網站更新"
git push origin

另外如果 Hugo 在電腦預覽完後,會留下建置完的 /public 資料夾,但 push 的時候用不到它。資料一旦變多,整個 /public 的空間用量就會變很大,不小心 push 到 repo 的時候會很麻煩,所以我會習慣在前面的指令之前加上 rm /public -rf,像是這樣:

rm /public -rf
git add -A
git commit -m "網站更新"
git push origin

接下來每次更新,都需要用 git 把檔案加入追蹤、填入新 commit 訊息,再推送更新到 Codeberg。每次都要這樣其實有點麻煩,我會把這些指令寫成一份 .sh 檔案,每次推送就直接執行檔案就好了。

啟動 Forgejo Action

更新完檔案,在 repo 的設定按 Settings → Units → Overview,勾選 “Enable integrated CI/CD pipelines with Forgejo Actions”,然後 Save Settings,把 Forgejo Actions 功能打開!

自動重新整理之後,標籤頁應該會出現 Actions,而且應該會有工作開始跑。如果沒有的話,隨便找個不會影響部落格運作的地方改一下,再重新 push,應該就會看到開始跑了。

部署成功之後,到設定好的網址看看,應該就可以看到網站上線了!

後記

對我來說,最一開始根本就不知道怎麼用,一直撞牆很久,中間也放棄了兩、三次吧,不過在寫這一篇之前,花了大概 10 分鐘測試,就把整個流程輕鬆跑完了。

讓我感到意外的是,對現在的我來說算簡單的事情,沒想到要用很長的篇幅才能寫完(是寫太多廢話吧 XD)

如果部署上有遇到其他問題,可以再來寫信問我(信箱 itsxiaobai [at] tuta.io),只要我有辦法的話啦。