A web-based editor for Caddy configuration files.
Provides a browser-based Monaco editor (the same editor that powers VS Code) for editing your Caddyfile, with:
- Syntax highlighting — directives, matchers, addresses, variables, paths, and more, all colour-coded
- Validate & apply — on save, the config is validated against the Caddy admin API before being written to disk and reloaded live, so a bad config can never take your server down
- Auto-restart — after every successful reload, CaddyBerry restarts the Caddy container via the Docker socket and waits for it to come back online before showing success
- Keyboard shortcut —
Ctrl/Cmd+Sto apply - Mobile friendly — readable and usable on small screens
Security note: CaddyBerry has no built-in authentication. Anyone who can reach the app can read and modify your Caddyfile. Run it on a private network or behind a reverse proxy with authentication (e.g. Caddy
basicauth, Authelia, oauth2-proxy).
services:
caddyberry:
image: ghcr.io/stelianmorariu/caddyberry:latest
ports:
- "3000:3000"
environment:
CADDYFILE_PATH: /config/Caddyfile
CADDY_ADMIN_URL: http://caddy:2019
# Optional: auto-restart Caddy after every reload
# CADDY_CONTAINER_NAME: caddy # Container to restart (default: caddy)
volumes:
- ./Caddyfile:/config/Caddyfile
# Required for auto-restart:
# - /var/run/docker.sock:/var/run/docker.sock
restart: unless-stoppedcaddyberry needs to share the same Caddyfile that Caddy reads on startup, and network access to the Caddy admin API (port 2019 by default).
| Variable | Default | Description |
|---|---|---|
CADDYFILE_PATH |
/caddy/Caddyfile |
Path to the Caddyfile on disk |
CADDY_ADMIN_URL |
http://caddy:2019 |
Base URL of the Caddy admin API |
CADDY_CONTAINER_NAME |
caddy |
Docker container name to restart after every reload (requires Docker socket) |
IS_DEV |
— | Set to true to skip all network requests and use built-in sample content instead |
After every successful reload, CaddyBerry restarts the Caddy container via the Docker socket and polls until the app is reachable again before showing success. This works around cases where Caddy's hot reload silently leaves it in a broken state.
To enable, mount the Docker socket and optionally set CADDY_CONTAINER_NAME (defaults to caddy). The Docker socket grants container-level restart privileges — a common trade-off in homelab setups.
Create a .env file in the project root:
# Use built-in sample data — no running Caddy instance needed
IS_DEV=true
# Or point at a real Caddy instance
# CADDYFILE_PATH=/path/to/your/Caddyfile
# CADDY_ADMIN_URL=http://localhost:2019Then:
npm install
npm run dev # runs on http://localhost:3000With IS_DEV=true, the editor loads a built-in sample Caddyfile on startup and mocks the apply pipeline — no running Caddy instance needed. A DEV badge appears in the toolbar with a dropdown to simulate success or failure responses.
