Skip to content

Deploying Baïkal

Baïkal is a lightweight, open-source CalDAV and CardDAV server that enables you to self-host your calendars and contacts with complete privacy and control. In an era where major tech companies harvest personal data from cloud-synced calendars and contacts, Baïkal offers a refreshing alternative—a self-hosted solution that keeps your appointments, events, birthdays, and contact information entirely under your control.

Built on the robust sabre/dav framework (the same technology that powers enterprise-grade calendar systems), Baïkal combines powerful CalDAV and CardDAV protocol support with an intuitive web-based administrative interface. This makes it accessible to both technical administrators and everyday users who simply want to sync their calendars and contacts across devices without relying on Google, Apple, or Microsoft cloud services.

Originally developed by Net Gusto and fruux, Baïkal has evolved into a community-driven project with contributions from developers worldwide. Its name, derived from Lake Baikal in Siberia—the world’s deepest and oldest freshwater lake—reflects the project’s depth of functionality and long-term stability.

What are CalDAV and CardDAV?

Before diving into the deployment, it’s helpful to understand the protocols that Baïkal implements:

  • CalDAV (Calendaring Extensions to WebDAV): An open standard protocol that allows clients to access and manage calendar data on remote servers. It enables real-time synchronization of events, appointments, reminders, and tasks across multiple devices and applications.

  • CardDAV (vCard Extensions to WebDAV): A companion protocol for synchronizing contact information. It allows clients to access and share address book data, including names, phone numbers, email addresses, and other contact details.

These protocols are supported by virtually all modern calendar and contact applications, including Apple Calendar, Apple Contacts, Mozilla Thunderbird, Evolution, and Android apps like DAVx5.

Why Baïkal?

Baïkal offers a compelling solution for privacy-conscious users, families, and organizations:

  • Complete Privacy: Host your calendars and contacts on your own infrastructure—no third-party access to your personal data, meeting schedules, or contact lists
  • Universal Compatibility: Works seamlessly with iOS, macOS, Android (via DAVx5), Mozilla Thunderbird, GNOME Evolution, and any CalDAV/CardDAV compatible application
  • Lightweight & Fast: Minimal resource requirements (runs comfortably on a Raspberry Pi) make it perfect for small servers, containers, and edge deployments
  • Easy Administration: Intuitive web-based admin interface for managing users, calendars, and address books—no command-line expertise required
  • Flexible Database Options: Supports both SQLite (perfect for personal use) and MySQL/MariaDB (scalable for teams and organizations)
  • Multi-User Support: Create separate accounts for family members, team members, or clients with individual calendars and address books
  • Shared Calendars: Share calendars between users for family scheduling, team coordination, or resource booking
  • Standards Compliant: Full CalDAV and CardDAV protocol implementation via the battle-tested sabre/dav framework
  • Active Development: Regular updates with security patches and new features from the open-source community
  • Open Source Freedom: GPL-3.0 licensed, ensuring transparency and the freedom to modify and distribute

With nearly 3,000 GitHub stars, over 5 million Docker pulls, and a decade of production use, Baïkal has established itself as the leading self-hosted solution for calendar and contact synchronization. Whether you’re an individual seeking privacy, a family wanting shared calendars, or an organization requiring data sovereignty, Baïkal provides a reliable, standards-compliant solution.

Docker Image Options

The community-maintained ckulka/baikal Docker image provides two variants:

VariantDescriptionPort
ckulka/baikal:nginxNginx-based image (smaller, recommended)80
ckulka/baikal:apacheApache httpd-based image80

Prerequisites

Before deploying Baïkal, ensure you have:

Deploying Baïkal

  1. Create a New Project

    Log in to your Klutch.sh dashboard at klutch.sh/app and create a new project for your Baïkal deployment.

  2. Create a New App

    Create a new app within your project using the following Docker image from Docker Hub:

    ckulka/baikal:nginx

    Alternatively, use ckulka/baikal:apache if you prefer the Apache-based variant.

  3. Configure Environment Variables (Optional)

    Baïkal works out-of-the-box with sensible defaults. However, you can optionally configure these environment variables:

    VariableDescriptionExample
    BAIKAL_SERVERNAMEServer name for Apache (Apache variant only)dav.example-app.klutch.sh
    BAIKAL_SERVERALIASServer aliases for Apache (Apache variant only)calendar.example.com
    BAIKAL_SKIP_CHOWNSkip file permission fixes on startuptrue
  4. Configure Persistent Storage

    Baïkal stores its configuration and database in two directories. Add persistent volumes to preserve your data:

    Mount PathDescriptionRecommended Size
    /var/www/baikal/SpecificDatabase and user data1GB
    /var/www/baikal/configConfiguration files100MB
  5. Set Network Configuration

    Configure your app to use HTTP traffic on port 80.

    Baïkal’s web interface and CalDAV/CardDAV endpoints are served over HTTP. Klutch.sh handles HTTPS termination automatically.

  6. Deploy Your App

    Click Deploy to start your Baïkal instance. The deployment typically completes within a minute.

Initial Setup Wizard

After deployment, complete the setup wizard to configure Baïkal:

Step 1: Access the Admin Interface

Navigate to your Baïkal URL:

https://baikal.example-app.klutch.sh/admin/

You’ll be greeted by the Baïkal setup wizard.

Step 2: Configure Site Settings

  1. Time Zone: Select your preferred time zone
  2. Card/CalDAV URI: Leave as default (/dav.php/) unless you have specific requirements
  3. Admin Password: Set a strong administrator password
  4. Admin Email: Enter the admin email address

Step 3: Database Configuration

Baïkal supports two database options:

  • No additional configuration required
  • Data stored in /var/www/baikal/Specific/db/db.sqlite
  • Perfect for personal use or small teams

If you need MySQL for larger deployments, first deploy a MySQL instance using our MySQL guide, then configure:

SettingDescription
MySQL HostYour MySQL app hostname
MySQL DatabaseDatabase name (e.g., baikal)
MySQL UsernameDatabase user
MySQL PasswordDatabase password

Step 4: Complete Setup

Click Start using Baïkal to finalize the installation. You’ll be redirected to the admin dashboard.

Managing Users

Creating Users

  1. Log in to the admin interface at /admin/
  2. Navigate to Users and resources
  3. Click Add user
  4. Fill in:
    • Username: The login identifier
    • Display Name: Friendly name shown in clients
    • Email: User’s email address
    • Password: User’s password
  5. Click Save changes

Creating Calendars and Address Books

Calendars and address books are created per user:

  1. Click on a user in the Users and resources section
  2. Use Add calendar or Add address book to create new resources
  3. Configure the name and other settings as needed

Connecting Clients

iOS/macOS

  1. Go to SettingsCalendar (or Contacts) → Accounts
  2. Select Add AccountOther
  3. Choose Add CalDAV Account or Add CardDAV Account
  4. Enter:
    • Server: https://baikal.example-app.klutch.sh/dav.php/
    • User Name: Your Baïkal username
    • Password: Your Baïkal password

Android (DAVx5)

  1. Install DAVx5 from F-Droid or Google Play
  2. Add a new account
  3. Select Login with URL and user name
  4. Enter:
    • Base URL: https://baikal.example-app.klutch.sh/dav.php/
    • User name: Your Baïkal username
    • Password: Your Baïkal password
  5. Select the calendars and address books to sync

Mozilla Thunderbird

  1. Go to Calendar tab
  2. Right-click and select New Calendar
  3. Choose On the Network
  4. Select CalDAV
  5. Enter:
    • Location: https://baikal.example-app.klutch.sh/dav.php/calendars/USERNAME/default/
    • Replace USERNAME with your Baïkal username

For contacts, install the TbSync add-on.

CalDAV/CardDAV URLs

The following URL patterns are used for connecting clients:

ResourceURL Pattern
CalDAV Principalhttps://your-app.klutch.sh/dav.php/principals/USERNAME/
CardDAV Principalhttps://your-app.klutch.sh/dav.php/principals/USERNAME/
Calendarhttps://your-app.klutch.sh/dav.php/calendars/USERNAME/CALENDAR_ID/
Address Bookhttps://your-app.klutch.sh/dav.php/addressbooks/USERNAME/ADDRESSBOOK_ID/

Most modern clients can auto-discover calendars and address books from the base URL:

https://your-app.klutch.sh/dav.php/

Sample Docker Compose for Local Development

For local development and testing before deploying to Klutch.sh:

version: '3.8'
services:
baikal:
image: ckulka/baikal:nginx
ports:
- "80:80"
volumes:
- baikal_data:/var/www/baikal/Specific
- baikal_config:/var/www/baikal/config
restart: unless-stopped
volumes:
baikal_data:
baikal_config:

Save as docker-compose.yml and run:

Terminal window
docker-compose up -d

Access Baïkal at http://localhost and complete the setup wizard.

Local Development with MySQL

version: '3.8'
services:
baikal:
image: ckulka/baikal:nginx
ports:
- "80:80"
volumes:
- baikal_data:/var/www/baikal/Specific
- baikal_config:/var/www/baikal/config
depends_on:
mysql:
condition: service_healthy
restart: unless-stopped
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=rootpassword
- MYSQL_DATABASE=baikal
- MYSQL_USER=baikal
- MYSQL_PASSWORD=baikalpassword
volumes:
- mysql_data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
volumes:
baikal_data:
baikal_config:
mysql_data:

During setup, configure MySQL with:

  • Host: mysql
  • Database: baikal
  • Username: baikal
  • Password: baikalpassword

Backup and Restore

Backing Up Data

The essential data to backup:

  1. SQLite Database: /var/www/baikal/Specific/db/db.sqlite
  2. Configuration: /var/www/baikal/config/

If using MySQL, backup your MySQL database separately.

Restoring Data

To restore Baïkal:

  1. Deploy a fresh Baïkal instance
  2. Restore the /var/www/baikal/Specific and /var/www/baikal/config volumes from backup
  3. Restart the container

Troubleshooting

Common Issues

“Unable to complete setup” error

  • Ensure both persistent volumes are properly mounted
  • Check that the volumes have correct permissions

Calendar/Contact sync not working

  • Verify the URL format matches your client’s requirements
  • Ensure you’re using HTTPS (Klutch.sh provides this automatically)
  • Check that the username and password are correct

Admin interface not accessible

  • Navigate to /admin/ (with trailing slash)
  • Clear browser cache and cookies

File permission errors

  • The container automatically fixes permissions on startup
  • If issues persist, check that volumes are writable

Additional Resources