Skip to content

Local Setup

This page explains how to set up a complete local development environment for Kamerplanter. Skaffold is the only authorized tool for the development workflow — it handles image building and deployment in the Kubernetes cluster. Manual docker build or kubectl apply commands are not used.


Prerequisites

Install the following tools before you begin:

Tool Min. Version Purpose
Docker 24+ Container runtime for Kind
Kind 0.20+ Local Kubernetes cluster
kubectl 1.28+ Kubernetes CLI
Skaffold 2.10+ Build and deploy automation
Helm 3.14+ Kubernetes package manager
asdf 0.14+ Node.js version management
Python 3.14+ Backend development without cluster
Node.js 25.1.0 Frontend development without cluster

Node.js version via asdf

A .tool-versions file in src/frontend/ pins Node.js to 25.1.0. After installing asdf, the correct version is activated automatically:

asdf plugin add nodejs
asdf install


Creating the Kind Cluster

The repository includes a pre-configured Kind configuration with three nodes (1 control plane, 2 workers) and predefined port mappings:

kind create cluster --config kind-config.yaml --name kamerplanter

The cluster exposes ports 80, 443, 8000, 3000, and 8529 directly on the host.

Existing cluster

If a cluster named kamerplanter already exists, delete it first:

kind delete cluster --name kamerplanter

After creation, verify that kubectl points to the new cluster:

kubectl cluster-info --context kind-kamerplanter

Starting Development with Skaffold

Skaffold builds container images locally (without pushing to a registry) and deploys them via Helm into the Kind cluster. File changes are synced directly into running containers without a full rebuild.

Full stack

skaffold dev --trigger=manual --port-forward

With --trigger=manual, a rebuild only happens when you press r. This prevents unwanted restarts during rapid file changes. Skaffold activates port forwarding automatically (see table below).

Backend only

skaffold dev --trigger=manual --port-forward -p backend-only

The backend-only profile removes the frontend artifact and its port forward from the build pipeline.

Frontend only

skaffold dev --trigger=manual --port-forward -p frontend-only

With debugger (debugpy)

skaffold debug --port-forward

The debug profile sets DEBUGPY_ENABLED=true as a Docker build argument in the backend container. The debugpy port 5678 then becomes available (see Debugging).


Port Forwards

Skaffold automatically forwards the following ports when --port-forward is set:

Service Local Port Cluster Target
Frontend 3000 Vite dev server on 5173
Backend API 8000 FastAPI on 8000
ArangoDB Web UI 8529 ArangoDB on 8529
Home Assistant 8123 Home Assistant on 8123

API documentation

Once running, the auto-generated Swagger UI is available at http://localhost:8000/docs. ReDoc is at http://localhost:8000/redoc.


Demo Credentials

The backend container runs seed scripts automatically on first startup. A demo user is then available:

Field Value
Email demo@kamerplanter.local
Password demo-passwort-2024
Tenant slug demo

Backend Locally Without Kubernetes

For pure backend development without cluster overhead, you can start the FastAPI server directly. A running ArangoDB instance is required (e.g. via Docker Compose).

# Start ArangoDB and Redis with Docker Compose
docker-compose up -d arangodb valkey

# Install Python dependencies
cd src/backend
pip install -e ".[dev]"

# Set environment variables
export ARANGODB_HOST=localhost
export ARANGODB_PORT=8529
export ARANGODB_DATABASE=kamerplanter
export ARANGODB_USERNAME=root
export ARANGODB_PASSWORD=rootpassword
export REDIS_URL=redis://localhost:6379/0
export DEBUG=true
export REQUIRE_EMAIL_VERIFICATION=false

# Start the server
uvicorn app.main:app --reload --port 8000

Hot reload

uvicorn --reload watches all .py files in the app/ directory and restarts the server automatically on changes. In the Kind cluster, Skaffold handles this via its sync mechanism.


Frontend Locally Without Kubernetes

The Vite dev server can run independently of the cluster. It proxies all /api requests to the backend (default: http://127.0.0.1:8000).

cd src/frontend
npm install
npm run dev

The dev server starts on port 5173. The backend URL can be overridden via the VITE_BACKEND_URL environment variable:

VITE_BACKEND_URL=http://localhost:8000 npm run dev

Home Assistant Integration

The HA integration in src/ha-integration/ is not automatically deployed by Skaffold. After modifying HA integration files, the contents must be copied manually into the running pod:

# Copy files into the pod
kubectl cp src/ha-integration/custom_components/kamerplanter/ \
  default/homeassistant-0:/config/custom_components/kamerplanter/

# Delete the Python cache (MUST always be done, otherwise HA loads old bytecode)
kubectl exec default/homeassistant-0 -- \
  rm -rf /config/custom_components/kamerplanter/__pycache__

# Restart the pod (the PVC persists, files survive the restart)
kubectl delete pod homeassistant-0 -n default

Troubleshooting

Skaffold cannot find the Kind cluster

Make sure the kubectl context is set correctly:

kubectl config use-context kind-kamerplanter

Backend pod not starting (CrashLoopBackOff)

Check the pod logs:

kubectl logs -l app=kamerplanter-backend --tail=50
Common cause: ArangoDB is not yet ready. The liveness probe waits up to 150 seconds (initialDelaySeconds: 30, failureThreshold: 10).

Port 8000 or 3000 is already in use

Kill all processes on the affected port:

lsof -ti:8000 | xargs kill -9

Seed data is missing after restart

Seed scripts only run on first startup or when the ArangoDB database is recreated. To rerun seeds:

kubectl exec -it deployment/kamerplanter-backend -- \
  python -m app.migrations.seed_auth

See also