# AGENTS.md > [!NOTE] > This file describes the constraints and conventions for the `k8s` directory, which contains deployments for the **haumdaucher.de** Kubernetes cluster. ## Project Overview This directory contains the Kubernetes manifests and Helm charts for a single-node Kubernetes cluster (Haumdaucher). * **Domain**: `*.haumdaucher.de` * **Orchestration**: Self-managed Kubernetes (single node). * **Ingress**: `ingress-nginx` * **SSL**: `cert-manager` (LetsEncrypt) ## Directory Structure * **Top-level folders**: Each folder corresponds to a Kubernetes **namespace**. * Example: `mailu/` contains resources for the `mailu` namespace. * **Documentation**: `README.md` is the **authoritative source** for deployment commands. Always check it before running commands. ## Code Style & Conventions * **Helm Version**: Helm 3 (`helm`) is used. * **Implementation Order**: Top-down. * **Naming**: Namespaces matches folder names. * **Formatting**: Standard YAML conventions. ## Security & Secrets > [!IMPORTANT] > **Git-Crypt is enforced.** > Do not touch encrypted files unless you have the key and know how to unlock them. **Encrypted File Patterns**: * `*.secret` * `*.secret.yaml` * `*.secret.values` * `*.secret.sh` ## Deployment Instructions **Always consult `README.md` first.** Deployments vary between Helm charts and raw manifests. ### Common Patterns * **Helm**: ```bash helm upgrade --install -n -f ``` * **Kubectl**: ```bash kubectl apply -f /.yaml ``` ### Operational Tasks * **Cleanup Error Pods**: ```bash kubectl get pods | grep Error | cut -d' ' -f 1 | xargs kubectl delete pod ``` ## Ingress Configuration Ingress resources **must** follow these strict conventions to work with the cluster's ingress controller (`nginx`) and certificate manager (`cert-manager`). ### Annotations All Ingress resources must include: ```yaml annotations: kubernetes.io/ingress.class: "nginx" cert-manager.io/cluster-issuer: "letsencrypt-prod" kubernetes.io/tls-acme: "true" # Standard nginx tweaks nginx.ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/force-ssl-redirect: "true" ``` ### Hostnames & TLS * **Domain**: Use a subdomain of `haumdaucher.de` or `moritzgraf.de`. * **TLS Secret Name**: Must use **hyphens** instead of dots. * Pattern: `--` * Example: `n8n.moritzgraf.de` -> `n8n-moritzgraf-de` ### Example ```yaml spec: ingressClassName: nginx tls: - hosts: - n8n.moritzgraf.de secretName: n8n-moritzgraf-de rules: - host: n8n.moritzgraf.de http: paths: - path: / pathType: Prefix backend: service: name: n8n port: number: 5678 ``` ## Storage / Persistence The cluster uses **OpenEBS** for dynamic local storage provisioning. ### PersistentVolumeClaims (PVC) * **Provisioner**: `openebs.io/local` (or similar, managed via `openebs-hostpath`). * **StorageClass**: `openebs-hostpath`. * **AccessMode**: Typically `ReadWriteOnce` (RWO) as it's local storage. To request storage, simply create a PVC or configure Helm charts to use the default storage class (or explicitly `openebs-hostpath`). ```yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: my-data spec: storageClassName: openebs-hostpath accessModes: - ReadWriteOnce resources: requests: storage: 1Gi ``` ## Deployment Constraints * **Resources**: Always define `requests` and `limits` for CPU and Memory to ensure fair scheduling on the single node. * **Namespaces**: Every application gets its own namespace. * **Secrets**: Encrypt all secrets using `git-crypt`.