Job containers need access to the DinD daemon for docker build/push.
Mount /var/run/docker.sock from DinD into job containers and set
docker_host in runner config.
The act_runner entrypoint ignores CONFIG_FILE for the daemon
command, so container.options (pnpm cache volume) never loads.
Use a custom command that registers manually then runs daemon
with --config explicitly.
The command override bypasses the entrypoint that handles
registration. Use CONFIG_FILE env var which the entrypoint
respects, keeping the registration flow intact.
Mount volume at /pnpm-store and set PNPM_STORE_DIR and
COREPACK_HOME env vars in job containers so pnpm and corepack
both write to the cached volume. Corepack cache avoids
re-downloading pnpm binary each run.
Pre-install pnpm 9.15.4 via corepack in the image so it doesn't
download every run. Use --config CLI flag instead of CONFIG_FILE
env var to ensure container.options volume mount is applied.
Mount a named Docker volume (pnpm-store) into every job container
at the default pnpm store path. The volume persists in the DinD
sidecar across job runs, so pnpm install reuses cached packages.
Build a runner-image based on node:20-bookworm with all CI tools
baked in, avoiding apt-get install in every workflow run. Runner
labels now point to gitea.coreworlds.io/lazorgurl/runner-image.
Without this, ArgoCD rejects SSH connections to the in-cluster
Gitea service. Uses a patch file to replace the known_hosts
ConfigMap with defaults + Gitea key.
Switch app-of-apps, platform, apps, and previews ApplicationSets
to read from in-cluster Gitea (gitea-helm-ssh.platform.svc:2222).
Previews now use Gitea PR generator instead of GitHub.
TLS between act_runner and DinD in the same pod is unnecessary
and causes race conditions with cert generation. Use port 2375
(no TLS) and set DOCKER_TLS_CERTDIR="" on the DinD sidecar.
All placeholder secrets replaced with real sealed values:
- argocd-gitea-token: API token for ArgoCD PR generator
- gitea-runner-token: registration token for in-cluster runner
- gitea-pull-secret: registry credentials for app image pulls
The Gitea Helm chart names services as gitea-helm-http and
gitea-helm-ssh, not gitea-http/gitea-ssh. Update IngressRoute
and runner deployment to match.
Valkey requires authentication. Use additionalConfigFromEnvs to
read the password from valkey-credentials secret and interpolate
it into the Redis URLs for cache and session config.
The _secret/_key syntax doesn't work in Gitea Helm values. Use
additionalConfigFromEnvs to inject GITEA__database__PASSWD from
the sealed secret, which the chart translates into app.ini config.
The longhorn-nvme StorageClass was defined but never included in the
Longhorn kustomization, so it was never deployed. Add it and revert
Gitea manifests back to longhorn-nvme as intended.
Gitea needs to be deployed before ArgoCD can read from it.
Keep GitHub repoURLs so ArgoCD can discover and deploy the
new gitea-pg, gitea, and gitea-runner directories. Switch
to Gitea repoURLs after Gitea is running and repo is pushed.
Deploy Gitea via Helm with dedicated CloudNativePG database,
in-cluster Actions runner (DinD), and built-in container registry.
ArgoCD repoURLs updated to use in-cluster Gitea SSH. Preview
ApplicationSet switched from GitHub PR generator to Gitea PR
generator. App images now pull from gitea.coreworlds.io registry.
Remaining setup after deploy: seal runner token, ArgoCD API token,
and registry pull secret once Gitea is running. Add ArgoCD deploy
key to Gitea repo settings.
- Add ServiceMonitors for Traefik, ArgoCD, and Longhorn
- Enable cert-manager ServiceMonitor via helm values
- Deploy Grafana Tempo for distributed tracing (single-binary, Longhorn PVC)
- Add Tempo datasource with trace-to-logs and trace-to-metrics correlation
- Instrument API with OpenTelemetry SDK (Prometheus metrics + OTLP traces)
- Replace console.log with pino structured logging + pino-http middleware
- Add Grafana dashboards for Traefik, API overview, and PostgreSQL (CNPG)
- Migrate all ingress hostnames from *.homelab.local to *.coreworlds.io
- Remove broken Traefik certresolver config (cert-manager handles TLS)
- Add internal-only IP allowlist middleware for platform services
- Add IngressRoutes for ArgoCD, Grafana, Longhorn (LAN-only via middleware)
- Seal and add Cloudflare API token for cert-manager DNS-01 challenges
- Update cert-manager ClusterIssuers with real email
- Update k3s TLS SAN to k3s.coreworlds.io
- Rewrite Ubiquiti docs for single-node topology and split-horizon DNS
- Fix seal-secret.sh controller name to match Helm release
- Add UCG DNS setup script using API key auth
cert-manager and CloudNativePG operator installs must complete before
their custom resources (ClusterIssuer, CNPG Cluster) can be applied.
Split into separate kustomize dirs so the ApplicationSet creates
independent ArgoCD apps that can sync in order:
- platform-cert-manager → installs operator
- platform-cert-manager-config → creates ClusterIssuers (after CRDs exist)
- platform-cloudnativepg → installs operator
- platform-cloudnativepg-cluster → creates PG cluster (after CRDs exist)
- Remove vault.yaml and kubeconfig from tracking
- Add vault files and kubeconfig to .gitignore everywhere
- Clean up stray infra/ansible/infra/ directory
- Update repo URLs from HTTPS placeholder to git@github.com:lazorgurl/homelab.git
- Update container image refs from OWNER to lazorgurl
- Set KUBECONFIG env in Taskfile
- Fix kubeconfig-fetch.sh to auto-detect server IP from inventory
- Fix Ansible: callback plugin, br_netfilter ordering, ssh service name