DashCaddy Documentation
Install Radicale Calendar
Lightweight self-hosted calendar (CalDAV) and contacts (CardDAV) server. Auto-connects to the DashCaddy calendar widget.
tomsquest/docker-radicale:latestWhat is Radicale Calendar?
Lightweight self-hosted calendar (CalDAV) and contacts (CardDAV) server. Auto-connects to the DashCaddy calendar widget.
Radicale ships as a self-contained Docker image that DashCaddy provisions with one click. DashCaddy handles the container lifecycle, DNS record, Caddy reverse-proxy entry, and HTTPS certificate so you can focus on using Radicale, not installing it. Uniquely among catalog apps, DashCaddy also auto-wires the deployed calendar into its own dashboard widget — credentials and the CalDAV source are generated at deploy time, so upcoming appointments appear on your dashboard without any manual configuration.
Prerequisites
- A running DashCaddy host with the dashboard accessible (default URL:
https://dashcaddy.local; configurable via thedashboardHostsetting inconfig.json). - You must be signed in to the dashboard with an admin session, or have an API key with admin scope (
POST /api/v1/auth/keysto create one). - No special host paths required — DashCaddy provisions
/opt/radicale/configand/opt/radicale/dataon first deploy. - For HTTPS with a real certificate, Technitium DNS must be configured and the host must have port 80/443 reachable from the internet. Otherwise DashCaddy will fall back to direct-IP access or a self-signed certificate.
Install via the DashCaddy dashboard
- Sign in at
https://dashcaddy.local(or your host's dashboard URL). - Click the 📱 App Selector button on the dashboard home page.
- Pick Radicale Calendar from the Productivity category.
- Fill in the deployment form: subdomain (default suggestion:
calendar), host port (default:5232). - Click Deploy. DashCaddy will write the Radicale config and credential store before container start, pull the image, create persistent volumes, write the Caddy route, create the DNS record, and register the calendar source with the dashboard widget automatically.
- When the dashboard shows the service as Running, the 📅 Calendar widget in the top bar immediately shows your upcoming events — zero extra setup.
Install via the REST API
Authenticate with an API key (or a JWT minted via POST /api/v1/auth/jwt). Send as X-API-Key: dk_... or Authorization: Bearer <jwt>.
curl -X POST https://dashcaddy.local/api/v1/apps/deploy \ -H "X-API-Key: dk_..." \ -H "Content-Type: application/json" \ -d { "appId": "radicale", "config": { "subdomain": "calendar", "port": 5232 } }The full body schema is in src/utilities/validate.js (Joi schema appDeploy). All config.* fields except subdomain are optional. Notable options:
config.port— host port (1–65535). Defaults to the template'sdefaultPort.config.useExisting: true+existingContainerId— attach DashCaddy metadata to an already-running container instead of pulling a new image.config.tailscaleOnly: true— restrict the reverse-proxy entry to your Tailscale network (a sensible default for personal calendars).config.allowedIPs— array of CIDR ranges allowed past the reverse proxy.config.createDns: false— skip DNS record creation (use when the subdomain already resolves).config.resources—{memory, cpus}limits applied to the container.
Install via the AI Intent Router (returns a structured intent)
The Intent Router returns a structured intent, not a deployed container. To deploy via AI, send natural language to:
curl -X POST https://dashcaddy.local/api/v1/ai/intent \ -H "X-API-Key: dk_..." \ -H "Content-Type: application/json" \ -d { "message": "Deploy a calendar server I can sync my phone with" }The response includes intent, action, parameters, and followup — your client (or the MCP server) must then call POST /api/v1/apps/deploy with those parameters to actually provision the container. With no LLM configured, the built-in pattern engine recognizes "calendar", "caldav", and "radicale" phrasing.
Install via the MCP Server
For AI agents (Claude Desktop, Hermes, etc.) configure the MCP server with:
DASHCADDY_URL=https://dashcaddy.local:3001 # internal API URL, may differ from dashboard URL DASHCADDY_API_KEY=dk_...The server exposes dashcaddy_deploy_app. Note: this tool writes the Caddy route and creates the services.json entry, but it does NOT pull the Docker image or start the container. You must run docker pull tomsquest/docker-radicale:latest and start the container yourself for the URL to actually serve traffic. For a fully-managed deployment, call POST /api/v1/apps/deploy directly from your agent.
Post-install: first-run checklist
- Add the CalDAV URL to your phone/computer calendar apps:
https://<your-domain>/<username>/(the DashCaddy-generated user and password are stored in the dashboard credential vault). - Manage sharing and additional users from the Radicale web interface.
- Check the 📅 widget on your DashCaddy dashboard — events sync within five minutes.
Volumes and persistent data
DashCaddy creates these volume mounts in the container spec:
/opt/radicale/config:/config/opt/radicale/data:/data
All paths are host paths (left side) mapped into the container (right side). Restarting the container preserves data; the auto-wired calendar source and its credentials survive redeploys.
Environment variables
This template ships no custom environment variables; Radicale is configured through the generated config file at /opt/radicale/config/config, which DashCaddy writes at deploy time.
Updating the image
There is no built-in auto-update — DashCaddy does NOT poll for new image digests. To pull a new version:
- SSH into the DashCaddy host and run
docker pull tomsquest/docker-radicale:latest. - Restart the container:
docker restart <containerId>(find the ID viaGET /api/v1/servicesor the dashboard). - Or deploy Watchtower from this catalog (separate template that polls Docker Hub and updates other containers automatically).
Troubleshooting
- Widget shows "No sources configured" after a manual (non-DashCaddy) Radicale install: use the calendar settings modal (⚙️ in the widget) to add the CalDAV URL and credentials yourself, or register the source via
POST /api/v1/calendar/sources. - 401 from CalDAV clients: the web interface stores users under
/opt/radicale/config/users; the DashCaddy-managed account lives in the encrypted credential vault, not a plaintext file. - Container restarts in a loop: check
docker logs <containerId>— the most common cause is an existing nonempty/opt/radicale/configowned by a different uid.