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

把 Hugo 網站架設到 Codeberg 吧!

Note

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

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

前言

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

  • 租一台雲端電腦,把部落格架在上面
  • 用 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),只要我有辦法的話啦。