Self-host a personal calendar and address book using Radicale
CalDAV and CardDAV are open protocols for sharing a calendar and address book respectively between devices. Radicale is a self-hosted CalDAV and CardDAV server that, as per their website,:
- Shares calendars and contact lists through CalDAV, CardDAV and HTTP.
- Supports events, todos, journal entries and business cards.
- Works out-of-the-box, no complicated setup or configuration required.
- Can limit access by authentication.
- Can secure connections with TLS.
- Works with many CalDAV and CardDAV clients.
- Stores all data on the file system in a simple folder structure.
- Can be extended with plugins.
- Is GPLv3-licensed free software.
Sounds good! Let's get it setup.
Install and configure
Install ...
$ python3 -m pip install --upgrade radicale
Make directories ...
$ mkdir -p ~/.config/radicale
$ mkdir -p ~/.var/lib/radicale/collections
$ sudo mkdir /etc/radicale
Setup user authentication for <username>
(choose a name) using htpasswd
...
$ sudo apt install apache2-utils
$ sudo htpasswd -c /etc/radicale/users <username>
Create ~/.config/radicale/config
. Example:
[server]
# access over the network
hosts = 0.0.0.0:5232, [::]:5232
max_connections = 20
# 100 Megabyte
max_content_length = 100000000
# 30 seconds
timeout = 30
[storage]
filesystem_folder = ~/.var/lib/radicale/collections
[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
# encryption method used in the htpasswd file
htpasswd_encryption = md5
# Average delay after failed login attempts in seconds
delay = 1
Run as a service
Run as a service with systemd as a user. Create directory ...
$ mkdir ~/.config/systemd/user
Create file ~/.config/systemd/user/radicale.service
. Example:
[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
[Service]
ExecStart=/usr/bin/env python3 -m radicale
Restart=on-failure
[Install]
WantedBy=default.target
At this point, a problem might arise. When I went to enable the service ...
$ systemctl --user enable radicale
Failed to connect to bus: No such file or directory
In my case, this was because the XDG_RUNTIME_DIR
and DBUS_SESSION_BUS_ADDRESS
environment variables were missing.
If this rears up and bites you, run the following commands and test ...
$ export XDG_RUNTIME_DIR="/run/user/$UID"
$ export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
$ systemctl --user status
It works! See: Managing another user's systemd units
To make this fix permanent, modify /etc/ssh/sshd_config
and set UsePAM no
to UsePAM yes
(which in Debian 10 is the default setting).
Enable and start the service ...
$ systemctl --user enable --now radicale
Check the status ...
$ systemctl --user status radicale
$ journalctl --user --unit radicale.service
Login to the web interface at http://<server-ip-address>:5232
with the newly-created username and password.
Click on Create new addressbook or calendar
and I create an empty calendar and a empty address book; each outputs a link to URL: http://server-ip-address>:5232/<username>/<string>/
.
Use Nginx as a reverse proxy
First, see "Nginx web server" to install and configure Nginx, an open-source, high performance, lightweight HTTP and reverse proxy server. Nginx sits in front of Radicale as the proxy, removing the location from the URL path that is forwarded to Radicale.
Example: An nginx configuration in /etc/nginx/conf.d/my-website.conf
that uses Duck DNS for Dynamic DNS and SSL via a self-signed certificate ...
server {
listen 80;
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my-subdomain-name.duckdns.org;
ssl_certificate /etc/ssl/certs/nginx-server-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-server-selfsigned.key;
location / {
root /home/my-username/html;
index index.html index.htm;
}
location /radicale/ { # The trailing / is important!
proxy_pass http://localhost:5232/; # The / is important!
proxy_set_header X-Script-Name /radicale;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Remote-User $remote_user;
proxy_set_header Host $http_host;
proxy_pass_header Authorization;
}
}
Restart nginx and radicale ...
$ sudo systemctl restart nginx
$ systemctl --user restart radicale
Navigate to https://my-subdomain-name.duckdns.org:port-number/radicale/ and confirm the Radicale login is displayed.
See Radicale Reverse Proxy for more options.
Add a client: Thunderbird
Recent versions of the Thunderbird email client now include a built-in calendar. Click on the calendar tab icon in the upper right corner to open.
In the calendar tab, click on the +
in the left calendar sidebar and add a new calendar on the network with CalDAV. Enter the URL for the Radicale-hosted calendar. Thunderbird's calendar populates with data.
For the address book, install the CardBook add-on. Click on the CardBook tab icon in the upper right corner to open.
In the address book column, right-click and choose New Addressbook
, select Remote
for location, CardDav
, and enter the URL for the Radicale-hosted address book. After setup, click and drag Thunderbird's existing contacts into the new address book.
Add a client: DAVx5
DAVx5 is a CalDAV/CardDAV synchronization client for Android, which I install via F-Droid.
After setting up an account with your Radicale username
and URL, the calendar and address book are synced to the phone, and viewable in your Calendar
and Contacts
apps.
» Next: A look at Xfce
« Previous: Nginx web server