Flux GitOps

Each release renders the Timoni module to plain manifests and pushes them to oci://forgejo.lihnet.mallon.ie/eagraiclainne/manifests (tags vX.Y.Z and latest), pinned to that release's server image. Flux pulls the artifact and reconciles it. This page is the complete stack — with the SQLite default there is no database service to run.

Prerequisites

  • A Kubernetes cluster with Flux installed (flux check passes)
  • kubectl pointed at it
  • A Forgejo token with package:read on forgejo.lihnet.mallon.ie

Namespace & registry access

One secret serves both consumers: Flux uses it to pull the manifest artifact, and the pods use it to pull the server image. The rendered manifests do not set imagePullSecrets, so attach it to the namespace's default ServiceAccount:

kubectl create namespace eagraiclainne

kubectl -n eagraiclainne create secret docker-registry gitea-registry-auth \
  --docker-server=forgejo.lihnet.mallon.ie \
  --docker-username=your-username \
  --docker-password=your-token

kubectl -n eagraiclainne patch serviceaccount default \
  -p '{"imagePullSecrets":[{"name":"gitea-registry-auth"}]}'

Storage

There is no database step. The rendered manifests carry the SQLite default: a 1Gi PVC (eagraiclainne-data) mounted at /data, the server owning /data/eagraiclainne.db and applying its schema on boot. Single replica, Recreate rollouts — one writer, by design. If you want the PostgreSQL backend instead, deploy via Timoni, whose values expose the storage engine.

OCIRepository & Kustomization

# eagraiclainne-flux.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: OCIRepository
metadata:
  name: eagraiclainne
  namespace: eagraiclainne
spec:
  interval: 10m
  url: oci://forgejo.lihnet.mallon.ie/eagraiclainne/manifests
  ref:
    tag: v1.0.0         # or semver: ">=1.0.0" to track releases
  secretRef:
    name: gitea-registry-auth
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: eagraiclainne
  namespace: eagraiclainne
spec:
  interval: 10m
  retryInterval: 30s
  timeout: 5m
  targetNamespace: eagraiclainne
  sourceRef:
    kind: OCIRepository
    name: eagraiclainne
  path: "./"
  prune: true
  wait: true
  patches:
    # Since v0.6.0 the rendered manifests ship with telemetry off (stdout
    # exporters). To export to your own collector, add the env on the
    # container — an explicit env entry outranks the envFrom ConfigMap.
    # Drop this block entirely if stdout logs are all you want.
    - target:
        kind: Deployment
        name: eagraiclainne
      patch: |
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: eagraiclainne
        spec:
          template:
            spec:
              containers:
                - name: server
                  env:
                    - name: EAG_OTLP_ENDPOINT
                      value: "lgtm.observability:4317"
                    - name: EAG_OTLP_INSECURE
                      value: "true"
kubectl apply -f eagraiclainne-flux.yaml
The same patches block is the lever for any other tweak to the rendered manifests — replicas, resources, extra EAG_* env. If you find yourself patching much, deploy via Timoni instead and set real values.

Verify

flux -n eagraiclainne get sources oci
flux -n eagraiclainne get kustomizations
kubectl -n eagraiclainne rollout status deployment/eagraiclainne
kubectl -n eagraiclainne port-forward svc/eagraiclainne 8080:8080 &
curl -sS http://localhost:8080/ | head -c 200

Then expose the Service through your ingress of choice and open it — first sign-in takes it from there. Upgrades are a tag edit (or automatic under a semver range). Schema changes apply themselves when the new pod boots.