Repository Structure and Conventions
Relevant source files
- .justfile
- .taskfiles/Repository/Taskfile.yaml
- bootstrap/helmfile/apps.yaml
- docs/ai-context/CONVENTIONS.md
- kubernetes/apps/actions-runner-system/kustomization.yaml
- kubernetes/apps/actions-runner-system/namespace.yaml
- kubernetes/apps/cert-manager/kustomization.yaml
- kubernetes/apps/cert-manager/namespace.yaml
- kubernetes/apps/database/namespace.yaml
- kubernetes/apps/default/namespace.yaml
- kubernetes/apps/downloads/namespace.yaml
- kubernetes/apps/flux-system/namespace.yaml
- kubernetes/apps/kube-system/kustomization.yaml
- kubernetes/apps/media/namespace.yaml
- kubernetes/apps/network/kustomization.yaml
- kubernetes/apps/network/namespace.yaml
- kubernetes/apps/observability/namespace.yaml
- kubernetes/apps/security/namespace.yaml
- kubernetes/apps/storage/democratic-csi/app/kustomization.yaml
- kubernetes/apps/storage/democratic-csi/ks.yaml
- kubernetes/apps/storage/namespace.yaml
- kubernetes/apps/system-upgrade/namespace.yaml
- kubernetes/components/common/alerts/alertmanager/alert.yaml
- kubernetes/components/common/alerts/alertmanager/provider.yaml
- kubernetes/components/common/alerts/github-status/alert.yaml
- kubernetes/components/common/kustomization.yaml
- scripts/migrate-k8s-schemas.py
This page details the organizational hierarchy and technical standards of the home-ops repository. It covers the directory layout, the GitOps entry points for Flux CD, and the standardized patterns used for deploying applications and cross-cutting infrastructure components.
Top-Level Directory Layout
The repository is organized into distinct functional areas to separate infrastructure provisioning, cluster manifests, and operational tooling.
| Directory | Purpose |
|---|---|
kubernetes/ | Contains all Kubernetes manifests, organized by namespace and application. |
infrastructure/ | Holds IaC (Terraform) and configuration management (Ansible) for the underlying nodes. |
.taskfiles/ | Modular Taskfile definitions for the task runner. |
scripts/ | Utility scripts for maintenance, such as schema migration or secret generation. |
docs/ | Technical documentation and architectural context. |
Kubernetes Directory Structure
The kubernetes/ directory is the heart of the GitOps workflow. It follows a strict hierarchy:
kubernetes/apps/: Applications organized by namespace (e.g.,media/,network/,storage/).kubernetes/components/: Reusable Kustomize components for shared logic (e.g., Backups, OIDC).kubernetes/flux/: Core Flux CD configuration and bootstrap manifests.
Sources:kubernetes/apps/kube-system/kustomization.yaml1-17kubernetes/apps/network/kustomization.yaml1-16
Standard App Deployment Pattern
The repository enforces a “Standard App Pattern” to ensure consistency across dozens of services. This pattern relies on the bjw-s/app-template Helm chart and a specific directory layout.
Capsule: StandardAppPattern
Every standard application MUST use the bjw-s/app-template OCI repository. This encapsulates Deployment, Service, and Ingress/Route resources into a single values object.
Applications are also required to include specific annotations for discovery:
- Homepage:
gethomepage.devannotations for the dashboard. - Gatus:
gatus.home-operations.comannotations on Envoy Gateway routes for uptime monitoring.
Sources:docs/ai-context/CONVENTIONS.md14-43
Flux Kustomization Wrappers (ks.yaml)
Apps are not pointed to directly by the root Flux configuration. Instead, they use a ks.yaml wrapper. This file serves as the entry point and allows for dependency management.
[Flowchart Diagram]
Sources:docs/ai-context/CONVENTIONS.md50-68kubernetes/apps/kube-system/kustomization.yaml9-16
Shared Library: Components
The kubernetes/components/ directory contains shared Kustomize logic that is “injected” into applications via their ks.yaml. This avoids manual duplication of complex resources like backup jobs or authentication filters.
Component Injection
Instead of manually defining a ReplicationSource for backups, an app’s ks.yaml includes the volsync component. Configuration is passed via postBuild.substitute variables.
| Component | Function |
|---|---|
common | Basic alerts and standard repository references. |
volsync | Kopia-based volume backups to S3/NFS. |
envoy-oidc | Native OIDC authentication via Envoy Gateway. |
ext-auth | Generic ForwardAuth protection using Authentik. |
Sources:kubernetes/components/common/kustomization.yaml1-8docs/ai-context/CONVENTIONS.md126-148
Dependency Management and Reconciliation
To ensure the cluster starts correctly after a cold boot, explicit dependencies are defined using Flux’s dependsOn field.
Dependency Flow
The following diagram illustrates the boot order requirements for a typical application:
[Flowchart Diagram]
Sources:docs/ai-context/CONVENTIONS.md71-96
Technical Conventions
YAML and Metadata
- Schema Validation: All YAML files should include a
# yaml-language-server: $schema=...header to enable IDE validation. - Namespace Immutability: Critical namespaces (e.g.,
flux-system,storage,security) havekustomize.toolkit.fluxcd.io/prune: disabledto prevent accidental deletion of the entire cluster state.
Sources:kubernetes/apps/flux-system/namespace.yaml1-11kubernetes/apps/storage/namespace.yaml1-11
Security and Immutability
- Image Pinning: All container images MUST be pinned using their
@sha256:digest. Tags are insufficient as they are mutable. - Secret Encryption: All secrets are stored as
.sops.yamlfiles, encrypted withsopsusing the Age algorithm before being committed to Git. - Makejinja Delimiters: When using Jinja2 templates for infrastructure, the syntax
#{var}#is used to avoid conflicts with Helm’s{{var}}syntax.
Sources:docs/ai-context/CONVENTIONS.md153-206
Common Components in Namespaces
Each namespace typically includes a common component that provides standard Alert resources for Flux reconciliation failures, ensuring that any sync error is reported to Alertmanager or GitHub Status.
Sources:kubernetes/components/common/alerts/alertmanager/alert.yaml1-28kubernetes/components/common/alerts/github-status/alert.yaml1-13