Zola daisyUI blog

Zola daisyUI blog

はじめに

Zola + daisyUI 使ったブログテンプレート作ったので、備忘録かねて記事にしてます。

作った理由、セットアップ手順等を記しています。


なぜ作ったか?

以前から Github pages での個人情報発信は考えていたのだが、ようやく重い腰を上げてアプリを構築した。

mosaos/zola-daisyui-blog

※ 実例は当サイト

当初 React-typescript で簡単なものを実装したり(markdown を表示可能にするところまでは作ってた)、Astro 使う方がとかの AI アドバイスに従って試したりしてたのだが、最終的には以下の技術スタックに落ち着くことに。

  • Zola
    Rust 製の SSG ( 静的サイトジェネレータ )
  • daisyUI
    tailwind CSS 状のコンポーネントライブラリ
  • Github pages
    当初からの要件

node 止めたのはメンテ地獄にはなりたくないという理由。実務でも React 案件には携わったりしてるのだが、node 系は

  • 関連するパッケージが多い
  • セキュリティ(脆弱性)対応多い
  • 破壊的変更多い

破壊的変更は私の得意な言語が Java ( Spring Boot とか)のせいもあるのだが、中身変わってないのにメンテが発生するのは、仕事でやるのはさておき個人の情報発信では面倒。

といった理由で上記の構成になったのだ。 daisyUI も node 必要という人もいるかもだが、CDNで公開されている full.css とかを利用すれば tailwind / daisyUI のビルドプロセスは無しで使える (全部入りにはなる)。最適化がーって話もあるかもだが、メンテ地獄嫌!が最重要な要件なので、CDNのリソース使うのは正義。


機能

作ったテンプレ。詳細は README.md 参照なのだが、以下のようになっている。
※ ほぼほぼ Zola/daisyUI 等の特性ではある。

  • レスポンシブデザイン
    daisyUIとTailwind CSSによる、モバイルにも対応したシンプルで使いやすいレイアウト。
  • Markdownベース
    Markdown でブログ記事やポートフォリオ作品を簡単に作成可能。記事には目次 ( TOC ) を表示することもできます。
  • 多言語対応
    多言語切り替え機能を標準搭載。必要に応じて任意の数の言語に拡張可能。
  • 静的サイト生成 ( SSG )
    高速かつ安全で、Node.jsなどのサーバーサイドランタイムを必要としない。
  • Dev Containers対応
    開発環境をすぐに構築でき、環境構築の手間を軽減。
  • タグ対応
    タグ付けにより、コンテンツを整理・分類できる。
  • 画像カルーセル / スライドショー
    ポートフォリオ作品などに複数の写真や画像を表示できる、カルーセルを用意。

開発環境

以下で確認しています。

  • Windows 11
  • WSL2 ( Ubuntu )
  • docker-ce
    Dev Container 使う場合。Desktop ではない。企業でライセンス無い場合も可能。
  • VS Code

構築手順

アプリ部分は Template プロジェクトとして github に登録してあります。お勧めの手順は以下。

尚、ローカルでの動作確認のためにシンボリックリンクを使うので WSL2 上推奨です ( windows の場合 )。
※ Mac は知らんのだ。

各種リポジトリの作成

  1. mosaos/zola-daisyui-blog にアクセス。
  2. Use this template > Create a new repository をクリック。自分のリポジトリとして作成する ( my-portfolio 等 )。Private でもOK。
  3. コンテンツ用リポジトリを別途作成する。my-portfolio-content 等。Private でよい。
    これはアプリ部分とコンテンツ部分を分離することで、今後アプリ部分がアップデートした場合に更新しやするするため。面倒な場合は、分離せずに、2 の my-portfolio にコンテンツを含めても問題ない。
  4. github pages 用のリポジトリを作製する (Public)。ドメイン直下で公開する場合には ユーザ名.github.io をリポジトリ名とする。

一旦ローカルで動作確認

※コンテンツ用リポジトリを分離していない場合は、シンボリックで付け替える作業は不要

非 DevContainer の場合

コンテンツをアプリ側の content にシンボリックリンクする。

アプリ側 ( my-portfolio ) 側の content は削除

cd /path/to/my-portfolio
rm -rf content

コンテンツリポジトリ(my-portfolio-content)をシンボリックリンク
※ 以下は my-portfolio と my-portfolio-content が同じ階層にある場合

ln -s ../my-portfolio-content content

DevContainer の場合

シンボリックリンクは機能しないため、mount する。

my-portfolio の content は削除せずに中身を消しておく。

my-portfolio の devcontainer.json に以下 ( mounts 定義 ) を追記する。

    "forwardPorts": [
        1111
    ],
    // ホスト側の content 用リポジトリを、コンテナ内の zola 側 content ディレクトリにバインドマウントする
    "mounts": [
        {
            "source": "${localWorkspaceFolder}/../my-portfolio-content",
            "target": "${containerWorkspaceFolder}/content",
            "type": "bind"
        }
    ]
    // "remoteUser": "root"

設定したら Rebuild Container して、DevContainer から content の中身が見えれば(リンクされていれば)成功

動作確認

ローカルで動作確認

cd /path/to/my-portfolio

DevContainer の場合は、VS Code に入って DevContainer のターミナルから確認する。

そうでない場合には WSL2(Ubuntu) に導入した zola を使って確認すればOK

code .
zola serve --interface 0.0.0.0 --port 1111 --base-url /

VSCode の場合、Your application running on port 1111 is available. See all forwarded ports というダイアログが表示されるので、Open in Browser をクリックして、サイトが表示されれば OK。
非 VS Code の場合、http://localhost:1111/ を開いて確認できれば OK。

.gitignore の調整

動作が確認できたら、
my-portfolio 側で my-portfolio-content のファイルを多重管理しないように content フォルダ以下は除外しておく ( 以下を追記 )。

content/**

my-portfolio で以下も行っておいた方がいいかも。

git rm --cached -r content

ここまでで ローカル側での開発/確認環境が出来たことになる。

必要に応じてコンテンツ追加や、アプリ部分のカスタマイズ等を行うのだ。

PAT(GitHub Personal Access Token)の準備

ここからは GitHub Actions で GitHub Pages にサイトを公開するための設定になる。
※ ローカル/Dev Container の Zola でSSG 生成して手動でページ公開するといった場合には必要ない。

my-portfolio からは別のプライベートリポジトリ ( my-portfolio-content )と、公開リポジトリ ( ユーザ名.github.io ) へのアクセス権が必要になる。以下の手順で PAT を用意する。

  1. 画面右の自分のアイコンから Settings > Developer settings > Personal access tokens から Tokens (classic) を開く

  2. Generate new token (classic) をクリック

  3. Note に説明 ( portfolio deploy token 等 ) を記載し、Expiration Date を設定する

    • 推奨:
      セキュリティの観点から 30 days または 60 days ( 定期的な更新が必要 )
    • 個人運用での妥協案:
      更新の手間を減らしたい場合は 90 days(期限切れ間近にリマインドメールが届く)

    ※ No expiration(無期限) はトークン漏洩時のリスクが高いため非推奨。

  4. Select scopes で以下にチェックを入れる

    • repo
  5. ページ下部の Generate token をクリックし、生成されたトークを控えておく ( ※ 一度閉じると再表示不可 )

GitHub Secrets へ登録

発行したトークンを、アプリ側のリポジトリ ( my-portfolio ) に秘密鍵として登録する。

  1. 自分の my-portfolio リポジトリのページを開く。
  2. Settings > Secrets and variables > Actions に移動する。
  3. New repository secret をクリックする。
    • Name: GH_PAT ( または分かりやすい名前 )
    • Secret: さっきコピーしたPAT の文字列を貼り付ける。
  4. Add secret で保存。

GithHub Actions ワークフローの作成

アプリ側のリポジトリ ( my-portfolio ) のルートに、GitHub Actions 用の設定ファイルを作成する。

※ 作者の設定になっているので適宜変更すること

.github/workflows/deploy.yml

name: Build and Deploy Zola Site

on:
  push:
    branches:
      - main # または master ( 自身のメインブランチに合わせる )

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      # 1. アプリリポジトリをチェックアウト
      - name: Checkout my-portfolio
        uses: actions/checkout@v4

      # 2. コンテンツリポジトリ(Private)を content/ フォルダへ直接チェックアウト
      - name: Checkout my-portfolio-content
        uses: actions/checkout@v4
        with:
          repository: mosaos/my-portfolio-content # ユーザー名/コンテンツリポジトリ名
          token: ${{ secrets.GH_PAT }}
          path: content

      # 3. Zola のインストール
      - name: Setup Zola
        uses: taiki-e/install-action@v2
        with:
          tool: zola@0.17.2 # バージョンは開発環境に合わせる

      # 4. Zola でサイトをビルド
      - name: Build Zola site
        run: zola build

      # 5. ビルド成果物(public/)を mosaos.github.io リポジトリへプッシュ
      - name: Push to mosaos.github.io
        env:
          GH_TOKEN: ${{ secrets.GH_PAT }}
        run: |
          git config --global user.name "GitHub Actions Bot"
          git config --global user.email "actions@github.com"

          # ビルド結果が出力される public ディレクトリに移動
          cd public

          # Gitリポジトリとして初期化してプッシュ
          git init
          git checkout -b main
          git remote add origin https://x-access-token:${{ secrets.GH_PAT }}@github.com/mosaos/mosaos.github.io.git
          git add -A
          git commit -m "Deploy from my-portfolio CI/CD at $(date)"
          git push -f origin main

設定ファイルを作成したら commit / push する。

※ commit / push 前には config.yml で base_url を 自分の github pages の url に変更しておきましょう。

※ Action が実行されれば OK。この時点で content が登録されていない場合は failure になるが、content 登録後に Rerun して問題なければ OK。

デプロイ先 ( ユーザ名.github.io ) 側の GitHub Pages 設定

  1. ユーザ名.github.io リポジトリの Settings > Pages を開く。
  2. Build and deployment 設定:
    • Source : Deploy from a branch を選択する。
    • Branch : main ( or master )、フォルダは / (root) を選択して Save を押す。

content 更新をトリガーにする

上記の設定の場合、my-portfolio への更新 ( main に push ) が Actions のトリガーになります。
通常は content が更新された場合にサイトが更新される方が便利でしょう。

この場合以下の設定をアプリ側 ( my-portfolio ) とコンテンツ側 ( my-portfolio-content ) に追加しましょう。

アプリ側 ( my-portfolio ) の設定

アプリ側の .github/workflows/deploy.yml の on: セクションを書き換えて、コンテンツ側からの合図 ( repository_dispatch ) を待ち受けられるようにします。

.github/workflows/deploy.yml

頭に以下を追記します。

アプリ側のリポジトリに実施したのと同じ方法で、GH_PAT Secrets 登録も行ってください。

name: Build and Deploy Zola Site

on:
  push:
    branches:
      - main # または master
  # 外部 ( コンテンツ側 ) からの待ち受け設定を追記
  repository_dispatch:
    types: [content_updated]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    #  ( 以下略 )

コンテンツ側 ( my-portfolio-content ) の設定

.github/workflows/deploy.yml

設定を新規作成します。

name: Trigger App Build on Content Push

on:
  push:
    branches:
      - main # 記事(Markdown)を管理するメインブランチに合わせる

jobs:
  trigger_dispatch:
    runs-on: ubuntu-latest
    steps:
      - name: Repository Dispatch
        uses: peter-evans/repository-dispatch@v3
        with:
          token: ${{ secrets.GH_PAT }} # コンテンツ側にも同じGH_PATをSecretに登録しておく
          repository: mosaos/my-portfolio # ターゲットとなるアプリ側のリポジトリ
          event-type: content_updated # アプリ側のtypesで待ち受けている名前と完全一致させる(ハイフンに注意)

zola-daisyui-blog の更新に追随する

upstream 登録

Use this template で作成したリポジトリは、Fork とは異なり元のリポジトリとは完全に独立した状態になっています。もし、元のテンプレートリポジトリの更新に追随したいときは以下を実行しておきましょう。

作製したプロジェクトのルートに移動し

cd my-portfolio

upstream 設定する。

git remote add upstream https://github.com/mosaos/zola-daisyui-blog

登録できたかは以下で確認できます。

git remote -v

元のテンプレートの変更を適用する

まずは変更を取得します。

git fetch upstream

通常のマージだと履歴が無関係と判断されてしまうため --allow-unrelated-histories を付けて merge します。

git merge upstream/main --allow-unrelated-histories

元テンプレートの変更がマージされます。自分が書き換えた部分とテンプレートの更新部分でコンフリクトがあれば、修正します。

修正が完了したらコミットしましょう。

あとは自分のリポジトリに push して完了です。