Files
homelab/k8s/apps/gotify/README.md
rock b0c17527f2 feat(gotify): add push notification server + SMTP email relay
- 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.
2026-09-10 08:25:36 +09:00

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

  1. Login to https://gotify.riotpiao.com with admin creds
  2. Applications → Create forgejo → copy app token
  3. Clients → Create smtp-emailer → copy client token
  4. Update gotify-tokens secret:
    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 → SettingsWebhooksAdd WebhookGotify:

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