De-google your calendar with Baikal

Finding a usable calendaring solution is a common hangup for people looking to reclaim their personal privacy by de -googling. Despite being anti-google services, there is no denying that the Google Calendar UX is incredible. Giving up Google Calendar is far harder than moving off Gmail or other Google service. I know because it was the hardest thing for me to give up and find a replacement for, especially since I needed a calendaring solution not just for my personal life but for my business as well.

This post outlines why I think Baikal is the best Google Calendar replacement for people with similar priorities as me. Specifically, people who value their privacy while also appreciating how seamless of a user experience Google Calendar offers for both the owner of the calendar and the people on the receiving end of invitations.

Choosing a solution


Any replacement solution I was going to try needed to meet the below set of criteria. This set of criteria is probably different for everyone. For me, if something checked off all of these boxes, then it was likely to have a serviceable UX while also maintaining my privacy.

  • Kept me in control of my data
  • Auto sync across devices/clients
  • Email invitations
  • Server-side scheduling support
  • Could be used with my business email address (ProtonMail) and domain
  • OSS, ideally FOSS
  • Easy to self host and maintain
  • Calendar sharing
  • Can be used as a standalone app (aka doesn't require a full platform of other services)

Potential solutions and criteria grading

After doing some research, I decided to give each of the options in the table below a fair shake. I took all of them except Nextcloud for a spin in real world scenarios. The reason I didn't go with Nextcloud was because I don't actually want or need the full suite of stuff Nextcloud offers, so it would have been overkill to configure an entire Nextcloud instance just for a calendar. This table can be used for a quick glance "feature comparison " checklist. Instead of giving each solution a grade for each feature, which would be subjective and complex, I simply checked off the feature if it existed in the solution.

Baikal Etesync Nextcloud Radicale Fruux
Data control x x x x
Sync x x x x x
Invitations x x x
Scheduling x x x
Custom Domain x x x x x
FOSS x x x x
Easy self host x x x x
Sharing x x x
Standalone x x x

As is obvious by the title of this post, I decided to go with Baikal.

Why Baikal?

Given that my criteria rubric is somewhat subjective, I want to explain in a bit more detail why I chose Baikal . First off, is incredibly easy to self host. It is FOSS and based on a fork of sabre/dav which is maintained by the highly competent team at Fruxx, one of the solutions I looked at.

Additionally, the UX is exactly what I was looking for. I work with clients who all use different calendaring solutions (Google, Microsoft, etc...). After configuring the Baikal email plugin, I was able to create, edit, RSVP , and do everything else you would expect to do to meeting invitations and it provided my clients with the exact UX they are used to seeing. They were able to RSVP, add entries to their calendar, etc...Baikal handles all of the updates and RSVPs server side so I can do thinks from my desktop or phone without any type of manual replying.

Installing and configuring Baikal

I run Baikal on an Ubuntu 18.04 LTS server. I reverse proxy requests to the "dav" subdomain of my primary business top level domain. I connect to it using the Lightning extension for Thunderbird on my desktops, and through various calendar apps on Android/iOS.


The dependencies for running Baikal are minimal. Make sure you have PHP 7 and Apache/Nginx installed at a minimum You can use MySQL but I use the out of the box SQLite default. If you plan to use SSL, ensure Certbot is installed. And if you want to take advantage of the Invitation email plugin, install msmtp. Enable php-fpm and nginx to

$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install php nginx python-certbot-nginx msmtp

Install latest Baikal release

To install Baikal, you simply pull down the latest zip from the github releases page and unzip it to wherever you want to keep it. I keep it in /var/wwww since it is a simple web app. If you want to use the Invitation email plugin, make sure you use version 0.6.0 or higher. After unzipping the release, change the ownership of the directory to ensure the process that runs Nginx can access it. Ensure you enable Nginx and php-fpm to start every time the server starts. I am assuming you have a firewall configured via UFW.

$ cd /var/www
$ wget
$ unzip -d baikal
$ sudo chown -R www-data:www-data baikal
$ sudo systemctl enable nginx
$ sudo systemctl enable php7.0-fpm

Configure Nginx

To actually figure out if you installed Baikal correctly, create an Nginx server block to forward requests on port 80.

$ sudo touch /etc/nginx/sites-available/baikal
$ sudo ln -s /etc/nginx/sites-available/baikal /etc/nginx/sites-enabled
$ sudo nano /etc/nginx/sites-available/baikal

Enter the below contents. Replace with your domain and php fpm versions as appropriate.

server {
  listen 80;

  root  /var/www/baikal/html;
  index index.php;

  rewrite ^/.well-known/caldav /dav.php redirect;
  rewrite ^/.well-known/carddav /dav.php redirect;

  charset utf-8;

  location ~ /(\.ht|Core|Specific) {
    deny all;
    return 404;

  location ~ ^(.+\.php)(.*)$ {
    try_files $fastcgi_script_name =404;
    include        /etc/nginx/fastcgi_params;
    fastcgi_split_path_info  ^(.+\.php)(.*)$;
    fastcgi_pass   unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_param  PATH_INFO        $fastcgi_path_info;

Test and restart Nginx.

$ sudo nginx -t
$ sudo systemctl restart nginx

Verify it is installed correctly by going to in your browser.

At this point, you can start to configure Baikal, but I typically prefer to ensure I have SSL working before doing anything. To do so, generate SSL certs and enable them via Certbot. I always choose to redirect all traffic to use HTTPS.

$ sudo certbot --nginx -d
$ sudo systemctl restart nginx

Navigate again to the Baikal admin...should be on SSL now. If you are curious about how Certbot does it's SSL magic, you can take a look at the Nginx config, you can see how it handles the SSL certs and redirects.

Configure email invitation plugin

One of primary reasons I chose Baikal was because of its support for email invitations and scheduling. This setting is enabled by default as long as you enter an email address for the "Email invite sender address" setting when configuring Baikal.

The plugin that Baikal uses relies on PHP's mail() function. So the key is to make sure that PHP's mail() actually works how you want it to. There are many ways to do this. The easiest way I have found is to configure PHP mail() to use msmtp as the client.

To properly configure msmtp, you'll need access to an SMTP service. Typically people use Google's free SMTP server for small projects like this. Obviously I didn't do that since it would defeat the entire purpose of de-googling to begin with. Instead, I chose to use Sendgrid.

It is easy to sign up for a free Sendgrid account. Even once the trial expires, you get 100 emails a day. So unless you are sending a crap ton of calendar invites, you should be good. Follow the Sendgrid instructions for configuring the use of your own domain. It involves adding a few CNAME DNS records. After you do that, test out that the custom domain sending will work via the "Sender Authentication" section in the Sendgrid Console. Be sure to whitelist whatever address you want to use for Baikal as well. I just went with ""

Once you verified that you can send emails from your domain via Sengrid, configure an API client for the SMTP Relay API. Sendgrid has a bunch of great client libraries but we don 't need those here, they just complicate things. Once you have your API credentials, complete the below steps.

$ sudo nano /etc/.msmtp_php

Enter this as the contents of the file, pasting in your own information for the "password" and "from" fields.

account sendgrid
auth on
port 587
tls on
tls_starttls on
tls_trust_file /etc/ssl/certs/ca-certificates.crt
user apikey                  
password xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Close and save the file then modify it's permissions so the webserver can use it.

$ sudo chown www-data:www-data /etc/.msmtp_php

After that, configure PHP's sendmail to use the msmtp configuration.

$ sudo nano /etc/php/7.0/fpm/php.ini

Find the sendmail_path line and change the value to

sendmail_path = "/usr/bin/msmtp -C /etc/.msmtp_php --logfile /var/log/msmtp.log -a sendgrid -t"

Close and save. If you want to test out the msmtp configuration via the PHP CLI first, you can edit the same sendmail_path line in the /etc/php/7.0/cli/php.ini file and then run a CLI test with a sample email.

Using Baikal

Everything should be configured and working correctly, so the last thing to do is connect clients to your fresh new Baikal server and start using it! I primarily use Thunderbird when I am on my desktop work machine and DAVx5 + Etar on my Android device.


To configure Thunderbird, install/open the Lightning extension. Create a new calendar and use your version of this url: You will be prompted to enter your password, do that. Make sure you do NOT check "prefer client-side email scheduling."

Now you can try creating a test invite. Your Baikal server should send out an email invitation to the invited person . When that person RSVPs, your Baikal server will send you an email with their RSVP and also update the .ics invitation with the RSVP status of each attendee!

When you receive invites from others, you can RSVP directly from Thunderbird and the Baikal server will send the appropriate RSVP email to the owner of the event. It is great.


Download DAVx5 and sync it with your new calendar. You should now be able to create and edit invitations directly from the native calendar app on your phone and be assured that your Baikal server is sending out the proper email updates.