A fully self-contained local development environment using Kind and in-cluster Forgejo as the single git source for the entire GitOps loop. This eliminates external dependencies (GitHub, local git daemon, self-signed CA) and provides a simple task sandbox:setup experience.
The sandboxed-local environment is a new cluster type alongside local and odcn-production. It runs everything inside a single Kind cluster:
Kind Cluster (rig-sandbox)
├── NGINX Ingress (ports 80/443 → host)
├── CloudNativePG Operator + PostgreSQL
├── CSI VolumeSnapshot CRDs
├── Forgejo (git server, rig-admin/admin1234, 4 repos)
├── ArgoCD (pointing to Forgejo repos)
├── Keycloak (admin/admin1234)
├── MinIO (object storage)
└── Operations Manager
Key differences from the local cluster type:
- No external git: Forgejo runs in-cluster; ArgoCD reads from Forgejo
- No self-signed CA: Uses a real wildcard TLS cert for
*.sandbox.rijksapp.dev - No git daemon: Infrastructure changes are synced to Forgejo via
task sandbox:sync - Simplified secrets: Plaintext admin/admin1234 credentials where possible
- kind - Kubernetes in Docker
- kubectl - Kubernetes CLI
- kustomize - Kubernetes configuration management
- jq - JSON processor
- rsync - File synchronization
- Docker - Container runtime
- dnsmasq - Local DNS resolver (for wildcard
*.sandbox.rijksapp.devresolution)
Install and start dnsmasq:
brew install dnsmasq
brew services start dnsmasqThe task sandbox:setup command will automatically configure dnsmasq to resolve *.sandbox.rijksapp.dev to 127.0.0.1 and create the macOS resolver file. You can also run this manually:
task sandbox:update-dnsGenerate a wildcard certificate:
certbot certonly --manual --preferred-challenges dns -d "*.sandbox.rijksapp.dev"Copy the certificate files to:
security/tls/sandbox-wildcard/fullchain.pem
security/tls/sandbox-wildcard/privkey.pem
task sandbox:setupThis single command performs the full setup:
- Verifies required tools are installed
- Activates the sandboxed-local configuration
- Generates an AGE key for SOPS encryption
- Creates the Kind cluster
- Installs NGINX Ingress and CNPG operator
- Installs CSI VolumeSnapshot CRDs
- Configures CoreDNS for
*.sandbox.rijksapp.dev - Creates namespace and imports TLS certificate
- Generates SOPS-encrypted secrets
- Deploys PostgreSQL and Forgejo (pre-ArgoCD)
- Initializes Forgejo with admin user and 4 repositories
- Syncs infrastructure to Forgejo
- Installs ArgoCD operator and bootstraps the system
- Updates
/etc/hosts(requires sudo)
After modifying files in the infrastructure/ directory:
task sandbox:syncThis copies the infrastructure/ subtree to Forgejo's zad-argo-infrastructure repository. ArgoCD will then detect and apply the changes.
| Service | URL | Credentials |
|---|---|---|
| ArgoCD | https://argo.sandbox.rijksapp.dev | admin / admin1234 |
| Forgejo | https://forgejo.sandbox.rijksapp.dev | rig-admin / admin1234 |
| Keycloak | https://keycloak.sandbox.rijksapp.dev | admin / admin1234 |
| MinIO | https://minio.sandbox.rijksapp.dev | admin / admin1234 |
| Operations Manager | https://zad.sandbox.rijksapp.dev | - |
task sandbox:destroyThe sandboxed-local environment is available as option 3 in cluster selection:
task select-cluster
# Select option 3: sandboxed-local| Repository | Purpose |
|---|---|
zad-projects |
Project YAML definition files |
zad-argo-user-applications |
ArgoCD Application manifests for user apps |
zad-argo-infrastructure |
Infrastructure config (synced from local infrastructure/ dir) |
zad-deployments |
Kubernetes manifests generated by Operations Manager |
The environment is configured via .env-taskfile-sandboxed-local:
CLUSTER_TYPE=sandboxed-local
KIND_CLUSTER_NAME=rig-sandbox
RIG_NAMESPACE=rig-system
INFRASTRUCTURE_CLUSTER_FOLDER=sandboxed-local
BOOTSTRAP_CLUSTER_FOLDER=sandboxed-localThe Operations Manager connects to Forgejo using in-cluster URLs:
- Projects:
http://forgejo.rig-system.svc.cluster.local:3000/rig-admin/zad-projects.git - ArgoCD apps:
http://forgejo.rig-system.svc.cluster.local:3000/rig-admin/zad-argo-user-applications.git
Passwords use the plain:admin1234 prefix to bypass AGE decryption.
Keycloak can be configured to federate with an upstream identity provider for SSO. See local-cluster-federation.md for details.
The task sandbox:sync command:
- Clones
zad-argo-infrastructurefrom Forgejo - Uses
rsyncto copyinfrastructure/content (stripping the prefix) - Commits and pushes changes
After sync, the ArgoCD Application path bootstrap/clusters/sandboxed-local maps to the repository root, since the infrastructure/ prefix is stripped.
- Bootstrap secrets (ArgoCD admin, repo credentials): Plaintext manifests in the overlay
- Infrastructure secrets (DB passwords, etc.): Generated via
_generate-secrets-sharedtask, SOPS-encrypted with the AGE key - Operations Manager secrets: Plaintext Secret (admin/admin1234 for all)
sops-age-key: Created fromsecurity/key.txt, used by ArgoCD CMP plugin and Operations Manager
All ingress resources reference the sandbox-wildcard-tls Secret, which contains the real wildcard certificate for *.sandbox.rijksapp.dev. This is imported during setup from security/tls/sandbox-wildcard/.
Check if PostgreSQL is ready:
kubectl get cluster rig-db -n rig-system
kubectl logs -n rig-system forgejo-0Verify the repo credential:
kubectl get secrets -n rig-system -l argocd.argoproj.io/secret-type=repositoryCheck ArgoCD can reach Forgejo:
kubectl exec -n rig-system deployment/argocd-server -- curl -s http://forgejo.rig-system.svc.cluster.local:3000/api/healthzIf the ingress route is not yet available, sandbox:sync falls back to port-forwarding. Ensure the Forgejo pod is running:
kubectl get pods -n rig-system -l app=forgejoVerify CoreDNS configuration:
kubectl get configmap coredns -n kube-system -o yamlEnsure the wildcard cert files exist:
ls -la security/tls/sandbox-wildcard/The certificate must be valid for *.sandbox.rijksapp.dev.