In this blog post I want to show how you can install your own, self-hosted CalDAV server that can be used by multiple users, how you can then create shared calendars and how you can integrate and synch everything to your Android smartphone. I used several information sources, which are mentioned at the corresponding places in the text, to achieve this and compiled everything into the following guide.
The Problem
To be organized is essential in today’s everyday life; it becomes even more important if you have to arrange appointments with family members. I and my wife mantain our individual digital calendars; for every “family” event we would have to inform each other, hoping that it won’t be forgot. An complete and reliable overview over my wife’s appointments of the near future is impossible this way.
The most obvious solution would be to use an online service such as Google Calendar, but I would not be happy to give away private data unnecessarily to Google. I am using an Android phone, but I try to decouple as most as possible from Google services. My contacts and my personal calendar are stored using Posteo and DAVdroid. However, Posteo does not allow to share calendars. Since I have an Rapberry Pi server at home, I decided to set up a self-hosted CalDAV server.
The Solution
A little research on this topic brought up two solutions that fit my purpose: Baïkal and Radicale. After some information gathering I decided to use Radicale since I found some sites1 2 3 that explain how to easily create sharable calendars using version 2.x of Radicale. For me a lightweight solution was a requirement; Baïkal needs a configured database such as MySQL or SQLite, an overhead I simply did not want to have.
Server
For the server, which runs Raspbian Jessie, I mainly used the instructions mentioned above in combination with the Radicale setup guide and the systemd Guide from the official Raspberry Pi site.
First, create a new user called radicale
that will later run the Radicale server as a service; this is a recommended way to keep the system secure:
$ sudo useradd --system --home-dir / --shell /sbin/nologin radicale
Code language: Bash (bash)
Then install the packages required by Radicale and Radicale itself. apache2-utils
is needed to use htpasswd
; the passwords will be encrypted using bcrypt (which needs libffi-dev
):
$ sudo apt-get install libffi-dev apache2-utils
$ python3 -m pip install --upgrade passlib bcrypt radicale
Code language: Bash (bash)
This setup uses the directory /etc/radicale
for the configuration files. First, create a configuration file /etc/radicale/configuration
:
[server]
hosts = 0.0.0.0:5232
[storage]
filesystem_folder = /path/to/collections
[auth]
type = htpasswd
htpasswd_filename = /path/to/users
# encryption method used in the htpasswd file
htpasswd_encryption = bcrypt
delay = 1
[rights]
type = from_file
file = /etc/radicale/rights
Code language: Bash (bash)
Second, create the /etc/radicale/rights
file that defines the rights of the users in the form of regular expressions. It is the basic form that is needed for users to access their own calendars; add an extra paragraph (you can see it at the beginning of the listing) that allows the specific user Alice to access Bob’s calendars that contain the String family:
# Allow Alice to access Bob's family calendar
[alice-family-access]
user = alice
collection = bob(/.*family.*)?
permission = rw
# Give owners read-write access to everything else:
[owner-write]
user = .+
collection = %(login)s(/.*)?
permission = rw
# Everyone can read the root collection
[read]
user = .*
collection =
permission = r
Code language: Bash (bash)
The users
file, which contains the user’s passwords, is created as follows:
$ htpasswd -B -c /etc/users user1
New password:
Re-type new password:
$ htpasswd -B /etc/users user2
New password:
Re-type new password:
Code language: Bash (bash)
The collection directory that later contains the calendar data is created as follows:
$ mkdir -p /path/to/collections
$ chown -R radicale:radicale /path/to/collections
Code language: Bash (bash)
Now the server can be started by using python3 -m radicale
. The CalDAV server should be accessible through http://localhost:5232/ using the web browser. Since Radicale should start on booting, a service is created for it with sudo nano /lib/systemd/system/radicale.service
. The configuration file also includes the security options from the Radicale page that did not let Radicale fail to start:
[Unit]
Description=A simple CalDAV (calendar) and CardDAV (contact) server
After=network.target
Requires=network.target
[Service]
ExecStart=/usr/bin/env python3 -m radicale
Restart=on-failure
User=radicale
# Optional security settings
PrivateTmp=true
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
Code language: Bash (bash)
FYI: The Radicale setup mentions the approach to use systemd as a user, but it seems (at least I could not get it to work!) that Raspbian Jessie is then not able to start the service correctly.
Now we can start/stop/restart the service using:
$ sudo systemctl start radicale.service
$ sudo systemctl stop radicale.service
$ sudo systemctl restart radicale.service
Code language: Bash (bash)
Finally, to have it started on booting we type:
$ sudo systemctl enable radicale.service
Code language: Bash (bash)
Android
On the Android phone I use DAVdroid, simply because I already have used it in combination with Posteo and it does a good job. Since my server is only accessible from the local network, I find it really useful that you can restrict DAVdroid to only sync if in a specific WLAN. One thing I had problems with is that Radicale does not really support calendar sharing for now: You have to manually enter the calendar URL you want to subscribe to. I recommend to go to the Android web browser, log in and then copy/paste the URL into DAVdroid since the adress is very long. For sharing, you have to send this URL to the person you want to share your calendar with. With the restriction to local WLAN, you can simply use the local IP address of the server.
DAVdroid makes the calendar available throughout the Android system, hence, it can be used in all calendar apps.
Summary
Using the instructions above, you have your own CalDAV server that serves calendars (and contacts) to your preferred calendar application.