Self-hosting

Kubernetes (Helm)

Scale beyond a single host. Install the published Helm chart on any cluster — EKS, GKE, AKS, k3s, OpenShift, or Docker Desktop.

2 min read

Docker Compose runs a single server and engine. The Helm chart runs the same stack with a horizontally scalable engine — it's published as an OCI artifact, so you only need kubectl + helm pointed at your cluster. The chart defaults to the kubernetes-edition images (:k8s tag, built with DNS engine discovery).

Install

Create the three required secrets, then install:

kubectl create namespace eddytor

kubectl -n eddytor create secret generic eddytor-secrets \
  --from-literal=EDDYTOR_DATABASE_URL="postgres://user:pass@host:5432/eddytor" \
  --from-literal=EDDYTOR_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
  --from-literal=EDDYTOR_API_KEY_SECRET="$(openssl rand -base64 32)"

helm upgrade --install eddytor oci://ghcr.io/nordalf/charts/eddytor -n eddytor \
  --set secrets.existingSecret=eddytor-secrets \
  --set config.publicUrl="https://eddytor.example.com" \
  --set ingress.enabled=true --set ingress.host=eddytor.example.com

secrets.existingSecret points the chart at a Secret you manage (so credentials never pass through helm --set). Ingress, autoscaling (HPA), and PodDisruptionBudgets are on by default; bring your own Postgres and object store in production (postgres.bundled / garage.bundled default false). After install, follow the printed NOTES to create the first admin (it runs inside the server pod via kubectl exec), then sign in:

eddytor config set-api-url https://eddytor.example.com
eddytor login

Scale the engine any time:

kubectl -n eddytor scale deploy/eddytor-engine --replicas=5

Trying it locally

No cluster? Stand up a throwaway one with k3d, kind, minikube, or Docker Desktop — then install with bundled Postgres + Garage on a NodePort. The -p flag maps the host's localhost:8080 onto the NodePort (a k3d feature):

k3d cluster create eddytor -p "8080:30080@server:0"

kubectl create namespace eddytor
kubectl -n eddytor create secret generic eddytor-secrets \
  --from-literal=EDDYTOR_DATABASE_URL="postgres://eddytor:eddytor@eddytor-postgres:5432/eddytor" \
  --from-literal=EDDYTOR_ENCRYPTION_KEY="$(openssl rand -base64 32)" \
  --from-literal=EDDYTOR_API_KEY_SECRET="$(openssl rand -base64 32)"

helm install eddytor oci://ghcr.io/nordalf/charts/eddytor -n eddytor \
  --set secrets.existingSecret=eddytor-secrets \
  --set postgres.bundled=true --set garage.bundled=true \
  --set server.service.type=NodePort --set server.service.nodePort=30080
# server reachable at http://localhost:8080
minikube

minikube doesn't surface NodePorts on localhost. Drop the NodePort flags and reach the stack with kubectl -n eddytor port-forward svc/eddytor-server 8080:8080 instead — that keeps the localhost:8080 URLs the chart defaults assume.

Evaluation only

Bundled single-replica Postgres/Garage have no HA and no backups. Use external, backed-up datastores and real secrets in production.

Create your first table

After eddytoradm setup + eddytor login, register the bundled Garage. The endpoint is the in-cluster Service name eddytor-garage:3900 (the chart's demo creds are garage.accessKey / garage.secretKey — override for real use):

eddytor create storage s3 --bucket eddytor \
  --endpoint http://eddytor-garage:3900 --region us-east-1 \
  --access-key-id GK00000000000000000000000000000000 \
  --secret-access-key 0000000000000000000000000000000000000000000000000000000000000000

# bulk queries use Flight SQL on server port 8082 (stays ClusterIP):
kubectl -n eddytor port-forward svc/eddytor-server 8082:8082 &
eddytor config set-flight-url http://localhost:8082

Still stuck? We reply fast.

Can't find it? Ask support and a human will answer, usually within a few hours.