../zola-deployment
Other language:Deploying Zola
Published:
About the Structure of This Site
This site is hosted on a Kubernetes cluster at my home. Additionally, it is built using Zola. I write in Markdown locally, and when I push to GitHub, it is automatically deployed to the Kubernetes cluster. In this article, I will discuss this structure in detail.
Building a Japanese Blog with Zola
By default, Zola does not support indexing in Japanese. Therefore, you need to build the Zola executable with the --features indexing-ja
flag.
However, the Docker image provided by the Zola is built without the --features indexing-ja
option, necessitating the creation of your own Zola Docker image.
Creating a Japanese-Supported Zola Image
- Git clone Zola from the repository.
- Create a Dockerfile with the following content:
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" ]
- Then build.
docker build -t zola:1.0.0 .
- Later, for use with GitHub Actions, upload the image to ghcr.io. Proceed assuming that the login process has been completed.
docker tag zola:1.0.0 ghcr.io/<GITHUB_ID>/zola:1.0.0
docker push ghcr.io/<GITHUB_ID>/zola:1.0.0
- Go to
https://github.com/users/<GITHUB_ID>/packages/container/zola/settings
and add your Zola repository to Manage Actions access.
With these steps completed, the Zola image for building is now ready.
Building the Site
- Place the following Dockerfile directly under your blog's directory:
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
- Perform a trial build:
docker build -t blog:1.0.0 .
With these steps, you can create a Docker image for your blog.
Automating Builds with GitHub Actions
Write the following content into .github/workflows/build.yaml
within the blog repository. Please modify the content as needed.
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 }}
With this setup, any push to GitHub will automatically trigger a Zola build, and the version tag will be incremented.
Automatic Deployment with Argo CD Image Updater
We will be using version 0.12.2
of Argo CD Image Updater. Assume that the Kubernetes cluster and Argo CD are already set up.
- Install Argo CD Image Updater:
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/v0.12.2/manifests/install.yaml
- Create files for deploying with Argo CD. Construct the following directory structure and I provide the examples for
blog.yml
,kustomization.yml
, andservice.yml
. Please writeingress.yml
according to your own environment.
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
- Write the Application manifest for Argo CD.
# 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
- deploy
kubectl apply -n argocd -f blog.yaml
If all the above steps have been carried out correctly, deployment should occur automatically.