No description
  • Makefile 46%
  • Shell 32.5%
  • Dockerfile 21.5%
Find a file
Benjamin Long cede90199c Initial commit: Hugo webhook deployer
Lightweight Docker container that listens for Forgejo/Gitea push webhooks
and automatically rebuilds a Hugo site. Single container replacement for
CI runners + Docker-in-Docker.
2026-03-05 23:46:50 +00:00
.env.example Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
.gitignore Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
docker-compose.yml.example Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
Dockerfile Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
entrypoint.sh Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
hooks.json.tmpl Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
Makefile Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
README.md Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
rebuild.sh Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
ssh_config Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00
VERSION Initial commit: Hugo webhook deployer 2026-03-05 23:46:50 +00:00

hugo-webhook-deployer

A lightweight Docker container that listens for Forgejo/Gitea push webhooks and automatically rebuilds a Hugo site.

No CI runners, no Docker-in-Docker — just a single container that clones, builds, and deploys.

How it works

git push → Forgejo webhook POST → hugo-webhook-deployer:9000
  → validates HMAC-SHA256 signature
  → filters for pushes to main
  → git pull + hugo --minify
  → output written to /output volume

Setup

1. Generate a deploy key

ssh-keygen -t ed25519 -f /tmp/deploy_key -N "" -C "hugo-deployer"

Add the public key to your Forgejo repo as a read-only deploy key (Settings → Deploy Keys):

cat /tmp/deploy_key.pub

Base64-encode the private key (you'll need this for DEPLOY_KEY_BASE64):

base64 -w0 /tmp/deploy_key

2. Generate a webhook secret

openssl rand -hex 32

Save this value — you'll set it in both the container config and the Forgejo webhook.

3. Configure environment variables

Variable Description
WEBHOOK_SECRET The random string from step 2 (must match Forgejo webhook config)
REPO_URL SSH clone URL for your repo, e.g. ssh://git@git.example.com:2222/org/repo.git
DEPLOY_KEY_BASE64 The base64-encoded private key from step 1

See .env.example for a template.

4. Run the container

The /output volume should point to wherever your web server serves static files from (e.g. Apache's DocumentRoot).

The site-cache volume persists the cloned repo between restarts so subsequent builds are fast git pulls instead of full clones.

Docker CLI

docker run -d \
  --name hugo-webhook \
  -p 9000:9000 \
  -v /var/www/your-site:/output \
  -v site-cache:/site \
  -e WEBHOOK_SECRET=your-secret \
  -e REPO_URL=ssh://git@git.example.com:2222/org/repo.git \
  -e DEPLOY_KEY_BASE64=$(base64 -w0 /tmp/deploy_key) \
  --restart unless-stopped \
  your-registry/hugo-webhook-deployer:latest

Docker Compose

See docker-compose.yml.example for a template.

Portainer

Create a new container or stack using the image and environment variables above.

5. Add the webhook in Forgejo

Go to your repo → Settings → Webhooks → Add Webhook (Gitea):

  • Target URL: http://<host>:9000/hooks/hugo-rebuild
  • Secret: same value as WEBHOOK_SECRET
  • Trigger on: Push events
  • Branch filter: main

6. Verify

Push a commit to main and check the container logs:

docker logs -f hugo-webhook

SSH configuration

The port is specified in the REPO_URL via the ssh:// scheme (e.g. ssh://git@host:2222/org/repo.git). The built-in ssh_config also sets a default port — edit it if your Forgejo SSH port differs.

Building from source

make release    # bump version, build, tag, push to registry
make build      # bump + build only
make version    # show current version

Components

  • Hugo (extended edition, via hugomods/hugo:exts)
  • adnanh/webhook — lightweight webhook receiver
  • Alpine Linux 3.21