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:
| Variant | Description | Port |
|---|---|---|
ckulka/baikal:nginx | Nginx-based image (smaller, recommended) | 80 |
ckulka/baikal:apache | Apache httpd-based image | 80 |
Prerequisites
Before deploying Baïkal, ensure you have:
Deploying Baïkal
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.
Create a New App
Create a new app within your project using the following Docker image from Docker Hub:
ckulka/baikal:nginxAlternatively, use
ckulka/baikal:apacheif you prefer the Apache-based variant.Configure Environment Variables (Optional)
Baïkal works out-of-the-box with sensible defaults. However, you can optionally configure these environment variables:
Variable Description Example BAIKAL_SERVERNAMEServer name for Apache (Apache variant only) dav.example-app.klutch.shBAIKAL_SERVERALIASServer aliases for Apache (Apache variant only) calendar.example.comBAIKAL_SKIP_CHOWNSkip file permission fixes on startup trueConfigure Persistent Storage
Baïkal stores its configuration and database in two directories. Add persistent volumes to preserve your data:
Mount Path Description Recommended Size /var/www/baikal/SpecificDatabase and user data 1GB /var/www/baikal/configConfiguration files 100MB 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.
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
- Time Zone: Select your preferred time zone
- Card/CalDAV URI: Leave as default (
/dav.php/) unless you have specific requirements - Admin Password: Set a strong administrator password
- Admin Email: Enter the admin email address
Step 3: Database Configuration
Baïkal supports two database options:
SQLite (Default, Recommended for Small Deployments)
- No additional configuration required
- Data stored in
/var/www/baikal/Specific/db/db.sqlite - Perfect for personal use or small teams
MySQL (Recommended for Production)
If you need MySQL for larger deployments, first deploy a MySQL instance using our MySQL guide, then configure:
| Setting | Description |
|---|---|
| MySQL Host | Your MySQL app hostname |
| MySQL Database | Database name (e.g., baikal) |
| MySQL Username | Database user |
| MySQL Password | Database 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
- Log in to the admin interface at
/admin/ - Navigate to Users and resources
- Click Add user
- Fill in:
- Username: The login identifier
- Display Name: Friendly name shown in clients
- Email: User’s email address
- Password: User’s password
- Click Save changes
Creating Calendars and Address Books
Calendars and address books are created per user:
- Click on a user in the Users and resources section
- Use Add calendar or Add address book to create new resources
- Configure the name and other settings as needed
Connecting Clients
iOS/macOS
- Go to Settings → Calendar (or Contacts) → Accounts
- Select Add Account → Other
- Choose Add CalDAV Account or Add CardDAV Account
- Enter:
- Server:
https://baikal.example-app.klutch.sh/dav.php/ - User Name: Your Baïkal username
- Password: Your Baïkal password
- Server:
Android (DAVx5)
- Install DAVx5 from F-Droid or Google Play
- Add a new account
- Select Login with URL and user name
- Enter:
- Base URL:
https://baikal.example-app.klutch.sh/dav.php/ - User name: Your Baïkal username
- Password: Your Baïkal password
- Base URL:
- Select the calendars and address books to sync
Mozilla Thunderbird
- Go to Calendar tab
- Right-click and select New Calendar
- Choose On the Network
- Select CalDAV
- Enter:
- Location:
https://baikal.example-app.klutch.sh/dav.php/calendars/USERNAME/default/ - Replace
USERNAMEwith your Baïkal username
- Location:
For contacts, install the TbSync add-on.
CalDAV/CardDAV URLs
The following URL patterns are used for connecting clients:
| Resource | URL Pattern |
|---|---|
| CalDAV Principal | https://your-app.klutch.sh/dav.php/principals/USERNAME/ |
| CardDAV Principal | https://your-app.klutch.sh/dav.php/principals/USERNAME/ |
| Calendar | https://your-app.klutch.sh/dav.php/calendars/USERNAME/CALENDAR_ID/ |
| Address Book | https://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:
docker-compose up -dAccess 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:
- SQLite Database:
/var/www/baikal/Specific/db/db.sqlite - Configuration:
/var/www/baikal/config/
If using MySQL, backup your MySQL database separately.
Restoring Data
To restore Baïkal:
- Deploy a fresh Baïkal instance
- Restore the
/var/www/baikal/Specificand/var/www/baikal/configvolumes from backup - 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
- Baïkal Official Website - Official documentation
- Baïkal GitHub Repository - Source code and issue tracking
- ckulka/baikal-docker - Docker image repository
- sabre/dav Documentation - CalDAV/CardDAV framework documentation
- DAVx5 - Android CalDAV/CardDAV sync app