Repository navigation
Installation
The included docker-compose.yml is a plug-n-play setup β the prebuilt image from GitHub Container Registry, two folders for your data, nothing else to configure:
docker compose up -dOpen http://localhost:3113. Interactive API docs: http://localhost:3113/docs.
That's genuinely the whole setup: no .env file needed, no build step, and your data lives in the ./data and ./uploads folders next to the compose file, so it survives rebuilds and restarts. Paste the same file into Dockge or Portainer and it just works there too.
The image (ghcr.io/elyld/verdant:latest, also tagged per release) builds for both linux/amd64 and linux/arm64 (handy for a Raspberry Pi).
Pull and recreate β your data lives in the bind-mounted folders, not the image:
docker compose pull && docker compose up -dIn Dockge: hit the update/redeploy button on the stack. On startup Verdant automatically adds any missing database columns, so old databases (even v1.x) upgrade cleanly without manual migrations.
| Host path | Container path | Contents |
|---|---|---|
./data |
/data |
garden.db (SQLite, WAL) |
./uploads |
/uploads |
Uploaded images |
Back up those two folders and you have everything. (There's also a one-click backup & restore inside the app under Settings β the database-only option makes a small zip you can grab before every upgrade.)
To change the host port, point Verdant at your Immich server, or turn on the Discord digest, copy .env.example to .env and fill in what you need, then re-run docker compose up -d.
| Variable | What it does |
|---|---|
GARDEN_PORT |
Host port (default 3113) |
IMMICH_BASE_URL |
Your Immich server, e.g. http://host.docker.internal:2283 when Verdant runs in Docker on the same machine as Immich |
IMMICH_API_KEY |
Immich API key |
TUNNEL_MODE |
true when behind a Cloudflare Tunnel β HSTS on, /docs off, proxy headers trusted |
TUNNEL_TOKEN |
Cloudflare tunnel token (only with the cloudflared service uncommented) |
FIRST_FROST_DATE |
Your average first fall frost (YYYY-MM-DD) β shows a countdown pill in the header |
Garden coordinates (for the weather strip and frost countdown) live on the Settings page in the app, not in env vars β there's a π "use my location" button if you don't know them.
Verdant is tunnel-ready: no sign-on inside the app, Cloudflare handles identity at the edge.
- In the Cloudflare dashboard: Zero Trust β Networks β Tunnels β create a tunnel, add a public hostname pointing at
http://garden:8000, and copy the tunnel token. - In
docker-compose.yml: comment out theports:block on the garden service (so the app is not on your LAN directly β only the tunnel can reach it), and uncomment thecloudflaredservice at the bottom. - In your
.env:TUNNEL_TOKEN=<your token>. -
docker compose up -d. - Add a Cloudflare Access policy (e.g. email one-time PIN) on the hostname β that's the sign-on, handled by Cloudflare, not Verdant.
Set TUNNEL_MODE=true too. (Keep ports: if you still want LAN access β the tunnel keeps working, but LAN clients bypass Cloudflare Access.)