Migrating calendars and contacts from Nextcloud to Radicale

Posted: 2023-04-09 08:53:16 by Alasdair Keyes

Direct Link | RSS feed

I've been running Nextcloud (https://nextcloud.com/) for several years (and Owncloud (https://owncloud.com/), prior to that) to provide my personal CalDAV calendar and CardDAV contact services.

My original intention was to make use of the other services that Nextcloud provides but as it turns out, I never have. It's a little overkill to run a full instance just for this functionality, it's also a big security footprint to keep updated and maintained when not making use if it to the full so I started to look for other solutions.

I tested out Radicale V3 and it seemed to do just what I needed. It provides both those services and is also included in the Debian repos, so it provides an easier install and update.

Although I tested out Radicale on Debian 11 which has V3, the server I will use for this is Debian 10 so I only get Radicale V2. Both seemed to work well, but this article is more about V2.

The configuration I chose was to run Radicale bound to localhost with htpasswd authentication and an Nginx reverse proxy in front to provide access via the internet. This seems to be the most basic and easiest setup. Although the bulk of this article is taken from the Radicale documentation, there are a few tweaks and changes included that I had to/wanted to make.

Note: Radicale refers to each calendar/contact entry as a collection, so you will see that terminology used here.

  1. Install

The python3 libraries are not requirements of the Radicale package, but if you're using htpasswd auth you will need them as they're required for it's htpasswd and bcrypt processing.

apt install radicale python3-passlib python3-bcrypt
  1. Configure Radicale

Edit /etc/radicale/config and ensure the following config exists.

type = htpasswd
htpasswd_filename = /etc/radicale/users
htpasswd_encryption = bcrypt
delay = 1
  1. Create the user
# htpasswd -B -c /etc/radicale/users yourusername
New password: ************
Re-type new password: ************
# chmod 640 /etc/radicale/users
# chown radicale: /etc/radicale/users
  1. Set up Nginx

This is straight from Radicale docs. The docs also provide a copy/paste Apache config too.

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  Host $http_host;
    proxy_pass_header Authorization;

If you're going to be importing existing data, you'll likely need to extend the reverse proxy timeouts as my calendar import took quite a few minutes. Your timeouts may vary but as an indicator my 1.2M calendar file took about 2-3 minutes to import.

proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;

Restart everything

# systemctl restart radicale.service
# systemctl reload nginx.service
  1. Download calendars and contacts from Nextcloud.

Once logged into your Nextcloud instance, you can get a single .ics and .vcf file for your calendar/contacts by going to the URL with ?export added to the end.

It should go without saying, not to make any changes to your contacts/calendars between making the backups here and setting up your clients to use the new Radicale server.

  1. Creation/Uploading of calendars

Login to the web interface that's provided by the NGINX/Apache config you created above. e.g. https://myradicaleserver.com/radicale/

The collections created use UUIDs, I didn't want to have to bother with those so I changed it to nicer paths...

# cd /var/lib/radicale/collections/collection-root/yourusername
# ls 
# ls -al
total 188
drwxr-x--- 4 radicale radicale   4096 Apr  8 20:13 .
drwxr-x--- 4 radicale radicale   4096 Apr  8 19:43 ..
drwxr-x--- 3 radicale radicale 167936 Apr  8 20:40 55f41fed-eccb-4feb-a460-69b1745d2c02
drwxr-x--- 3 radicale radicale  12288 Apr  8 20:16 6a2b1bfd-ca46-45e4-8dcf-861b448c519f
# mv 6a2b1bfd-ca46-45e4-8dcf-861b448c519f contacts
# mv 55f41fed-eccb-4feb-a460-69b1745d2c02 calendar
# ls -al
total 188
drwxr-x--- 4 radicale radicale   4096 Apr  8 20:13 .
drwxr-x--- 4 radicale radicale   4096 Apr  8 19:43 ..
drwxr-x--- 3 radicale radicale 167936 Apr  8 20:40 calendar
drwxr-x--- 3 radicale radicale  12288 Apr  8 20:16 contacts

Refreshing the web UI will show the updated paths.

  1. Import the dumps to Radicale
# curl -u 'yourusername:plaintextpassword' -X PUT https://yourradicaleserver.com/radicale/username/calendar --data-binary @personal-2023-04-08.ics
# curl -u 'yourusername:plaintextpassword' -X PUT https://yourradicaleserver.com/radicale/username/contacts --data-binary @Contacts-2023-04-08.vcf

Reresh the Web UI and you will notice that the name/description/colours you set will have been changed or removed. Use the Edit link to set them again.

That's it, you then just need to configure your clients to use the new calendars/contacts. I use Thunderbird for my PC and DavX5 on my phone and both worked with no issues.

If you found this useful, please feel free to donate via bitcoin to 1NT2ErDzLDBPB8CDLk6j1qUdT6FmxkMmNz

© Alasdair Keyes

IT Consultancy Services

I'm now available for IT consultancy and software development services - Cloudee LTD.

Happy user of Digital Ocean (Affiliate link)


Validate HTML 5