Simple Shared Family Calendar and Notes with Radicale

There are lots of solutions for shared calendars, but most of them are not for free, not privacy-friendly, or neither. This note is about a simple self-hosting setup that works well for sharing a calendar, notes and TODO items with my family.

Radicale and Nginx Setup

I already had a Raspberry Pi 3 that is both a restic backup endpoint and running my mpd instance. Adding one more little useful service to it was a matter of tinkering for an hour or two. Out of the existing options, radicale seemed to be the most lightweight and quick to setup.

If your distribution provides it, you can just get it from there, but as it is a Python package, it can be installed easily via pip. The official quick-start documentation is really nice. All I had to do is update /etc/radicale/config with:

[server]
hosts = localhost:5232

[auth]
type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = autodetect

Then create some user credentials:

$ htpasswd -5 -c /etc/radicale/users user1
New password:
Re-type new password:
# Add another user
$ htpasswd -5 /etc/radicale/users user2
New password:
Re-type new password:

Note that htpasswd is not secure without https! You also need to configure a reverse proxying server like nginx and use certbot to enable https support.

For radicale behind nginx, a section like this (taken from here) is needed, which can be saved in e.g. /etc/nginx/radicale.conf:

### Proxy Forward to local running "radicale" server

## "well-known" redirect at least for Apple devices
rewrite ^/.well-known/carddav /radicale/ redirect;
rewrite ^/.well-known/caldav /radicale/ redirect;

## Base URI: /radicale/
location /radicale/ {
    proxy_pass        http://localhost:5232;
    proxy_set_header  X-Script-Name /radicale;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Host $host;
    proxy_set_header  X-Forwarded-Port $server_port;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_set_header  Host $http_host;
    proxy_pass_header Authorization;
}

and it must be included in the main /etc/nginx/nginx.conf to take effect:

http {
    ...
    server {
        ...
        include radicale.conf;
        ...
    }
    ...
}

If you run this from home and did not use nginx before, make sure to forward ports 80 (HTTP) and 443 (HTTPS) to your device running the services. I am using this in combination with built-in DynDNS functionality provided by my domain registrar.

Enable and start the nginx and radicale systemd service, and you are done! Just do not forget to regularly renew the HTTPS certificate with certbot renew.

If you do not want to bother with nginx and https, alternatively you could also only use radicale through your own VPN using Wireguard, but I think it is more inconvenient that the little bit of extra setup needed to set up nginx with https.

Android Phone Setup

On our Android phones, we are using following apps from F-Droid:

Then:

  • In DAVx5, you have to connect via URL with user name and point to https://your.host/radicale, providing the configured credentials.

  • In your calendar app, enable the calendars from your radicale instance.

  • In jtx Board, just enable DAVx5 synchronization support.

Conclusion

It all works pretty well and I have no complaints at all regarding the self-hosted calendar. One caveat is that all of us are using the same user radicale user account, because true shared calendars with multiple users that can share access to events and have to invite each other seemed to be more cumbersome than useful and overkill for our purposes, in any case that would have required a much more heavy software stack.

For notes and todos, the only major drawback is the lack of push-synchronization. This means that this setup is not suitable for near-realtime activity in the notes or TODO entries. But that is not strictly necessary for 99% of our real-world situations. Despite minor issues I have with the interface, I think jtx Board is a great app and without it I would not even know all the neat things you could do using just standard CalDAV and CardDAV features!

Overall, this is a neat setup that you can setup quickly and that is not a headache to maintain, so if you are still searching for the right solution, maybe this is worth a try!