Baikal CalDAV Runbook
Service: Baikal CalDAV
Label: Docker container baikal + LaunchAgent com.john.calendar-bridge
Tier: P2 (Business)
Port: 5232 (local), calendar.basicconsulting.no (public via Cloudflare)
What It Does
Self-hosted CalDAV server for ALAI Business calendar. Alem syncs from iPhone/MacBook via native Calendar app. calendar-bridge.js daemon scans emails every 5min, detects meeting invites, forwards to [email protected], and creates CalDAV events.
Architecture
Email (john@) → email-agent.js → calendar-bridge.js → Baikal CalDAV → Alem iPhone/Mac
↓
mail-native.js forward → [email protected]
Components
| Component | Location | Type |
|---|---|---|
| Baikal server | ~/system/services/baikal/docker-compose.yml | Docker |
| calendar-bridge.js | ~/system/tools/calendar-bridge.js | Tool + Daemon |
| LaunchAgent | ~/Library/LaunchAgents/com.john.calendar-bridge.plist | Daemon (5min) |
| Cloudflare tunnel | calendar.basicconsulting.no → localhost:5232 | Tunnel |
| Credentials | Vaultwarden → "Baikal CalDAV" | Vault |
| Calendar | "ALAI Business" (CalDAV user: alem) | CalDAV |
| Data | ~/system/services/baikal/data/ | Persistent volume |
Dependencies
- Docker (container: baikal)
- Cloudflare tunnel (com.john.cloudflared)
- Vaultwarden (credentials)
- mail-native.js (email forwarding)
- email-agent.js (inline meeting detection)
Health Check
# Quick check
node ~/system/tools/calendar-bridge.js test
# Docker container
docker ps --filter name=baikal
# CalDAV endpoint
curl -s -o /dev/null -w "%{http_code}" http://localhost:5232/dav.php/
# Public URL (expect 401 = auth required = healthy)
curl -s -o /dev/null -w "%{http_code}" https://calendar.basicconsulting.no/dav.php/
# List events
node ~/system/tools/calendar-bridge.js list
Common Failures & Fixes
Failure 1: Baikal container down
Symptoms: calendar-bridge.js test fails, CalDAV 502/connection refused Fix:
cd ~/system/services/baikal && docker compose up -d
Failure 2: Cloudflare tunnel not routing
Symptoms: Public URL returns 404 or timeout, local URL works fine Fix:
# Check config includes calendar entry
grep calendar ~/.cloudflared/config.yml
# Restart tunnel
launchctl kickstart -k gui/$(id -u)/com.john.cloudflared
Failure 3: Calendar-bridge scan finds nothing
Symptoms: Meeting invites arrive but no events created, no forwards Check:
# Check daemon is running
launchctl list | grep calendar-bridge
# Check logs
tail -50 ~/system/logs/calendar-bridge.log
# Check state file
cat ~/system/logs/calendar-bridge-state.json
# Manual scan with verbose
node ~/system/tools/calendar-bridge.js scan --verbose
Failure 4: Alem can't sync from iPhone
Symptoms: iPhone Calendar shows error, events not showing Check:
- Verify credentials in Vault:
node ~/system/tools/vault.js get "Baikal CalDAV" - Test public CalDAV endpoint (should return 401, not 502/404)
- iPhone settings: Server =
calendar.basicconsulting.no/dav.php/principals/alem
Failure 5: Authentication failure
Symptoms: 401 with correct password Fix: Password might be out of sync. Re-hash in Baikal DB:
NEW_PASS=$(bw get password "Baikal CalDAV" --session $(cat /tmp/bw-session))
DIGEST=$(printf "alem:BaikalDAV:$NEW_PASS" | md5)
docker exec baikal sqlite3 /var/www/baikal/Specific/db/db.sqlite \
"UPDATE users SET digesta1='$DIGEST' WHERE username='alem';"
Restart Procedure
# Restart Baikal
cd ~/system/services/baikal && docker compose restart
# Restart calendar-bridge daemon
launchctl kickstart -k gui/$(id -u)/com.john.calendar-bridge
Backup
- SQLite DB: ~/system/services/baikal/data/Specific/db/db.sqlite
- Config: ~/system/services/baikal/data/config/baikal.yaml
- Included in daily db-backup.sh via Docker volume mount
MC Task
Created: #3029 (Deploy), #3035 (Documentation + Watchdog)
No comments to display
No comments to display