# FlowerCore Update Center # GitOps adoption of the live fc-updater namespace after PUB-1/PUB-3. # Runtime credentials remain in existing K8s Secrets; do not store them here. --- apiVersion: v1 kind: Namespace metadata: name: fc-updater labels: app.kubernetes.io/part-of: flowercore --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: updatecenter-data namespace: fc-updater labels: app.kubernetes.io/name: updatecenter-web app.kubernetes.io/part-of: flowercore spec: accessModes: - ReadWriteOnce storageClassName: longhorn volumeMode: Filesystem resources: requests: # Sized for fleet bundle storage (LocalFsBundleStore.MaxTotalBytes # soft cap at 25 GiB per project_uc_remaining_4_apps_signed_2026_05_06). # Mike Bundle alone is ~5.1 GiB; cluster live capacity is already # 20 GiB after a manual expand. PVCs cannot shrink, so git must track # at least the live size to avoid the OutOfSync loop. storage: 25Gi --- apiVersion: apps/v1 kind: Deployment metadata: name: updatecenter-web namespace: fc-updater labels: app: updatecenter-web app.kubernetes.io/name: updatecenter-web app.kubernetes.io/part-of: flowercore spec: replicas: 1 revisionHistoryLimit: 3 strategy: # SQLite + local bundle storage live on a single RWO PVC. Recreate avoids # two pods overlapping the same write path during future image bumps. type: Recreate selector: matchLabels: app: updatecenter-web template: metadata: labels: app: updatecenter-web spec: nodeName: rke2-server containers: - name: web image: localhost/fc-updater-web:v20260507-public-privacy imagePullPolicy: Never ports: - containerPort: 8080 name: http env: - name: ASPNETCORE_URLS value: http://+:8080 - name: FlowerCore__Updater__Database__Provider value: sqlite - name: FlowerCore__Updater__Database__ConnectionString value: Data Source=/data/updatecenter.db - name: FlowerCore__Updater__BundleStorage__LocalFs__RootDirectory value: /data/bundles - name: FlowerCore__Updater__PublicShares__RequirePublicVisibilityOnPublicHosts value: "true" - name: FlowerCore__Updater__PublicShares__Links__0__Code value: 8f3c2a9e7d41 - name: FlowerCore__Updater__PublicShares__Links__0__AppId value: flowercore.faith-ai-mike - name: FlowerCore__Updater__PublicShares__Links__0__Channel value: stable - name: FlowerCore__Updater__PublicShares__Links__0__RuntimeId value: win-x64 - name: FlowerCore__Updater__PublicShares__Links__0__DisplayName value: Faith AI Mike Edition - name: FlowerCore__Updater__PublicShares__Links__0__Headline value: Faith AI Mike Edition - name: FlowerCore__Updater__PublicShares__Links__0__Description value: Private release link for Mike's Faith AI bundle. - name: FlowerCore__Updater__Auth__Bootstrap__Enabled value: "true" - name: FlowerCore__Updater__Auth__Bootstrap__Username valueFrom: secretKeyRef: name: updater-bootstrap-auth key: username - name: FlowerCore__Updater__Auth__Bootstrap__Password valueFrom: secretKeyRef: name: updater-bootstrap-auth key: password - name: FlowerCore__Updater__Auth__Bootstrap__SigningKey valueFrom: secretKeyRef: name: updater-bootstrap-auth key: signing-key - name: FlowerCore__Updater__Signing__AutoSignOnPublish value: "true" - name: FlowerCore__Updater__Signing__RequireSignatureOnPublish value: "true" - name: FlowerCore__Updater__Signing__PfxBase64 valueFrom: secretKeyRef: name: updater-signing key: pfx-base64 - name: FlowerCore__Updater__Signing__PfxPassword valueFrom: secretKeyRef: name: updater-signing key: pfx-password - name: FlowerCore__Updater__Signing__OpItemReference value: op://FlowerCore/step-ca-codesign - name: FlowerCore__Updater__Signing__TrustAnchorPath value: /etc/flowercore-updater/signing/root-ca.pem - name: FlowerCore__Updater__GitHub__Token valueFrom: secretKeyRef: name: updater-webhooks key: github-token - name: FlowerCore__Updater__GitHub__WebhookSecret valueFrom: secretKeyRef: name: updater-webhooks key: github-webhook-secret - name: FlowerCore__Updater__Gitea__Token valueFrom: secretKeyRef: name: updater-webhooks key: gitea-token - name: FlowerCore__Updater__Gitea__WebhookSecret valueFrom: secretKeyRef: name: updater-webhooks key: gitea-webhook-secret readinessProbe: tcpSocket: port: http initialDelaySeconds: 10 periodSeconds: 15 livenessProbe: tcpSocket: port: http initialDelaySeconds: 30 periodSeconds: 30 volumeMounts: - name: data mountPath: /data - name: signing mountPath: /etc/flowercore-updater/signing readOnly: true volumes: - name: data persistentVolumeClaim: claimName: updatecenter-data - name: signing secret: secretName: updater-signing items: - key: root-ca.pem path: root-ca.pem --- apiVersion: v1 kind: Service metadata: name: updatecenter-web namespace: fc-updater labels: app: updatecenter-web app.kubernetes.io/name: updatecenter-web app.kubernetes.io/part-of: flowercore spec: type: ClusterIP selector: app: updatecenter-web ports: - name: http port: 8080 targetPort: http --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: updatecenter-web-tls namespace: fc-updater spec: secretName: updatecenter-web-tls issuerRef: name: step-ca-acme kind: ClusterIssuer dnsNames: - updatecenter.iamworkin.lan - updates.iamworkin.lan --- apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: updatecenter-web-internal-tls namespace: fc-updater spec: secretName: updatecenter-web-internal-tls issuerRef: name: step-ca-acme kind: ClusterIssuer dnsNames: - updatecenter-internal.iamworkin.lan --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: updatecenter-web namespace: fc-updater spec: entryPoints: - web - websecure routes: - match: (Host(`updatecenter.iamworkin.lan`) || Host(`updates.iamworkin.lan`)) && (Method(`GET`) || Method(`HEAD`) || Method(`POST`) || Method(`OPTIONS`)) kind: Rule services: - name: updatecenter-web port: 8080 tls: secretName: updatecenter-web-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: updatecenter-web-internal namespace: fc-updater spec: entryPoints: - web - websecure routes: - match: Host(`updatecenter-internal.iamworkin.lan`) kind: Rule services: - name: updatecenter-web port: 8080 tls: secretName: updatecenter-web-internal-tls --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: updatecenter-web-public namespace: fc-updater spec: entryPoints: - websecure routes: - match: (Host(`update.flowercore.io`) || Host(`updates.flowercore.io`)) && (Method(`GET`) || Method(`HEAD`) || Method(`POST`) || Method(`OPTIONS`)) kind: Rule services: - name: updatecenter-web port: 8080 tls: secretName: cf-origin-flowercore-io