../zola-deployment

Other language:
en

Zolaのデプロイ

Published:

technology Zola Kubernetes Argo CD Docker

このサイトの構成について

このサイトは自宅のKubernetesクラスタでホストされています。また、Zolaを使用してサイトを作成しています。 ローカルでMarkdownを書き、GitHubにpushをすると自動的にKubernetesクラスタへデプロイされる構成になっています。 今回はこの構成について書いていきます。

日本語ブログをZolaでビルドする

Zolaはデフォルトで日本語のindexingに対応していません。そのため、--features indexing-jaを付けてZola本体をビルドする必要があります。 しかし、Zola公式から提供されているDockerイメージは--features indexing-ja無しでビルドされているため、ZolaのDockerイメージを自作する必要があります。

日本語対応のZolaイメージを作成する

  1. Zolaをgit cloneしてきます。
  2. Dockerfileを以下のようにします。
FROM rust:slim AS builder

RUN apt-get update -y && \
  apt-get install -y make g++ libssl-dev && \
  rustup target add x86_64-unknown-linux-gnu

WORKDIR /app
COPY . .

RUN cargo build --release --target x86_64-unknown-linux-gnu --features indexing-ja

FROM gcr.io/distroless/cc-debian12:latest
COPY --from=builder /app/target/x86_64-unknown-linux-gnu/release/zola /bin/zola
ENTRYPOINT [ "/bin/zola" ]
  1. ビルドします。
docker build -t zola:1.0.0 .
  1. 後でGitHub Actionsから使用するために、ghcr.ioへアップロードします。ログイン処理は済んでいるものとして進みます。
docker tag zola:1.0.0 ghcr.io/<GITHUB_ID>/zola:1.0.0
docker push ghcr.io/<GITHUB_ID>/zola:1.0.0
  1. https://github.com/users/<GITHUB_ID>/packages/container/zola/settings へアクセスし、Manage Actions accessへ自分のZolaリポジトリを追加します。

以上でビルド用Zolaイメージが完成しました。

サイトのビルドをする

  1. 以下のDockerfileをブログのディレクトリ直下に設置します。
FROM ghcr.io/<GITHUB_ID>/zola:1.0.0 as zola

COPY . /project
WORKDIR /project
RUN ["zola", "build"]

FROM ghcr.io/static-web-server/static-web-server:2
WORKDIR /
COPY --from=zola /project/public /public
  1. お試しビルドをします。
docker build -t blog:1.0.0 .

これでブログのDockerイメージを作ることができます。

GitHub Actions で自動ビルドをする

ブログのリポジトリ内 .github/workflows/build.yamlへ以下の内容を書き込みます。内容は適宜修正してください。

on:
  push:
    branches:
      - main
  workflow_dispatch:

permissions:
  id-token: write
  contents: write

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: write

    steps:
      - name: Check out the repository
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract version from tags
        id: get_version
        run: |
          git fetch --prune --unshallow
          latest_tag=$(git describe --tags $(git rev-list --tags --max-count=1) 2>/dev/null || echo "v0.0.0")
          version="${latest_tag/v/}"
          echo "::set-output name=version::${version}"

      - name: Increment version
        id: inc_version
        run: |
          version="${{ steps.get_version.outputs.version }}"
          major=$(echo $version | cut -d. -f1)
          minor=$(echo $version | cut -d. -f2)
          patch=$(echo $version | cut -d. -f3)
          new_version="$major.$minor.$((patch + 1))"
          echo "New version: $new_version"
          echo "::set-output name=new_version::${new_version}"

      - name: Build and push Docker image
        uses: docker/build-push-action@v2
        with:
          context: .
          push: true
          tags: |
            ghcr.io/${{ github.actor }}/blog/blog:${{ steps.inc_version.outputs.new_version }}
            ghcr.io/${{ github.actor }}/blog/blog:latest

      - uses: rickstaa/action-create-tag@v1
        id: "tag_create"
        with:
          tag: ${{ steps.inc_version.outputs.new_version }}
          tag_exists_error: false
          message: ${{ steps.inc_version.outputs.new_version }}
          github_token: ${{ secrets.GITHUB_TOKEN }}

この状態でGitHubへ何かをpushすると自動的にZolaビルドが走り、バージョンタグがインクリメントされます。

Argo CD Image Updater で自動デプロイをする

Argo CD Image Updaterのバージョンは0.12.2を使用します。 Kuberentes クラスタ、Argo CD は構築済みとして進めます。

  1. Argo CD Image Updater のインストール
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/v0.12.2/manifests/install.yaml
  1. Argo CDデプロイ用のファイルを作成する。以下のディレクトリ構造で作っていきます。blog.ymlkustomization.ymlservice.ymlのみ例を張ります。ingress.ymlは各自環境に合わせて書いてください。
apps/
├─ blog/
│  ├─ base/
│  │  ├─ blog.yml
│  │  ├─ ingress.yml
│  │  ├─ kustomization.yml
│  │  ├─ service.yml
│  ├─ overlays/
│  │  ├─ kustomization.yml
# apps/blog/base/blog.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: blog
  labels:
    app: blog
spec:
  selector:
    matchLabels:
      app: blog
  replicas: 1
  template:
    metadata:
      labels:
        app: blog
    spec:
      containers:
        - image: ghcr.io/<GITHUB_ID>/blog/blog:latest
          imagePullPolicy: Always
          name: blog
# apps/blog/base/kustomization.yml
resources:
  - blog.yml
  - ingress.yml
  - service.yml
# apps/blog/base/service.yml
apiVersion: v1
kind: Service
metadata:
  name: blog
  namespace: blog
spec:
  type: LoadBalancer
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: blog
# apps/blog/overlays/kusotmization.yml
bases:
  - ../base
  1. Argo CD の Application マニフェストを書きます。
# blog.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: blog
  namespace: argocd
  annotations:
    argocd-image-updater.argoproj.io/image-list: "blog=ghcr.io/<GITHUB_ID>/blog/blog:latest"
    argocd-image-updater.argoproj.io/write-back-method: "argocd"
    argocd-image-updater.argoproj.io/blog.update-strategy: "latest"
    argocd-image-updater.argoproj.io/blog.allow-tags: "regexp:^\\d+\\.\\d+\\.\\d+$"
spec:
  project: default
  source:
    repoURL: '<ArgoCD git Repository>'
    path: 'apps/blog/overlays'
    kustomize:
      namePrefix: blog-
  destination:
    server: 'https://kubernetes.default.svc'
    namespace: 'blog'
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
  1. デプロイ。
kubectl apply -n argocd -f blog.yaml

以上の手順がうまく行っていれば自動的にデプロイされるはずです。