Files
homelab-optimized/docs/services/individual/baikal-clients.md
Gitea Mirror Bot e7652c8dab
Some checks failed
Documentation / Build Docusaurus (push) Failing after 5m3s
Documentation / Deploy to GitHub Pages (push) Has been skipped
Sanitized mirror from private repository - 2026-04-20 01:32:01 UTC
2026-04-20 01:32:01 +00:00

6.6 KiB

Baikal — Client Setup

Companion to baikal.md (auto-generated from compose). This file is hand-maintained and covers how to connect CalDAV/CardDAV clients to the Baikal server on Atlantis.

Server Reference

Field Value
Host Atlantis (Synology NAS)
Container baikal (image ckulka/baikal)
Port 12852 → container 80
Auth HTTP Digest (not Basic)
DAV root /dav.php/
Admin UI http://<host>:12852/admin/

Endpoints (all equivalent for authed CalDAV)

URL When to use
http://192.168.0.200:12852/ LAN-only clients (dashboard, LAN appliances)
http://atlantis:12852/ Nodes with Tailscale MagicDNS
http://atlantis.tail.vish.gg:12852/ Preferred for portable clients (laptops that move on/off LAN) — stable DNS, works everywhere on the tailnet
http://100.83.230.112:12852/ Raw Tailscale IP — fallback if DNS misbehaves

URL patterns

  • Principal: /dav.php/principals/<user>/ — point auto-discovering clients (iOS, macOS, DAVx⁵) here.
  • Calendar: /dav.php/calendars/<user>/<calendar-uri>/ — explicit calendar URL for clients that need it (Thunderbird with "Locate calendar" off).
  • Address book: /dav.php/addressbooks/<user>/<addressbook-uri>/.

Credentials

  • Baikal users live in the users table of /volume1/docker/baikal/Specific/db/db.sqlite. Passwords are stored as MD5 digesta1 (MD5(user:BaikalDAV:password)) — not reversible.
  • The vish user password is referenced by the dashboard's upcoming-events widget (see dashboard/api/routers/overview.py, BAIKAL_PASS constant). Pull it from there — do not paste it into docs or client configs that get committed.
  • Reset or create a user from the admin UI at /admin/ (login with the admin password from compose env).

Inspecting the database

No sqlite3 binary in the container — use PHP PDO:

ssh atlantis "sudo /usr/local/bin/docker exec baikal php -r '
\$db=new PDO(\"sqlite:/var/www/baikal/Specific/db/db.sqlite\");
foreach(\$db->query(\"SELECT id,username FROM users\") as \$r){
  echo \$r[\"id\"].\" \".\$r[\"username\"].PHP_EOL;
}'"

Useful tables: users, principals, calendars, calendarinstances (displayname, ACL, share state), calendarobjects, addressbooks, cards.

Thunderbird (GUI path)

  1. File → New → Calendar → On the Network → Next.
  2. Username: Baikal user (e.g. vish).
  3. Location: either
    • http://atlantis.tail.vish.gg:12852/dav.php/principals/vish/ — lets TB auto-discover all calendars for that user, or
    • a specific calendar URL, e.g. http://atlantis.tail.vish.gg:12852/dav.php/calendars/vish/default/.
  4. Find Calendars → select the one(s) to add → Subscribe.
  5. Password prompt appears on first sync; tick Use Password Manager to save.

Thunderbird (headless / prefs.js path)

Use when the client machine is remote and you want to drop a calendar in without touching the GUI. Procedure:

  1. Close Thunderbird. prefs.js is rewritten on exit — any edits made while it is running get clobbered.
  2. Clear stale lock files if present: rm -f ~/.thunderbird/<profile>/lock ~/.thunderbird/<profile>/.parentlock.
  3. Back up: cp prefs.js prefs.js.bak-$(date +%Y%m%d-%H%M%S).
  4. Generate a UUID: cat /proc/sys/kernel/random/uuid.
  5. Append the registry block below (replace <UUID> and tweak name, color, uri, username).
  6. Update the calendar.list.sortOrder line — append the new UUID (space-separated) so the calendar actually shows up.
user_pref("calendar.registry.<UUID>.cache.enabled", true);
user_pref("calendar.registry.<UUID>.calendar-main-in-composite", true);
user_pref("calendar.registry.<UUID>.color", "#3aa57c");
user_pref("calendar.registry.<UUID>.disabled", false);
user_pref("calendar.registry.<UUID>.forceEmailScheduling", false);
user_pref("calendar.registry.<UUID>.imip.identity.key", "id1");
user_pref("calendar.registry.<UUID>.name", "vish (Baikal)");
user_pref("calendar.registry.<UUID>.notifications.times", "");
user_pref("calendar.registry.<UUID>.readOnly", false);
user_pref("calendar.registry.<UUID>.refreshInterval", "30");
user_pref("calendar.registry.<UUID>.suppressAlarms", false);
user_pref("calendar.registry.<UUID>.type", "caldav");
user_pref("calendar.registry.<UUID>.uri", "http://atlantis.tail.vish.gg:12852/dav.php/calendars/vish/default/");
user_pref("calendar.registry.<UUID>.username", "vish");

Password handling: do not attempt to pre-populate the login store — it is NSS-encrypted and requires live TB APIs to write correctly. Leave the password out of prefs.js entirely; on first sync Thunderbird will prompt, and the user ticks Use Password Manager once.

Verification (from client machine, before TB relaunch): confirm the client can reach the URL with the credentials:

curl -s -o /dev/null -w 'HTTP %{http_code}\n' \
  --digest -u '<user>:<password>' \
  http://atlantis.tail.vish.gg:12852/dav.php/calendars/<user>/default/

Expect HTTP 200. If 401, the password is wrong or the realm name changed. If no response, check Tailscale reachability (tailscale status | grep atlantis) before blaming Baikal.

Deployed clients (as of 2026-04-19)

Client Calendar URL Auth flavor
Dashboard widget (homelab-vm) vish/default http://192.168.0.200:12852/dav.php/calendars/vish/default/ Digest via httpx.DigestAuth, creds in dashboard/api/routers/overview.py
Thunderbird on moon laptop vish/default http://atlantis.tail.vish.gg:12852/dav.php/calendars/vish/default/ Digest, password in TB password manager (user-entered on first sync)

Troubleshooting

  • 401 Unauthorized: Baikal speaks Digest, not Basic. Most curl tests need --digest. Thunderbird handles this automatically.
  • Calendar appears but never refreshes: check calendar.registry.<UUID>.cache.enabled is true; the local-cache is what TB displays between network syncs.
  • Events not showing on the dashboard: the widget only queries vish/default. Other calendars need a separate calendar-query REPORT against their URL.
  • Admin UI locked out: INSTALL_DISABLED is touched in /var/www/baikal/Specific/ after first setup. Delete that file in the container to re-enable the install wizard if you need to reset the admin password.
  • baikal.md — auto-generated compose reference.
  • hosts/synology/atlantis/baikal/baikal.yaml — stack definition.
  • dashboard/api/routers/overview.py — dashboard CalDAV consumer (reference implementation for Digest queries).