db9f47649d6258974cd22c9eeb1c6e2eb077e2c1
All checks were successful
CI / build-test (push) Successful in 1m3s
README.md and .claude/CLAUDE.md with new features, architecture, and API changes
- Reflect addition of React SPA, SQLite persistence, and tag management - Update quick start guide for backend and frontend setup - Document full API routes and database schema - Revise project structure for recent refactor - Improve production and testing notes for clarity
DIUN Webhook Dashboard
A Go web app that receives DIUN webhook events and shows image updates in a modern dashboard. Events are persisted to SQLite so they survive restarts.
- Receives DIUN webhooks at
POST /webhook - Serves a React SPA dashboard at
/ - REST API for updates, tags, and acknowledgements
- Persistent storage via SQLite (
diun.db) - Tag/group system to organize images
- Dismiss (acknowledge) updates you've reviewed
Quick start
Run locally (Go 1.26+)
# Build the frontend first
cd frontend && bun install && bun run build && cd ..
# Start the server
go run ./cmd/diunwebhook/
# open http://localhost:8080
Docker
docker build -t diun-webhook-dashboard .
docker run --rm -p 8080:8080 diun-webhook-dashboard
# open http://localhost:8080
Docker Compose
docker compose up -d
# open http://localhost:8080
DIUN configuration example
Configure DIUN to send webhooks to this app. Example (YAML):
notif:
webhook:
enable: true
endpoint: http://your-host-or-ip:8080/webhook
Expected JSON payload (simplified):
{
"image": "library/nginx",
"tag": "1.27.0",
"status": "new",
"time": "2026-02-23T16:00:00Z"
}
API
| Method | Endpoint | Description |
|---|---|---|
POST |
/webhook |
Accept a DIUN event JSON body |
GET |
/api/updates |
Return all events (keyed by image) with tag and acknowledged state |
PATCH |
/api/updates/{image} |
Mark an event as acknowledged (dismiss) |
GET |
/api/tags |
List all tags |
POST |
/api/tags |
Create a new tag |
DELETE |
/api/tags/{id} |
Delete a tag (cascades to assignments) |
PUT |
/api/tag-assignments |
Assign an image to a tag |
DELETE |
/api/tag-assignments |
Unassign an image from its tag |
Project Structure
cmd/diunwebhook/ — main application entrypoint
pkg/diunwebhook/ — core library (handlers, DB, models)
frontend/ — React SPA (Bun + Vite + React 19 + Tailwind + shadcn/ui)
.gitea/workflows/ — CI/CD workflows (Gitea Actions)
Dockerfile — 3-stage multi-stage build
docker-compose.yml — single-service compose file
Development
Backend:
go run ./cmd/diunwebhook/
Frontend (dev server with hot reload):
cd frontend
bun install
bun run dev # http://localhost:5173, proxies API to :8080
Testing
Run unit tests and check coverage:
go test -v -coverprofile=coverage.out -coverpkg=./... ./...
Aim for 80-90% coverage. Coverage below 80% will emit a warning in CI but will not fail the pipeline.
CI/CD with Gitea Actions
- CI (
.gitea/workflows/ci.yml): Runs on push/PR todevelop. Checks formatting (gofmt), runsgo vet, tests with coverage, and builds the binary. - Release (
.gitea/workflows/release.yml): Manual dispatch. Runs tests, bumps version, tags, builds and pushes Docker image to Gitea registry, creates a release with changelog.
Production notes
- Behind a reverse proxy, ensure the app is reachable at
/webhookfrom DIUN. - Data is persisted to
diun.dbin the working directory. Mount a volume to preserve data across container recreations. - Consider adding auth, rate limiting, or a secret/token on the webhook endpoint if exposed publicly.
License
MIT — see LICENSE.