This Docker Compose configuration sets up Radicale with Tailscale as a sidecar container to keep the app reachable over your Tailnet.
Radicale is a small but powerful CalDAV (calendars, to-do lists) and CardDAV (contacts) server. It is lightweight, easy to configure, and requires minimal resources, making it a great self-hosted alternative to cloud-based calendar and contact sync services.
- CalDAV and CardDAV support for syncing calendars, to-do lists, and contacts
- Works with any compliant client (Thunderbird, GNOME Calendar, DAVx5, Apple Calendar, etc.)
- Lightweight with minimal resource usage
- Simple file-based storage
- Web interface for managing collections
- Built-in access control and authentication
In this setup, the tailscale-radicale service runs Tailscale, which manages secure networking for Radicale. The radicale service utilizes the Tailscale network stack via Docker's network_mode: service: configuration. This keeps the app Tailnet-only unless you intentionally expose ports.
The container runs with hardened security settings: read-only filesystem, no new privileges, dropped capabilities, and resource limits (256M memory, 50 pids).
- This image uses tomsquest/docker-radicale. Refer to their documentation for advanced configuration options.
- To configure users and authentication, mount a custom config file or refer to the Radicale documentation.
Radicale uses htpasswd for authentication. To set up users:
-
Create the required directories:
set -a && source .env && set +a mkdir -p ./${SERVICE}-data/config
-
Create an
htpasswdfile with your first user (requiresapache2-utilson Debian/Ubuntu orhttpd-toolson Fedora):htpasswd -B -c ./${SERVICE}-data/users <username>
To add more users without overwriting the file, omit
-c:htpasswd -B ./${SERVICE}-data/users <username>
-
Fill out config file:
nano ./${SERVICE}-data/config/radicale.confWith:
[auth] type = htpasswd htpasswd_filename = /config/users htpasswd_encryption = bcrypt [storage] filesystem_folder = /data/collections
-
Restart the stack:
docker compose down && docker compose up -d
Please check the following contents for validity as some variables need to be defined upfront.
.env— Main variable:TS_AUTHKEY