diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..e7b4860 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,15 @@ +{ + "permissions": { + "allow": [ + "Bash(git -C /Users/alice/Projects/private/homelab/apps log --oneline -10)", + "Bash(git -C /Users/alice/Projects/private/homelab/apps remote -v)", + "Bash(git -C /Users/alice/Projects/private/homelab/apps config --list)", + "Bash(ls:*)", + "Bash(git -C /Users/alice/Projects/private/homelab/apps log --all --oneline --decorate -15)", + "Bash(git -C /Users/alice/Projects/private/homelab/apps branch -a)", + "Bash(helm dependency:*)", + "Bash(helm lint:*)", + "Bash(helm template:*)" + ] + } +} diff --git a/.gitignore b/.gitignore index ce57049..66bf927 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ charts/*.tgz __pycache__/ **/Chart.lock + +*-local-secret.yaml diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..aa4a2d8 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,100 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Kubernetes Helm-based homelab application deployment system using ArgoCD for GitOps. Contains 40+ containerized applications deployed via Helm charts with a shared common library to minimize template duplication. + +## Commands + +```bash +# Validate YAML files +yamllint . + +# Helm chart operations (run from chart directory) +helm dependency build # Fetch common library dependency +helm lint . # Validate chart syntax +helm template . --set globals.environment=prod --set globals.domain=example.com + +# Utility scripts +./scripts/migrate_database.py [--clean] # PostgreSQL migration +./scripts/sync_pvc_with_host.sh # PVC sync +``` + +## Architecture + +### Directory Structure +- `apps/charts/` - Individual application Helm charts (deployed to `prod` namespace) +- `apps/common/` - Shared Helm library chart with standardized templates +- `apps/root/` - ArgoCD ApplicationSet for auto-discovery +- `shared/charts/` - Shared infrastructure services (authentik, nats) +- `scripts/` - Python/Bash utility scripts for database migration and PVC sync + +### Deployment Model +Three ArgoCD ApplicationSets auto-discover charts from their respective `charts/` directories. Folders suffixed with `.disabled` are excluded from deployment. + +### Common Library Pattern +Most charts use the common library (`apps/common/`) which provides standardized templates. A minimal chart needs: + +1. `Chart.yaml` with common library dependency: +```yaml +apiVersion: v2 +version: 1.0.0 +name: my-app +dependencies: + - name: common + version: 1.0.0 + repository: file://../../common +``` + +2. Standardized `values.yaml` (see `apps/common/README.md` for full structure) + +3. Template files that include common helpers: +```yaml +# templates/deployment.yaml +{{ include "common.deployment" . }} +``` + +Or use single file with `{{ include "common.all" . }}` to render all resources automatically. + +### Key Templates +- `common.deployment` - Deployment with health probes, volumes, init containers +- `common.service` - Service(s) with port mapping +- `common.pvc` - Persistent volume claims +- `common.virtualService` - Istio routing (public/private gateways) +- `common.oidc` - Authentik OIDC client registration +- `common.database` - PostgreSQL database provisioning +- `common.externalSecrets` - Password generators and secret templates + +### Placeholders in values.yaml +- `{release}` - Release name +- `{namespace}` - Release namespace +- `{fullname}` - Full app name +- `{subdomain}` - App subdomain (from `subdomain` value) +- `{domain}` - Global domain +- `{timezone}` - Global timezone + +### Secret Naming Conventions +- OIDC credentials: `{release}-oidc-credentials` (clientId, clientSecret, issuer) +- Database connection: `{release}-connection` (url, host, port, user, password) +- Generated secrets: `{release}-secrets` + +## Conventions + +- Chart and release names use kebab-case +- All container images pinned by SHA256 digest (Renovate manages updates) +- Storage uses `persistent` storageClassName +- Istio VirtualServices route via public/private gateways +- Deployment strategy: `Recreate` for stateful apps, `RollingUpdate` for stateless + +## YAML Style +- Max line length: 120 characters +- Indentation: 2 spaces +- Truthy values: `true`, `false`, `on`, `off` + +## Documentation +- `AGENTS.md` - Chart creation guidelines +- `apps/common/README.md` - Complete common library reference +- `apps/common/MIGRATION.md` - Guide for migrating charts to common library +- `apps/common/TEMPLATING.md` - Placeholder system documentation diff --git a/apps/charts/glados/Chart.yaml b/apps/charts/glados/Chart.yaml new file mode 100644 index 0000000..e2817ae --- /dev/null +++ b/apps/charts/glados/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +version: 1.0.0 +name: glados +dependencies: + - name: common + version: 1.0.0 + repository: file://../../common diff --git a/apps/charts/glados/templates/deployment.yaml b/apps/charts/glados/templates/deployment.yaml new file mode 100644 index 0000000..4508e33 --- /dev/null +++ b/apps/charts/glados/templates/deployment.yaml @@ -0,0 +1 @@ +{{ include "common.deployment" . }} diff --git a/apps/charts/glados/templates/pvc.yaml b/apps/charts/glados/templates/pvc.yaml new file mode 100644 index 0000000..379bad9 --- /dev/null +++ b/apps/charts/glados/templates/pvc.yaml @@ -0,0 +1 @@ +{{ include "common.pvc" . }} diff --git a/apps/charts/glados/values.yaml b/apps/charts/glados/values.yaml new file mode 100644 index 0000000..f648a89 --- /dev/null +++ b/apps/charts/glados/values.yaml @@ -0,0 +1,57 @@ +image: + repository: ghcr.io/morten-olsen/agentic + tag: 0.0.21 + pullPolicy: Always + +subdomain: glados + +deployment: + strategy: Recreate + replicas: 1 + +container: + ports: + - name: http + port: 8080 + protocol: TCP + +initContainers: + - name: fix-permissions + image: busybox + command: ["sh", "-c", "chown -R 1000:1000 /data"] + volumeMounts: + - name: data + mountPath: /data + securityContext: + runAsUser: 0 + +volumes: + - name: data + mountPath: /data + persistentVolumeClaim: data + +persistentVolumeClaims: + - name: data + size: 10Gi + +env: + GLADOS_LLM_MODEL: + valueFrom: + secretKeyRef: + name: glados-secrets + key: GLADOS_LLM_MODEL + GLADOS_LLM_API_KEY: + valueFrom: + secretKeyRef: + name: glados-secrets + key: GLADOS_LLM_API_KEY + GLADOS_TELEGRAM_BOT_TOKEN: + valueFrom: + secretKeyRef: + name: glados-secrets + key: GLADOS_TELEGRAM_BOT_TOKEN + GLADOS_TELEGRAM_OWNER_ID: + valueFrom: + secretKeyRef: + name: glados-secrets + key: GLADOS_TELEGRAM_OWNER_ID