# Gotify — self-hosted push notification server + SMTP email relay. # Forgejo webhooks → Gotify → push notifications + email forwarding. # Runs on control plane (no GPU needed), lightweight. apiVersion: apps/v1 kind: Deployment metadata: name: gotify namespace: notifications labels: app: gotify spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: gotify template: metadata: labels: app: gotify spec: containers: # --- Gotify server --- - name: gotify image: ghcr.io/gotify/server:2.6.1 command: ["/bin/sh", "-c"] args: - | export GOTIFY_DATABASE_DIALECT=postgres export GOTIFY_DATABASE_CONNECTION="host=gotify-db-rw.notifications port=5432 user=${DB_USER} password=${DB_PASS} dbname=gotify sslmode=disable" exec /app/gotify-app ports: - containerPort: 80 protocol: TCP env: - name: GOTIFY_DEFAULTUSER_NAME valueFrom: secretKeyRef: name: gotify-admin key: username - name: GOTIFY_DEFAULTUSER_PASS valueFrom: secretKeyRef: name: gotify-admin key: password - name: DB_USER valueFrom: secretKeyRef: name: gotify-db-app key: username - name: DB_PASS valueFrom: secretKeyRef: name: gotify-db-app key: password - name: GOTIFY_SERVER_PORT value: "80" - name: GOTIFY_SERVER_KEEPALIVEPERIODSECONDS value: "0" - name: TZ value: Asia/Tokyo resources: requests: cpu: 50m memory: 64Mi limits: cpu: 200m memory: 128Mi livenessProbe: httpGet: path: /health port: 80 periodSeconds: 30 initialDelaySeconds: 10 readinessProbe: httpGet: path: /health port: 80 periodSeconds: 10 initialDelaySeconds: 5 # --- SMTP emailer sidecar --- # Watches Gotify WebSocket stream, forwards messages as email. # https://github.com/eternal-flame-AD/gotify-broadcast - name: smtp-emailer image: ghcr.io/gotify/server:2.6.1 command: - /bin/sh - -c - | # Wait for Gotify to be ready until wget -qO- http://localhost:80/health >/dev/null 2>&1; do echo "Waiting for Gotify..." sleep 2 done echo "Gotify is ready, starting email relay..." # Poll Gotify messages and forward via SMTP using msmtp # Install msmtp for lightweight SMTP sending apk add --no-cache msmtp curl jq # Configure msmtp cat > /tmp/msmtprc </dev/null) if [ -n "$MESSAGES" ]; then echo "$MESSAGES" | jq -r '.messages[]? | @base64' | while read -r MSG; do DECODED=$(echo "$MSG" | base64 -d) ID=$(echo "$DECODED" | jq -r '.id') TITLE=$(echo "$DECODED" | jq -r '.title // "Notification"') BODY=$(echo "$DECODED" | jq -r '.message // ""') PRIORITY=$(echo "$DECODED" | jq -r '.priority // 5') APP=$(echo "$DECODED" | jq -r '.appid // 0') DATE=$(echo "$DECODED" | jq -r '.date // ""') # Only forward messages with priority >= configured threshold if [ "$PRIORITY" -ge "${MIN_PRIORITY:-0}" ]; then printf "Subject: [Gotify] %s\nFrom: %s\nTo: %s\nContent-Type: text/plain; charset=UTF-8\n\n%s\n\n---\nPriority: %s\nDate: %s" \ "$TITLE" "$SMTP_FROM" "$NOTIFY_EMAIL" "$BODY" "$PRIORITY" "$DATE" | \ msmtp -C /tmp/msmtprc "$NOTIFY_EMAIL" && \ echo "Email sent for message $ID: $TITLE" || \ echo "Failed to send email for message $ID" fi # Update last seen ID if [ "$ID" -gt "$LAST_ID" ]; then LAST_ID=$ID fi done fi sleep ${POLL_INTERVAL:-30} done env: - name: GOTIFY_CLIENT_TOKEN valueFrom: secretKeyRef: name: gotify-tokens key: client-token - name: SMTP_HOST valueFrom: secretKeyRef: name: gotify-smtp key: host - name: SMTP_PORT valueFrom: secretKeyRef: name: gotify-smtp key: port - name: SMTP_FROM valueFrom: secretKeyRef: name: gotify-smtp key: from - name: SMTP_USER valueFrom: secretKeyRef: name: gotify-smtp key: user - name: SMTP_PASS valueFrom: secretKeyRef: name: gotify-smtp key: password - name: NOTIFY_EMAIL valueFrom: secretKeyRef: name: gotify-smtp key: notify-email - name: MIN_PRIORITY value: "5" - name: POLL_INTERVAL value: "15" resources: requests: cpu: 10m memory: 32Mi limits: cpu: 100m memory: 64Mi # No volumes — Postgres handles persistence