# OneLab GitOps (k3s + Argo CD) This directory holds the **Helm chart** that replaces `docker stack deploy` from the legacy Swarm installer (`app/docker-compose.yml`). ## Layout | Path | Purpose | |------|---------| | `charts/onelab` | Helm chart (StatefulSets, Deployments, Services, ConfigMaps, Secrets) | | `values/*.yaml` | Environment-specific overrides (non-secret defaults; use sealed/external secrets for prod) | | `argocd/application.yaml` | `Application` (multi-source): OneLab chart + [`observability/`](observability/) (Loki/Promtail/Grafana) | | `observability/` | Umbrella Helm chart for log aggregation (same Argo app, release `onelab-obs`) | ## Prerequisites 1. **k3s** (or any Kubernetes) with default storage class for Postgres/Rabbit PVCs (e.g. `local-path`). 2. **Image pull access** to `hub.andrewalliance.com` — create a docker-registry secret and reference it in `imagePullSecrets`: ```bash kubectl create namespace onelab kubectl create secret docker-registry hub-andrewalliance -n onelab \ --docker-server=hub.andrewalliance.com --docker-username=... --docker-password=... ``` 3. **RabbitMQ TLS secret** (name `onelab-rabbit-tls` by default) — see `values/k3s-example.yaml` comments, or set `rabbitmq.tls.embed: true` with PEM strings in a **private** values file. 4. **Host paths** (default): ensure `/opt/onelab/data` and `/opt/onelab/logs` exist on nodes that run workloads using `persistence.mode: hostPath`, or switch to RWX storage for multi-node. ## Helm (without Argo CD) ```bash cd gitops/charts/onelab helm upgrade --install onelab . -n onelab --create-namespace \ -f ../../values/k3s-example.yaml ``` ## Argo CD 1. Push this repository to a Git remote Argo CD can read. 2. Edit `argocd/application.yaml`: `repoURL`, `targetRevision`, and values file as needed. 3. `kubectl apply -f gitops/argocd/application.yaml` (from a machine with a working kubeconfig). The Application uses **`spec.sources`** (Argo CD 2.6+): source 1 is the OneLab chart (`releaseName: onelab`), source 2 is [`observability/`](observability/) (`releaseName: onelab-obs`). Both deploy to namespace **`onelab`**. Sync waves order Postgres → Redis/Rabbit/config → application pods. ### Logs / Grafana See [docs/OBSERVABILITY.md](docs/OBSERVABILITY.md). Change `grafana.adminPassword` in `observability/values.yaml` before relying on it in production. ## kubectl / credentials If `kubectl` reports *You must be logged in*, refresh your kubeconfig (e.g. copy `/etc/rancher/k3s/k3s.yaml` from the server or re-run your auth plugin) before applying manifests. ## Private Git + registry See [docs/BOOTSTRAP.md](docs/BOOTSTRAP.md) for Argo CD access to `git.luneski.fr` and `docker-registry` for `hub.andrewalliance.com`. ## Helm note (Windows) Helm 3.19 may return empty content for `.Files.Get` on Windows; this chart uses `fromYaml (.Files.AsConfig)` as a workaround so packaged files still render correctly. ## Application configuration (`configurations.yml`) Do **not** need to edit `app/configurations.yml` in Git for Kubernetes. The chart builds `configurations.yml` from `charts/onelab/files/configurations.gotmpl` and stores it in Secret **`onelab-configurations`** (mounted by app pods and `ldap-worker`). 1. **Values (recommended)** — set `onelab.compliance.enabled`, `onelab.ldap.enabled`, and related fields. See `values/instance-overrides.example.yaml`. Point Helm/Argo at an extra values file for your site (Argo: add another path under `spec.source.helm.valueFiles`, relative to the chart directory). 2. **Bring your own Secret** — set `configuration.existingSecretName` to a Secret you manage (SealedSecrets, External Secrets, `kubectl create secret ... --from-file=configurations.yml=...`). The chart will **not** create `onelab-configurations` in that case; the Secret must contain key **`configurations.yml`**. A **ConfigMap** alone is fine if you mount it yourself, but this chart expects a **Secret** for the config file (same as Swarm-style sensitivity). LDAP TLS file paths in values are container paths; mount PEMs with extra volumes on `ldap-worker` if you use them. ## Ingress (web UI) Enable `ingress.enabled` and set `ingress.host` (and optional TLS). Traffic is sent to Service **`revproxy`** (internal nginx). On k3s, `ingress.className: traefik` matches the default controller. For **cert-manager**, set `ingress.tls: true`, `ingress.tlsSecretName`, and `ingress.certManager.clusterIssuer` (e.g. `letsencrypt-prod`). Ensure a **DNS A/CNAME** for `ingress.host` points to your ingress before the ACME challenge runs. ## Not migrated in this chart - **Edge proxy stack** (`app/proxy/docker-compose.yml`, host 80/443 Swarm mode) — replaced for K8s by this **Ingress** + `revproxy`; optional **cert-manager** for TLS at the Ingress. - **Swarm-only secrets** (e.g. `ssl_passphrase`) — handle via Kubernetes Secrets or external operators.