apiVersion: v1 kind: Namespace metadata: name: notifications --- # 1. GOTIFY STORAGE PERFORMANCE LAYER apiVersion: v1 kind: PersistentVolumeClaim metadata: name: gotify-data-pvc namespace: notifications spec: accessModes: - ReadWriteOnce storageClassName: longhorn resources: requests: storage: 5Gi --- # 2. GOTIFY CORE SERVICE DEPLOYMENT apiVersion: apps/v1 kind: Deployment metadata: name: gotify namespace: notifications spec: replicas: 1 selector: matchLabels: app: gotify template: metadata: labels: app: gotify spec: containers: - name: gotify image: docker.io/gotify/server:2.5.0 ports: - containerPort: 80 env: - name: GOTIFY_SERVER_PORT value: "80" - name: GOTIFY_SERVER_KEEPALIVEPERIODSECONDS value: "30" # Optional: Enforce default admin timezone - name: TZ value: "Europe/London" resources: requests: memory: "50Mi" cpu: "10m" limits: memory: "256Mi" cpu: "200m" volumeMounts: - name: gotify-storage mountPath: /app/data volumes: - name: gotify-storage persistentVolumeClaim: claimName: gotify-data-pvc --- apiVersion: v1 kind: Service metadata: name: gotify-svc namespace: notifications spec: ports: - port: 80 targetPort: 80 selector: app: gotify --- # 3. APPRISE API MICROSERVICE DEPLOYMENT apiVersion: apps/v1 kind: Deployment metadata: name: apprise-api namespace: notifications spec: replicas: 1 selector: matchLabels: app: apprise-api template: metadata: labels: app: apprise-api spec: containers: - name: apprise image: docker.io/caronc/apprise:latest ports: - containerPort: 8000 resources: requests: memory: "256Mi" # Higher floor for initialization cpu: "50m" limits: memory: "1Gi" # Extra head room so it doesn't get OOMKilled cpu: "500m" --- apiVersion: v1 kind: Service metadata: name: apprise-svc namespace: notifications spec: ports: - port: 8000 targetPort: 8000 selector: app: apprise-api --- # 4. INGRESS ROUTING FOR GOTIFY WEB UI & MOBILE APP apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: gotify-ingress namespace: notifications annotations: cert-manager.io/cluster-issuer: "letsencrypt-production" nginx.ingress.kubernetes.io/backend-protocol: "HTTP" nginx.ingress.kubernetes.io/ssl-redirect: "true" # Mandatory for Gotify dynamic long-polling/websockets to keep mobile alerts instant nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" spec: ingressClassName: nginx tls: - secretName: gotify-tls-secret hosts: - gotify.needlestack.boo rules: - host: gotify.needlestack.boo http: paths: - path: / pathType: Prefix backend: service: name: gotify-svc port: number: 80