Calendar and contact management across devices using Radicale and vdirsyncer

-- 2025-10-16 --

Radicale is an open source CalDAV (calendars, to-do lists) and CardDAV (contacts) server that allows you to synchronize you data across devices without using propriety services that may compromise your privacy. This guide explains how I installed and configured it on a VPS running Debian Trixie and how I sync the server from my home computer (running Void Linux) using vdirsyncer so I can read it with khal (for my calendars) or khard (for my contacts). pass ("the standard unix password manager") is also used in this set up.

Radicale

vdirsyncer

khal

khard

pass

Radicale

First install Radicale on the server.

Changes to /etc/radicale/config

Radicale is often run through a reverse proxy such as nginx or apache, however I prefer to run it as completely independent service. In the [server] section, make the following changes:

This means that Radicale will listen on port 5232 and won't interfere with any of the more commonly used ports such as 80 or 443. You can create a self-signed certificate to allow SSL to be used but I've found that some client software doesn't like that so I created a signed certificate using Let's Encrypt. However I found there were permission problems further down the line. I got round these by simply copying the certificates into the /etc/radicale directory and changing the ownership of these files to the radicale user (which is automatically created on installation):

Before proceeding further check that the data storage directory exists with the correct ownership and permissions:

There are several ways to deal with authentication; I decided to use a htpasswd file to save my user's password (encrypting it with bcrypt), so I made the following changes to the [auth] section:

Running the service

As the server will be run by the user radicale a password must be created for them:

Start the service and check everything's OK:

Once Radicale is running on your server you can log in to it from your client machine's web browser at:

From here you can set up new calendars, contact lists etc. or amend existing ones.

vdirsyncer

Now I need to synchronise my data on my client machine (running Void Linux). First install vdirsyncer:

Choose and create locations for your calendar, contacts and vdirsyncer's status file. These are the ones I use:

Now create ~/.config/vdirsyncer/config:

The [general] section simply points to the location for the status file created earlier.

Synchronisation is done in pairs defined in the [pair <NAME>] section. 'a' and 'b' refer to the storages defined in [storage <NAME>] sections. 'collections' tells 'vdirsyncer discover' where to look for collections (calendars and contact lists. The 'metadata' property tells 'vdirsyncer metasync' what metadata should be synced for each collection. I sync 'displayname' and 'color' for calendars but only 'displayname' for contacts ('color' will produce an error for contacts).

The [storage <NAME>] sections are pretty self-explanatory. Make sure 'fileext' is correct for either calendars ('.ics') or contacts ('.vcf') on local storage. 'type' should be 'filesystem' for local storage and either 'caldav' (calendars) or 'carddav' (contacts) for remote storage.

'conflict_resolution' tells vdirsyncer what to if both a remote and local item has changed since the last sync. The default is to throw and error. I prefer to regard my local storage as definitive which in the above file means setting 'conflict_resolution' to 'a wins'.

The password for the remote storage can be stored in plain text

I prefer to fetch the password using pass. The reason the command is formatted in the way above is to prevent pass submitting any extra lines in its record.

There are a few ways to make vdirsyncer communicate over SSL, I have used 'verify_fingerprint'. To get the fingerprint run:

To initialise the storage run:

These commands will need to be run if you ever change the configuration for any of the pairs defined in the config file.

To actually synchronise the data and the metadata run:

It is best to set up a cron job to run these commands on a regular basis.

khal and khard

khal and khard are command line programs to display and manipulate calendars and contacts respectively. This isn't a guide on all the features that these applications have just instructions on getting them up and running.

To install:

khal configuration

Create the config file at '~/.config/khal/.config':

Under the [calendars] section there should be seperate subsection for each calendar. Start with the calendar's name in doubled up square brackets. Check the '~/.Calendar' directory for the calendar's multi-digit name and set path appropriately. Set 'type' to 'calendar'. I set 'color' to 'auto' here. This means that khal will use the colour vdirsyncer pulls from the remote storage. This colour will be a 24-bit value so won't display properly on a terminal that doesn't support 24-bit colour. If that is the case use one of the 16 colour names that khal supports, e.g.:

This won't synchronise with the remote storage so you'll have to match them up as best you can.

'priority' is a way to tell khal how to colour days in some views where there are events from different calendars. The colour from the calendar with the highest priority is used.

The [locale] section contains the date and time formats you want to use in different views of khal. The [default] section contains the 'default_calendar' that is used for various functions if you don't specify the calendar to use.

There are many other ways of customising khal through its config file. This guide just gives the basics.

Check khal works:

khard configuration

khard comes with an example configuration file which will be installed at '/usr/share/examples/khard/khard.conf.example'. Copy this to your configuration directory.

Edit the config file, it's mostly self-explanatory. Make sure that under the [addressbooks] section there is a seperate subsection for each list of contacts. Start with the addressbook's name in doubled up square brackets. Check the '~/.Contacts' directory for the addressbook's multi-digit name and set path appropriately.

Check it runs:

Linux tips and guides

Home page