From 8875cc4a36f222dac0f1b88db3b6a33e7a87a40a Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Mon, 19 Jan 2026 18:33:53 -0800 Subject: [PATCH] Add miniflux k8s manifests and ArgoCD app --- argocd/apps/miniflux.yaml | 28 +++++++++ argocd/manifests/miniflux/README.md | 59 +++++++++++++++++++ argocd/manifests/miniflux/deployment.yaml | 59 +++++++++++++++++++ .../manifests/miniflux/ingress-tailscale.yaml | 17 ++++++ argocd/manifests/miniflux/kustomization.yaml | 9 +++ argocd/manifests/miniflux/secret-db.yaml.tpl | 9 +++ argocd/manifests/miniflux/service.yaml | 13 ++++ 7 files changed, 194 insertions(+) create mode 100644 argocd/apps/miniflux.yaml create mode 100644 argocd/manifests/miniflux/README.md create mode 100644 argocd/manifests/miniflux/deployment.yaml create mode 100644 argocd/manifests/miniflux/ingress-tailscale.yaml create mode 100644 argocd/manifests/miniflux/kustomization.yaml create mode 100644 argocd/manifests/miniflux/secret-db.yaml.tpl create mode 100644 argocd/manifests/miniflux/service.yaml diff --git a/argocd/apps/miniflux.yaml b/argocd/apps/miniflux.yaml new file mode 100644 index 0000000..d277058 --- /dev/null +++ b/argocd/apps/miniflux.yaml @@ -0,0 +1,28 @@ +# Miniflux RSS Reader +# Requires: CloudNativePG PostgreSQL cluster and manual secret setup +# +# Before syncing, create the database secret: +# kubectl create namespace miniflux +# op inject -i argocd/manifests/miniflux/secret-db.yaml.tpl | kubectl apply -f - +# +# Note: The Tailscale Ingress may initially get hostname "feed-1" if "feed" is +# already claimed. After clearing the old service, delete the device from +# Tailscale admin to allow the Ingress to claim "feed". +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: miniflux + namespace: argocd +spec: + project: default + source: + repoURL: ssh://forgejo@indri.tail8d86e.ts.net:2200/eblume/blumeops.git + targetRevision: main + path: argocd/manifests/miniflux + destination: + server: https://kubernetes.default.svc + namespace: miniflux + syncPolicy: + syncOptions: + - CreateNamespace=true + # Manual sync only - no automated sync on git push diff --git a/argocd/manifests/miniflux/README.md b/argocd/manifests/miniflux/README.md new file mode 100644 index 0000000..fc77468 --- /dev/null +++ b/argocd/manifests/miniflux/README.md @@ -0,0 +1,59 @@ +# Miniflux Kubernetes Deployment + +RSS/Atom feed reader deployed via ArgoCD. + +## Prerequisites + +- CloudNativePG PostgreSQL cluster running in `databases` namespace +- Miniflux database and user created in PostgreSQL (from Phase 3 migration) +- Tailscale operator installed + +## Setup + +1. Create the namespace and database secret: + +```bash +kubectl create namespace miniflux +op inject -i argocd/manifests/miniflux/secret-db.yaml.tpl | kubectl apply -f - +``` + +2. Apply the ArgoCD application: + +```bash +kubectl apply -f argocd/apps/miniflux.yaml +argocd app sync miniflux +``` + +## Access + +- URL: https://feed.tail8d86e.ts.net +- Exposed via Tailscale Ingress + +## Configuration + +Environment variables in `deployment.yaml`: +- `POLLING_FREQUENCY`: How often to check feeds (minutes) +- `BATCH_SIZE`: Number of feeds to refresh per interval +- `CLEANUP_ARCHIVE_UNREAD_DAYS`: Days to keep unread entries +- `CLEANUP_ARCHIVE_READ_DAYS`: Days to keep read entries + +## Management + +```bash +# View logs +kubectl -n miniflux logs -f deployment/miniflux + +# Restart deployment +kubectl -n miniflux rollout restart deployment/miniflux + +# Check health +curl https://feed.tail8d86e.ts.net/healthcheck +``` + +## Database Connection + +Connects to PostgreSQL via internal k8s DNS: +`blumeops-pg-rw.databases.svc.cluster.local:5432` + +The database is also accessible externally via Tailscale at: +`pg.tail8d86e.ts.net:5432` diff --git a/argocd/manifests/miniflux/deployment.yaml b/argocd/manifests/miniflux/deployment.yaml new file mode 100644 index 0000000..3884e1d --- /dev/null +++ b/argocd/manifests/miniflux/deployment.yaml @@ -0,0 +1,59 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: miniflux + namespace: miniflux +spec: + replicas: 1 + selector: + matchLabels: + app: miniflux + template: + metadata: + labels: + app: miniflux + spec: + containers: + - name: miniflux + image: ghcr.io/miniflux/miniflux:latest + ports: + - containerPort: 8080 + env: + - name: DATABASE_URL + valueFrom: + secretKeyRef: + name: miniflux-db + key: url + - name: RUN_MIGRATIONS + value: "1" + - name: BASE_URL + value: "https://feed.tail8d86e.ts.net/" + - name: POLLING_FREQUENCY + value: "60" + - name: BATCH_SIZE + value: "100" + - name: POLLING_SCHEDULER + value: "entry_frequency" + - name: CLEANUP_ARCHIVE_UNREAD_DAYS + value: "180" + - name: CLEANUP_ARCHIVE_READ_DAYS + value: "60" + resources: + requests: + memory: "64Mi" + cpu: "50m" + limits: + memory: "256Mi" + cpu: "200m" + livenessProbe: + httpGet: + path: /healthcheck + port: 8080 + initialDelaySeconds: 10 + periodSeconds: 30 + readinessProbe: + httpGet: + path: /healthcheck + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 diff --git a/argocd/manifests/miniflux/ingress-tailscale.yaml b/argocd/manifests/miniflux/ingress-tailscale.yaml new file mode 100644 index 0000000..e384f66 --- /dev/null +++ b/argocd/manifests/miniflux/ingress-tailscale.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: miniflux-tailscale + namespace: miniflux + annotations: + tailscale.com/proxy-class: "crio-compat" +spec: + ingressClassName: tailscale + defaultBackend: + service: + name: miniflux + port: + number: 8080 + tls: + - hosts: + - feed diff --git a/argocd/manifests/miniflux/kustomization.yaml b/argocd/manifests/miniflux/kustomization.yaml new file mode 100644 index 0000000..80927eb --- /dev/null +++ b/argocd/manifests/miniflux/kustomization.yaml @@ -0,0 +1,9 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: miniflux + +resources: + - deployment.yaml + - service.yaml + - ingress-tailscale.yaml diff --git a/argocd/manifests/miniflux/secret-db.yaml.tpl b/argocd/manifests/miniflux/secret-db.yaml.tpl new file mode 100644 index 0000000..bfc5b43 --- /dev/null +++ b/argocd/manifests/miniflux/secret-db.yaml.tpl @@ -0,0 +1,9 @@ +# Apply with: op inject -i argocd/manifests/miniflux/secret-db.yaml.tpl | kubectl apply -f - +apiVersion: v1 +kind: Secret +metadata: + name: miniflux-db + namespace: miniflux +type: Opaque +stringData: + url: postgres://miniflux:{{ op://vg6xf6vvfmoh5hqjjhlhbeoaie/ns6wylqiuqgczpo7gq2akaxbti/password }}@blumeops-pg-rw.databases.svc.cluster.local:5432/miniflux?sslmode=disable diff --git a/argocd/manifests/miniflux/service.yaml b/argocd/manifests/miniflux/service.yaml new file mode 100644 index 0000000..a2cc8b0 --- /dev/null +++ b/argocd/manifests/miniflux/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: miniflux + namespace: miniflux +spec: + selector: + app: miniflux + ports: + - name: http + port: 8080 + targetPort: 8080 + protocol: TCP