From 9c9db094a02dfdd143dd177e1be8eec4a5416fba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jirka=20Stehl=C3=ADk?= Date: Tue, 24 Mar 2026 22:32:03 +0100 Subject: [PATCH] Added article about auto release updates --- content/blog/04-automatic-release.md | 104 ++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/content/blog/04-automatic-release.md b/content/blog/04-automatic-release.md index bff9857..8769347 100644 --- a/content/blog/04-automatic-release.md +++ b/content/blog/04-automatic-release.md @@ -1,6 +1,6 @@ --- date: '2026-03-24T20:36:26+01:00' -draft: true +draft: false title: 'Automatic web update release' author: "Jirka" tags: ["self-host", "gitea", "automation"] @@ -170,3 +170,105 @@ jobs: ``` This will automatically create package on push to master. + +Now, once the package was successfully built, we can move onto the webhook. + +## Webhook set up + +For webhook, we will use `almir/webhook:latest` image, But because we need curl and zip, we will build it on our own. +Created `webhook` directory next to `web` directory and create `Dockerfile`: +``` +FROM almir/webhook:latest + +USER root + +RUN apk add --no-cache curl unzip + +WORKDIR /app +``` + +Next we will specify script, which will be executed on webhook trigger. Create file `deploy.sh` with `+x` privileges to be executable: +```bash +#!/bin/sh +set -e + +TEMP_DIR=$(mktemp -d) +ZIP_PATH="$TEMP_DIR/web.zip" + +curl -fL -o "$ZIP_PATH" "https://git.jirkabuilds.dev/api/packages/jirka/generic/hugo-build/latest/web.zip" + +# Delete old web data +rm -rf /site_data/* +rm -rf /site_data/.[!.]* 2>/dev/null || true + +unzip -q "$ZIP_PATH" -d /site_data/ + +rm -rf "$TEMP_DIR" +``` + +As you can see, we are downloading created package and replacing all site content. + +Next step is to define hook itself. Create `hooks.json` file with following content: +``` +[ + { + "id": "deploy-web", + "execute-command": "/app/deploy.sh", + "command-working-directory": "/app", + "trigger-rule": { + "match": { + "type": "value", + "value": "secret token", + "parameter": { + "source": "header", + "name": "X-Deploy-Token" + } + } + } + } +] +``` +You should create `secret`, which you will store to Gitea, same as with token earlier` with name `WEBHOOK_SECRET`. Thanks to it, only the workflow can trigger this webhook. + +And last step is to create `docker-compose.yml`: +``` +services: + webhook: + build: . + container_name: jirkabuilds_release_web_webhook + volumes: + - ./hooks.json:/etc/webhook/hooks.json:ro + - ./deploy.sh:/app/deploy.sh:ro + - ./../web/site_data:/site_data + command: ["-verbose", "-hooks=/etc/webhook/hooks.json", "-hotreload"] + restart: unless-stopped + networks: + - jirkabuilds_proxy_network + +networks: + jirkabuilds_proxy_network: +``` + +You can see, we are using the same proxy network as for everything. Next step is to add following block to `Caddyfile`: +``` +hooks.jirkabuilds.dev { + reverse_proxy jirkabuilds_release_web_webhook:9000 +} +``` + +And following line to our root `docker-compose.yml` +``` + - webhook/docker-compose.yml +``` + +Now you can restart the stack and webhook should work. + +Final last step is to replace #TODO in our workflow with following: +``` + - name: Trigger Webhook + run: | + curl -X POST "https://hooks.jirkabuilds.dev/hooks/deploy-web" \ + -H "X-Deploy-Token: ${{ secrets.WEBHOOK_SECRET }}" +``` + +And that is it. On next push, web should update itself automatically.