Docker Compose Quick Start¶
From zero to a running Kamerplanter instance with your first plants in 5 minutes.
Prerequisite
Docker and Docker Compose must be installed. If not, follow the Installation guide first.
1. Download the repository¶
Download the source code and navigate to the directory:
Don't have Git installed?
You can also download the repository as a ZIP file: Go to the GitHub page, click the green Code button and choose Download ZIP. Extract the file and open a terminal in the extracted folder.
2. Create configuration¶
Copy the example configuration and adjust the passwords:
Open the .env file in a text editor and change at least the passwords:
# Set secure passwords (at least 12 characters recommended)
ARANGO_ROOT_PASSWORD=your-secure-password # (1)!
ARANGODB_PASSWORD=your-secure-password # (2)!
- The database password. Choose a secure password — it won't be shown in the browser.
- Must be identical to
ARANGO_ROOT_PASSWORD.
Generate a secure password
On Linux/macOS you can generate a random password:
Copy the output and use it as the password in your .env file.
You can leave the remaining settings at their default values for now.
Four additional mandatory secrets (otherwise the backend won't start)¶
Without these four values the backend start-up aborts
.env.example sets DEBUG=false. With DEBUG=false the backend checks four more secrets at start-up — JWT_SECRET_KEY, FERNET_KEY, ERASURE_TOMBSTONE_SALT and LOG_PSEUDONYM_SALT — and aborts with an error if any of them is missing (fail-fast gate, independent of the operating mode). The bundled docker-compose.yml/docker-compose.release.yml do not automatically pass these four variables into the backend container — you have to add them yourself. The celery-worker container now also checks FERNET_KEY and LOG_PSEUDONYM_SALT at start-up and aborts the same way if a value is missing or invalid — the celery-worker entry in the docker-compose.override.yml below is therefore mandatory, not optional. celery-beat does not check LOG_PSEUDONYM_SALT.
Generate the four values:
# JWT_SECRET_KEY, ERASURE_TOMBSTONE_SALT and LOG_PSEUDONYM_SALT (at least 32 characters each)
openssl rand -hex 32
# FERNET_KEY (must be a valid Fernet key)
python3 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Add the four values to your .env:
JWT_SECRET_KEY=<output of openssl rand -hex 32>
FERNET_KEY=<output of the Fernet command>
ERASURE_TOMBSTONE_SALT=<second output of openssl rand -hex 32>
LOG_PSEUDONYM_SALT=<third output of openssl rand -hex 32>
Also create a docker-compose.override.yml that actually passes these values into the containers (Docker Compose loads it automatically when it sits in the same directory):
services:
backend:
environment:
JWT_SECRET_KEY: ${JWT_SECRET_KEY}
FERNET_KEY: ${FERNET_KEY}
ERASURE_TOMBSTONE_SALT: ${ERASURE_TOMBSTONE_SALT}
LOG_PSEUDONYM_SALT: ${LOG_PSEUDONYM_SALT}
celery-worker:
environment:
FERNET_KEY: ${FERNET_KEY}
ERASURE_TOMBSTONE_SALT: ${ERASURE_TOMBSTONE_SALT}
LOG_PSEUDONYM_SALT: ${LOG_PSEUDONYM_SALT}
celery-beat:
environment:
FERNET_KEY: ${FERNET_KEY}
ERASURE_TOMBSTONE_SALT: ${ERASURE_TOMBSTONE_SALT}
Alternative: DEBUG=true for short local tests only
Setting DEBUG=true in .env skips this check entirely and the backend starts even without the four secrets. That's acceptable for a brief, purely local test on your own machine, but never for a server reachable over the network — DEBUG=true also enables verbose logging. Details on every mandatory secret per feature: Configuration Matrix — Mandatory secrets.
3. Start Kamerplanter¶
Start all services with a single command:
Docker downloads the required images on first start. This may take 2–5 minutes depending on your internet connection. Subsequent starts are much faster.
Check that all services are running:
You should see five services, all with status running or healthy:
NAME STATUS
kamerplanter-arangodb-1 running (healthy)
kamerplanter-valkey-1 running (healthy)
kamerplanter-backend-1 running (healthy)
kamerplanter-celery-worker-1 running
kamerplanter-celery-beat-1 running
kamerplanter-frontend-1 running (healthy)
A service shows 'unhealthy' or 'restarting'?
Wait 30 seconds and run docker compose ps again — some services take a bit longer to start. If the problem persists, check the logs:
4. Open Kamerplanter in your browser¶
Open your browser and go to:
Since Kamerplanter starts in Light Mode by default, there is no login screen — you'll go straight to the Onboarding Wizard.
5. First-time setup¶
When you open Kamerplanter for the first time, it automatically starts the Onboarding Wizard. It guides you through experience level, location, and starter kit selection (e.g. "Windowsill Herbs" or "Houseplant Starter") in just a few minutes. Everything is self-explanatory and described in full on the Onboarding Wizard page.
Done!¶
Your Kamerplanter is running. From here you can:
- View plants and track growth status
- Check tasks created by the starter kit
- Adjust locations — rename rooms, add new ones
- Add more plants — via the "Master Data" menu
Optional profiles (AI, sensor data)¶
The base start with docker compose up -d covers the full plant, task, and care workflow. Additional features — the AI knowledge assistant and sensor data history — can be enabled via optional Docker Compose profiles.
Profiles are additive and combinable
Each profile extends the base setup with additional services. You can activate multiple profiles at the same time.
Profile overview¶
| Profile | What it starts | Purpose | Required .env setting |
|---|---|---|---|
vectordb | PostgreSQL + pgvector (port 5433) + Reranker Service (port 8081) | AI/RAG knowledge assistant — semantic search in the knowledge base | VECTORDB_ENABLED=true |
ollama | Ollama LLM server (port 11434) | Local LLM inference for the knowledge assistant, as an alternative to a cloud LLM API | LLM_PROVIDER=ollama and LLM_API_URL=http://ollama:11434 |
timescaledb | TimescaleDB (port 5432) | Time-series storage of sensor data (measurement history, automatic downsampling) | TIMESCALEDB_ENABLED=true |
Example commands¶
Base only (default — no profile needed):
AI knowledge assistant with local LLM (Ollama):
Then enable the services in your .env:
VECTORDB_ENABLED=true
LLM_PROVIDER=ollama
LLM_API_URL=http://ollama:11434
LLM_MODEL=llama3.2 # Any model available in Ollama
Model download on first start
Ollama downloads the model on first use. Depending on the model, that is 4–15 GB — plan your disk space accordingly.
AI knowledge assistant with cloud LLM (e.g. Anthropic):
VECTORDB_ENABLED=true
LLM_PROVIDER=anthropic
LLM_API_KEY=sk-ant-...
LLM_MODEL=claude-sonnet-4-20250514
Sensor data history:
Resource requirements per profile¶
Ollama requires significantly more resources
LLM models are large. For a smaller model (e.g. llama3.2) expect at least 8 GB of RAM and 5 GB of free disk space. Larger models need more. Without a dedicated GPU, inference runs on the CPU — slower, but functional.
| Profile | Additional RAM (typical) | Additional disk |
|---|---|---|
vectordb | ~512 MB | ~500 MB |
ollama | 8–16 GB (depending on model) | 5–30 GB (depending on model) |
timescaledb | ~256 MB | grows with sensor data |
Useful commands¶
| Command | What it does |
|---|---|
docker compose up -d | Start all base services |
docker compose --profile vectordb --profile ollama up -d | Start base + AI profiles |
docker compose --profile timescaledb up -d | Start base + sensor data profile |
docker compose stop | Stop all services (data is preserved) |
docker compose down | Stop and remove containers (data is preserved) |
docker compose down -v | Stop everything and delete all data (fresh start) |
docker compose logs -f backend | Follow backend logs live |
docker compose ps | Show status of all services |
Deleting data
The command docker compose down -v permanently deletes all stored data. Only use it if you want a complete fresh start.
Access points¶
Standard (always available)¶
| Service | URL | Description |
|---|---|---|
| User interface | http://localhost:8080 | The Kamerplanter app |
| API documentation | http://localhost:8000/api/v1/docs | Interactive API reference (Swagger UI) |
| Database UI | http://localhost:8529 | ArangoDB web interface (for advanced users) |
Optional (only with active profile)¶
| Service | URL | Profile | Description |
|---|---|---|---|
| Reranker Service | http://localhost:8081 | vectordb | Cross-encoder for RAG quality |
| Ollama | http://localhost:11434 | ollama | Local LLM server (API) |
Every port is reachable only from this machine
Docker Compose binds every port in the tables above to 127.0.0.1. http://localhost:… works from the machine running Kamerplanter, but no other device on the same network can reach it — not the databases, not Valkey, not Ollama, and not the app itself. ArangoDB, Valkey and the PostgreSQL databases hold your data behind the example passwords from .env.example; Ollama and the reranker service have no authentication at all.
Want to open Kamerplanter on your phone or tablet? Mind that this stack runs in Light mode, which has no login: once the ports are open, every device on your network can read and change your data. If that is fine on your home network, set KAMERPLANTER_BIND_ADDRESS=0.0.0.0 in .env and restart with docker compose up -d. That opens only the user interface (port 8080) and the API (port 8000) to your network — the databases, Valkey, Ollama and the reranker stay on this machine. The steps are in Permanent operation — Accessing from other devices.
The reranker container also runs read-only, as UID 1000, and without Linux capabilities — see "Container hardening" in the AI architecture.
See also¶
- Onboarding Wizard — Detailed description of all wizard steps
- Light Mode — What Light Mode means
- First Deployment — Run Kamerplanter permanently on your own server