An alchemist's furnace.
Athanor is a devcontainer-based development environment for Helmetica. It provides a local kind cluster with all modules needed to develop and test service charts (reagents).
- Docker (or a compatible engine like OrbStack)
- VS Code with the Dev Containers extension
- Clone this repository and open it in VS Code.
- When prompted, choose Reopen in Container. Alternatively open the command palette (
F1) and run Dev Containers: Reopen in Container. - Wait for the container to build and provision. The
postCreateCommandautomatically runsjust ignite, so once provisioning finishes you already have a running cluster.
Another good way to run the devcontainer is Devsy. It works with any IDE and can run the devcontainer on your local Docker daemon or on remote providers:
devsy workspace up .If you prefer the plain CLI, the devcontainer CLI works too:
devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . zshThe devcontainer ships all tooling needed for development:
- Go,
just,git,vim docker(docker-in-docker)kubectl(with completions and kubecolor),helm,krewjqandyq- Nix
The devcontainer forwards the following ports to your host:
| Port | Purpose |
|---|---|
| 8088 | Ingress HTTP (traefik) |
| 8443 | Ingress HTTPS (traefik) |
| 5000 | Internal container registry (TLS) |
| 36377 | Kubernetes API server |
The devcontainer exists to give you a standardized environment with working Metallb routing. Only use this if the devcontainer setup can't be used.
This is the recommended path on hosts that only have rootless Podman, where nesting a docker-in-docker devcontainer is painful. Be sure to check (kind's rootless docs) before continuing.
go, just, git, kubectl, helm, jq, yq. kind and kustomize are fetched at pinned versions via go run, so they do not need to be installed.
kind autodetects the container engine it runs on (docker, podman, or nerdctl):
export KUBECONFIG=$(pwd)/.kind/kind-config
just igniteRunning any container engine rootless (Podman, rootless containerd/nerdctl, or rootless Docker) puts the container network inside a user network namespace, so the host has no route to the MetalLB address pool. MetalLB still assigns IPs and works inside the cluster, but curl <EXTERNAL-IP> from the host fails with "no route to host" (kind#3388).
The same applies to MacOS, because there containers run in a VM.
Ingress is unaffected — Traefik uses host ports via the cluster's extraPortMappings, so localhost:8088/localhost:8443 work as usual. For a LoadBalancer service, use kubectl port-forward instead.
If you need to (re-)create the cluster manually, simply ignite the furnace to get a kind cluster with all necessary modules:
just quench
just igniteThis creates the kind cluster and installs the modules from the hearth/ folder:
- traefik as ingress controller, reachable on
localhost:8088/localhost:8443 - metallb so
LoadBalancerservices get IPs - kube-prometheus-stack for monitoring
- k8up for backups
- cert-manager for certificates
- COSI (the
objectstorage.k8s.ioCRDs and its central controller) so aBucketClaimprovisions a real bucket - The garage operator with its COSI driver enabled, plus a single-node Garage cluster
- An internal container registry on
localhost:5000(TLS, self-signed) - And of course the helmetica framework
To talk to the cluster from outside the devcontainer, point kubectl at the generated kubeconfig:
export KUBECONFIG=$(pwd)/.kind/kind-configThe garage BucketClass and BucketAccessClass are installed and pointed at the local
Garage cluster, so a claim is all it takes:
apiVersion: objectstorage.k8s.io/v1alpha2
kind: BucketClaim
metadata:
name: scratch
namespace: default
spec:
bucketClassName: garage
protocols:
- S3kubectl get bucketclaims,buckets
kubectl -n garage-system logs deployment/garage-operator -fSome handy URLs once the furnace is lit:
- http://prometheus.127.0.0.1.nip.io:8088
- http://alertmanager.127.0.0.1.nip.io:8088
- http://s3.127.0.0.1.nip.io:8088
Editing a module's values file (e.g. hearth/traefik/values.yaml) and re-running just ignite reconciles every module, or run the single recipe (e.g. just traefik-setup) to upgrade only that one.
Then put the service charts (reagents) into the reagents/ folder and develop away.
To stop and delete the cluster:
just quenchjust (or just --list) lists all available recipes.
.
├── hearth # Modules for athanor (one folder per module)
├── reagents # Charts to be developed go here
├── Justfile # Contains logic to start/stop the devenv
├── Justfile.vars.just # Pinned versions of all modules (managed by Renovate)
├── README.md
└── renovate.json