Replacing Baïkal with Radicale

Licenced under CC-BY-4.0, created by Peter Molnar (), published at to canonical URL with keywords #contacts #calendar #CardDAV #CalDAV

I was becoming unhappy with Baïkal, my contact and calendar sync server: a growing number of clients was unable to use it, so I started to look for alternatives. This time I wanted something plain text based.

Probably one of the most attacked - as in argument - pages on the indieweb wiki1 is the database-antipattern entry2; it’s one of those with which nearly all of us disagrees when they first come in contact with it.

Let me quote it:

The database antipattern is the use of a database for primary long-term storage of posts and other personal content (like on an indieweb site), and is an anti-pattern due to the additional maintenance costs, uninspectability, platform-dependence, and long-term fragility of databases and their storage files, as documented with specific examples below.

The important part is in bold: database as primary, long term storage. For syncing my contacts I’ve been using:

  • Baïkal3 as server
  • DAVDroid4 on my phone
  • Evolution5 and Thunderbird6 on desktop
  • Rainloop7 as webmail

All of these can sync contacts, some calendars as well, all through the abomination called DAV, but all of them are storing these in some kind of database, mostly SQLite. SQLite is an ideal storage - for cache and for fast in-app lookups, but not for long term. If you’ve ever tried to import dumps from MySQL to SQLite or the other way around it quickly becomes visible why that antipattern entry was written.

So I decided to look for an alternative which would store my contacts in actual vcf and ics files. For the record, Baïkal has the actual VCF text in the database, so it’s not much more than a regular file storage.

A quick search revealed a Python implementation, called Radicale8. Although it mentions that it has a backend, called multifilesystem, which uses per contact files, unfortunately I could not get that one running. So I’m running it with filesystem backend, which uses a single, merged file per resource.

It wasn’t hard to get it running, and the documentation works fine as well, so if you want something that stores your contacts and calendars in plain text (well, ICS and VCF, not the most readable format, but it’s text), radicale is out there, use it.


hosts =
daemon = True
pid = /tmp/
ssl = False
base_prefix = /radicale/
realm = Radicale - Password Required

request = utf-8
stock = utf-8

caldav = '/home/radicale/%(user)s/caldav/'
carddav = '/home/radicale/%(user)s/carddav/'

type = IMAP

imap_hostname = my.imap.server
imap_port = 993
imap_ssl = True

committer = Peter Molnar <>

type = owner_only

type = filesystem

filesystem_folder = /home/radicale/db

config = /home/radicale/radicale_logging.conf

#Access-Control-Allow-Origin = *


keys = root

keys = console,file

keys = simple,full

level = WARNING
handlers = console,file

class = StreamHandler
level = INFO
args = (sys.stdout,)
formatter = simple

class = FileHandler
args = ('/home/radicale/log',)
formatter = full

format = %(message)s

format = %(asctime)s - %(levelname)s: %(message)s


location /radicale {
    try_files $uri @radicale;

location /.well-known/carddav {
    try_files $uri @radicale;

location /.well-known/caldav {
    try_files $uri @radicale;

location @radicale {
    proxy_set_header Proxy "";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Proxy-Connection "";
    proxy_ignore_client_abort on;