<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <docs>https://blogs.law.harvard.edu/tech/rss</docs>
    <title>Flux on Fuchsbau</title>
    <link>https://this-is-fine.io/tags/flux/</link>
    <description>Recent content in Flux on Fuchsbau</description>
    <image>
      <title>Flux on Fuchsbau</title>
      <link>https://this-is-fine.io/tags/flux/</link>
      <url>https://source.unsplash.com/2000x1322/?fox</url>
    </image>
    <ttl>1440</ttl>
    <generator>Hugo 0.125.4</generator>
    <language>de-DE</language>
    <lastBuildDate>Wed, 20 May 2026 22:26:11 UT</lastBuildDate>
    <atom:link href="https://this-is-fine.io/tags/flux/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Running Mastodon in the Lab (Fediverse Stack)</title>
      <link>https://this-is-fine.io/posts/20251121-mastodon-fediverse/</link>
      <pubDate>Fri, 21 Nov 2025 11:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251121-mastodon-fediverse/</guid>
      <description>Mastodon is a federated microblog server: local timelines plus ActivityPub links to other instances. Running it means managing state (PostgreSQL, media, cache) and edge (HTTPS and /.well-known for discovery). The lab instance is at https://mastodon.this-is-fine.social.
It ships as a Helm release through Flux, same GitOps style as the rest of the lab.
Federation is the interesting part socially and technically. Other servers discover you through HTTPS hostnames and /.well-known endpoints; if DNS or TLS drifts, federation breaks even when the pod is healthy. That is why the lab treats edge (Gateway API, cert-manager, external-dns) as first-class dependencies, not an afterthought.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <content:encoded><![CDATA[Mastodon is a federated microblog server: local timelines plus ActivityPub links to other instances. Running it means managing state (PostgreSQL, media, cache) and edge (HTTPS and /.well-known for discovery). The lab instance is at https://mastodon.this-is-fine.social.
It ships as a Helm release through Flux, same GitOps style as the rest of the lab.
Federation is the interesting part socially and technically. Other servers discover you through HTTPS hostnames and /.well-known endpoints; if DNS or TLS drifts, federation breaks even when the pod is healthy. That is why the lab treats edge (Gateway API, cert-manager, external-dns) as first-class dependencies, not an afterthought.
Software map Need Project Learn App Mastodon Admin setup SQL CloudNative-PG Postgres operator Cache Dragonfly Redis-compatible cache Media Rook-Ceph RGW S3 API via ObjectBucketClaim Ingress Gateway API HTTPRoute on shared-gateway-external TLS cert-manager ACME for *.this-is-fine.social Secrets External Secrets SMTP, VAPID, secretKeyBase from Vault Request path Internet -&amp;gt; mastodon.this-is-fine.social (HTTPRoute) -&amp;gt; Mastodon (Helm) PostgreSQL (CNPG) Dragonfly (cache) object storage (Rook S3) Federation needs stable DNS and valid TLS — see Mastodon federation notes. SMTP, VAPID, and secretKeyBase sync from Vault through External Secrets, like other lab apps.
Media attachments land in object storage (Rook’s S3-compatible endpoint) so the web pods do not fill local disks with uploads. PostgreSQL holds accounts and timelines; Dragonfly backs Redis-shaped caching Mastodon expects. None of those pieces are optional if you want a instance that survives real use.
Capacity and backups Mastodon is not a small Deployment: size CPU, memory, and database disk from upstream guidance. Database backups (CNPG) and optional PVC backups (VolSync) are separate choices.
Other fediverse apps (for example Pixelfed) can share the namespace; this article stays on Mastodon.
Further reading: ActivityPub, Mastodon releases.
]]></content:encoded>
    </item>
    <item>
      <title>VolSync, Volume Snapshots, and Restic Off-Site Backups</title>
      <link>https://this-is-fine.io/posts/20251121-volsync-restic-backups/</link>
      <pubDate>Fri, 21 Nov 2025 08:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251121-volsync-restic-backups/</guid>
      <description>Stateful apps need point-in-time copies and a copy off the cluster. The lab uses VolSync with the restic mover: Kubernetes creates a VolumeSnapshot, VolSync runs restic against it, and encrypted data lands in a remote repository. The restic URL and password live in Vault and reach the cluster through External Secrets.
VolSync sits in the middle: you already run the CSI snapshot controller and a storage class that supports snapshots (Rook-Ceph block volumes in the lab). VolSync watches a ReplicationSource, triggers on a schedule, and spins up a short-lived mover job. You get off-site copies without shelling into pods to run restic by hand.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <content:encoded><![CDATA[Stateful apps need point-in-time copies and a copy off the cluster. The lab uses VolSync with the restic mover: Kubernetes creates a VolumeSnapshot, VolSync runs restic against it, and encrypted data lands in a remote repository. The restic URL and password live in Vault and reach the cluster through External Secrets.
VolSync sits in the middle: you already run the CSI snapshot controller and a storage class that supports snapshots (Rook-Ceph block volumes in the lab). VolSync watches a ReplicationSource, triggers on a schedule, and spins up a short-lived mover job. You get off-site copies without shelling into pods to run restic by hand.
Building blocks Software Role snapshot-controller CSI snapshot API VolSync ReplicationSource and movers (restic, rsync, &amp;hellip;) restic Encrypted, deduplicated backup format Rook-Ceph Block volumes and snapshot class Data path app PVC -&amp;gt; ReplicationSource (schedule, e.g. @daily) -&amp;gt; VolumeSnapshot (CSI) -&amp;gt; restic mover -&amp;gt; remote repository Retention and prune settings sit on the ReplicationSource. See VolSync restic usage.
GitOps pattern A common Flux app installs the VolSync operator once. Each app includes the shared template and sets dependsOn: volsync. Flux postBuild sets APP, capacity, schedule, and storage class — same mechanism as domains in the GitOps overview. Per-app repository paths append ${APP} at runtime so one leaked credential does not cover every volume.
Opt-in is intentional: not every Deployment needs a PVC backup. Stateless replicas and caches stay out unless you add the template. That keeps mover jobs and repository size predictable.
Example: opt in an app The bundle in k8s/templates/volsync/ ships a PVC, ExternalSecret, ReplicationSource, and ReplicationDestination.
1. Kustomize — include the template beside the workload:
# app/kustomization.yaml resources: - ../../../../../../templates/volsync - deployment.yaml 2. Flux — depend on the operator and substitute variables:
# ks.yaml (Flux Kustomization) spec: dependsOn: - name: volsync postBuild: substitute: APP: my-app VOLSYNC_SCHEDULE: &amp;#34;@daily&amp;#34; VOLSYNC_CAPACITY: 5Gi VOLSYNC_CACHE_CAPACITY: 5Gi VOLSYNC_STORAGECLASS: &amp;#34;${BLOCK_STORAGE_CLASS}&amp;#34; VOLSYNC_SNAPSHOTCLASS: &amp;#34;${BLOCK_STORAGE_CLASS}&amp;#34; 3. Deployment — mount the PVC the template creates (claimName must match APP):
volumes: - name: data persistentVolumeClaim: claimName: my-app Flux renders ${APP} on the ReplicationSource and sets repository: my-app-volsync-secret (restic settings from Vault via ExternalSecret):
apiVersion: volsync.backube/v1alpha1 kind: ReplicationSource metadata: name: &amp;#34;${APP}&amp;#34; spec: sourcePVC: &amp;#34;${APP}&amp;#34; trigger: schedule: &amp;#34;${VOLSYNC_SCHEDULE:-@weekly}&amp;#34; restic: copyMethod: Snapshot repository: &amp;#34;${APP}-volsync-secret&amp;#34; Full field list: ReplicationSource API.
Why snapshots? A snapshot avoids stopping the pod and works well with Ceph’s CSI driver. The mover reads consistent blocks from the snapshot volume instead of the live mount, which matters when the app keeps writing logs or database pages.
Restore is the mirror path: a ReplicationDestination pulls from restic into a target PVC when you need to recover or clone. The lab wraps that in task helpers; semantics follow the VolSync user guide.
]]></content:encoded>
    </item>
    <item>
      <title>ZeroClaw in the Lab: a GitOps Agent on Matrix</title>
      <link>https://this-is-fine.io/posts/20251120-zeroclaw-in-the-lab/</link>
      <pubDate>Thu, 20 Nov 2025 09:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251120-zeroclaw-in-the-lab/</guid>
      <description>ZeroClaw (nickname Claw) is a small AI agent for cluster work: check Flux status, explain failing pods, dry-run Renovate, draft Git patches. It shares the same GitOps monorepo as the cluster — it is not a second control plane.
You talk to it on Matrix at matrix.this-is-fine.social. Web fetches go through MCP to a Scrapling sidecar instead of built-in browser tools, so there is one audited path for HTTP.
The agent is deliberately ops-focused. It is not a general chatbot for the public internet; it reads cluster state, follows skills checked into Git, and proposes changes that still pass human review. That keeps expectations aligned with what automation can safely do inside a production-shaped lab.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <content:encoded><![CDATA[ZeroClaw (nickname Claw) is a small AI agent for cluster work: check Flux status, explain failing pods, dry-run Renovate, draft Git patches. It shares the same GitOps monorepo as the cluster — it is not a second control plane.
You talk to it on Matrix at matrix.this-is-fine.social. Web fetches go through MCP to a Scrapling sidecar instead of built-in browser tools, so there is one audited path for HTTP.
The agent is deliberately ops-focused. It is not a general chatbot for the public internet; it reads cluster state, follows skills checked into Git, and proposes changes that still pass human review. That keeps expectations aligned with what automation can safely do inside a production-shaped lab.
Concepts worth knowing Topic Pointer GitOps agent Policy and skills in Git; credentials mounted read-only at runtime Agent Skills Short SKILL.md playbooks instead of huge prompts MCP Sidecar on loopback; the agent calls tools over HTTP Matrix E2EE Crypto state on a PVC — not inside the workspace seed image Skills are the main teaching device. Each skill is a short markdown playbook (flux debugging, storage checks, Renovate dry-runs) so the model reaches for a documented procedure instead of improvising shell one-liners.
Flow operator -&amp;gt; Matrix chat -&amp;gt; ZeroClaw pod (kubectl, flux, skills) -&amp;gt; MCP -&amp;gt; Scrapling (web) -&amp;gt; git patch on forge -&amp;gt; merge -&amp;gt; Flux reconciles Pod layout init: copy OCI workspace seed onto PVC containers: zeroclaw (daemon) scrapling :8000 (MCP) mounts: kubeconfig, registry auth, matrix, sops-age HTTPRoute: claw.this-is-fine.internal An ImageVolume refreshes workspace files from oci.this-is-fine.io/zeroclaw/workspace on each start. Conversation memory and Matrix state/ stay on the PVC. API access to other clusters uses normal pod DNS and *.tif.internal (see the tailnet post).
Forge CI builds and signs images — Cosign and Kyverno. The workspace image can refresh on every pod start while chat history and Matrix crypto keys persist on disk, which is the usual split between replaceable config and state you must not wipe casually.
Deliberate limits Changes go through a cloned repo and review, not edits on the live PVC tree. Built-in web_fetch and browser tools are disabled; Scrapling handles the web. Effective permissions follow kubeconfig RBAC; AGENTS.md gates destructive actions. Claw is a readable layer on top of Flux: ask in chat, confirm with flux get, land the fix in Git. If Flux says the cluster is healthy but an app misbehaves, the agent still has to read events and logs like anyone else — it just lowers the friction for doing that often.
]]></content:encoded>
    </item>
    <item>
      <title>Lab GitOps: Talos, Flux, and a Monorepo</title>
      <link>https://this-is-fine.io/posts/20251120-lab-gitops-flux-talos/</link>
      <pubDate>Thu, 20 Nov 2025 08:00:00 UT</pubDate>
      <dc:creator>ff0x</dc:creator>
      <guid>https://this-is-fine.io/posts/20251120-lab-gitops-flux-talos/</guid>
      <description>The lab is a Kubernetes testbed: try cluster layouts here before they go to production. After a short manual bootstrap, Flux keeps the cluster in sync with Git — the usual GitOps loop of declared state in version control and controllers that apply diffs.
Nodes run Talos Linux on Turing Pi RK1 boards. Images come from the Talos Image Factory (metal-arm64, sbc-rockchip / turingrk1). Talos keeps the node OS small and API-driven: you do not SSH in to patch packages. That pushes complexity into Kubernetes manifests, which fits a GitOps workflow.
Everything after the first bootstrap lives in one monorepo: cluster overlays, shared operators, Helm charts, and application kustomizations. Talos machine config (talconfig) is versioned there too, but applied with talosctl, not Flux. Drawing that line clearly avoids pretending the entire world is reconciled from Git when the hypervisor and disk layout are still operator steps.
</description>
      <category domain="https://this-is-fine.io/categories/infrastructure">Infrastructure</category>
      <content:encoded><![CDATA[The lab is a Kubernetes testbed: try cluster layouts here before they go to production. After a short manual bootstrap, Flux keeps the cluster in sync with Git — the usual GitOps loop of declared state in version control and controllers that apply diffs.
Nodes run Talos Linux on Turing Pi RK1 boards. Images come from the Talos Image Factory (metal-arm64, sbc-rockchip / turingrk1). Talos keeps the node OS small and API-driven: you do not SSH in to patch packages. That pushes complexity into Kubernetes manifests, which fits a GitOps workflow.
Everything after the first bootstrap lives in one monorepo: cluster overlays, shared operators, Helm charts, and application kustomizations. Talos machine config (talconfig) is versioned there too, but applied with talosctl, not Flux. Drawing that line clearly avoids pretending the entire world is reconciled from Git when the hypervisor and disk layout are still operator steps.
Stack (what each piece teaches) Piece Learn more Talos API-driven, immutable nodes — no SSH shell on hosts Flux GitRepository, Kustomization, HelmRelease Kustomize &#43; Helm Overlays vs charts — choose per app SOPS &#43; AGE Encrypted secrets in Git; decrypted at reconcile Vault &#43; External Secrets Long-lived credentials outside plain Git Cilium CNI; BGP can advertise service LoadBalancer ranges Gateway API &#43; Envoy Gateway HTTP and TCP ingress cert-manager ACME and in-cluster CAs Rook-Ceph Block, filesystem, and S3-style storage Renovate Automated bumps for image and chart pins Bootstrap, then GitOps flash Talos (RK1) -&amp;gt; talosctl bootstrap -&amp;gt; flux bootstrap Git becomes the source of truth One monorepo holds shared common/ operators and per-cluster overlays. The GitRepository uses an ignore block so Flux does not clone agent code, docs, or unrelated trees on every reconcile. That keeps sync intervals reasonable on modest hardware.
How a change rolls out Git branch (main) -&amp;gt; GitRepository (poll) -&amp;gt; common layer (Flux, Cilium, cert-manager, ...) -&amp;gt; repo definitions (Helm/OCI) -&amp;gt; app overlays (your workloads) -&amp;gt; HelmRelease, HTTPRoute, PVC, ExternalSecret, ... dependsOn orders that graph (storage before apps, for example). postBuild substitution reads common-config and fills hostnames — this-is-fine.io, this-is-fine.social, this-is-fine.internal, tif.internal — so the same manifests work on every cluster without per-site forks.
Bootstrap secrets use SOPS; runtime passwords and tokens live in Vault and sync through External Secrets. The split mirrors how often values change: bootstrap keys rotate rarely; database passwords and API tokens churn more often and are easier to audit in Vault.
Renovate watches the same repo and opens bump PRs for container images, Helm charts, and Talos or Flux pins. That closes the loop so the lab does not silently fall behind upstream.
DNS zones (quick map) this-is-fine.io public internet (ACME, external gateway) this-is-fine.social fediverse this-is-fine.internal lab UIs (internal gateway, Vault PKI) tif.internal Headscale tailnet (MagicDNS) Takeaway Talos limits the OS problem; Flux limits the “what is actually deployed?” problem. Together they give a repeatable lab: flash boards, bootstrap once per cluster, then iterate by merge request like any other software project.
More on this setup: ZeroClaw, Envoy Gateway, Cilium BGP, Zot, Pocket ID, backups, tailnet, image signing.
]]></content:encoded>
    </item>
  </channel>
</rss>
