- Gotify server (ghcr.io/gotify/server:2.6.1) in notifications namespace - SMTP emailer sidecar polls messages, forwards as email via msmtp - Ingress at gotify.riotpiao.com with WebSocket support - 1Gi Longhorn PVC for message persistence - ArgoCD Application (wave 8, auto-sync) - Secrets template for admin creds, SMTP config, tokens - README with setup guide: tokens, Forgejo webhooks, SMTP providers Enables PR created/merged email notifications from Forgejo.
3.3 KiB
3.3 KiB
Gotify — Push Notifications + Email Relay
Self-hosted notification server with SMTP email forwarding sidecar.
Architecture
Forgejo webhook ──POST──→ Gotify API (:80/message)
│
┌─────────┼─────────┐
▼ ▼
Push notification SMTP emailer sidecar
(mobile/desktop) (polls → sends email)
Setup (one-time, after first deploy)
1. Encrypt secrets before committing
# Edit secrets.yaml with real values first, then:
sops -e -i k8s/apps/gotify/secrets.yaml
2. Create Gotify app + client tokens
- Login to
https://gotify.riotpiao.comwith admin creds - Applications → Create
forgejo→ copy app token - Clients → Create
smtp-emailer→ copy client token - Update
gotify-tokenssecret:kubectl -n notifications create secret generic gotify-tokens \ --from-literal=app-token=<APP_TOKEN> \ --from-literal=client-token=<CLIENT_TOKEN> \ --dry-run=client -o yaml | kubectl apply -f -
3. Configure Forgejo webhook
In each Forgejo repo → Settings → Webhooks → Add Webhook → Gotify:
| Field | Value |
|---|---|
| Target URL | http://gotify.notifications.svc.cluster.local/message |
| Token | The app token from step 2 |
| Events | Pull Request (Created, Merged, Closed) |
Or via API:
FORGEJO_TOKEN="<your-pat>"
APP_TOKEN="<gotify-app-token>"
curl -s -X POST "https://forgejo.riotpiao.com/api/v1/repos/rock/homelab/hooks" \
-H "Authorization: token $FORGEJO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "gotify",
"active": true,
"config": {
"content_type": "json",
"url": "http://gotify.notifications.svc.cluster.local/message?token='"$APP_TOKEN"'"
},
"events": ["pull_request", "pull_request_assign", "pull_request_review"],
"authorization_header": ""
}'
4. Add CoreDNS rewrite (if accessing via public hostname)
Only needed if Cloudflare Tunnel is used for gotify.riotpiao.com:
# terraform/files/coredns/Corefile — add rewrite:
rewrite name gotify.riotpiao.com ingress-nginx-controller.ingress-nginx.svc.cluster.local
Then: cd terraform && terraform apply && cd .. && make apply-cp
5. SMTP providers
| Provider | Host | Port | Notes |
|---|---|---|---|
| Gmail | smtp.gmail.com | 587 | Use App Password (2FA required) |
| Resend | smtp.resend.com | 587 | Free 100 emails/day |
| Sendgrid | smtp.sendgrid.net | 587 | Free 100 emails/day |
| Mailgun | smtp.mailgun.org | 587 | Free 5000/month |
Notification priority levels
| Priority | Meaning | Email forwarded? |
|---|---|---|
| 0-4 | Low (info) | No (below MIN_PRIORITY=5) |
| 5-7 | Normal (PR created) | Yes |
| 8-10 | High (PR merged, failures) | Yes |
Verify
# Test push notification
APP_TOKEN="<app-token>"
curl -X POST "https://gotify.riotpiao.com/message?token=$APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Test","message":"Hello from homelab","priority":5}'
# Check email sidecar logs
kubectl -n notifications logs deployment/gotify -c smtp-emailer --tail=20