Keeper.sh
Calendar sync tool that aggregates and syncs events across providers
Alternative to: onecal, calendarbridge, reclaim.ai
Keeper.sh aggregates and syncs calendars across Google, Outlook/Office 365, iCloud, Fastmail, and CalDAV or ICS sources so events stay consistent everywhere. It runs incremental two-way sync with privacy controls (e.g. cloning events as free/busy only), lets you subscribe to a combined iCal feed, and manages everything from a self-hosted web dashboard.
Keeper.sh Docker Compose example
Self-host Keeper.sh on your own server, homelab, or VPS starting from this Docker Compose example.
It runs Keeper.sh in Docker containers using the official ghcr.io/ridafkih/keeper-standalone:latest image, with persistent volumes and automatic restarts preconfigured.
Review the environment variables and adjust them to your setup, save the file as compose.yml (or docker-compose.yml), and start the stack with docker compose up -d.
services:
keeper:
image: ghcr.io/ridafkih/keeper-standalone:latest
restart: unless-stopped
environment:
# Secret key used to sign authentication sessions. Use a long random string.
BETTER_AUTH_SECRET: "changeme"
# Key used to encrypt CalDAV credentials at rest. Use a long random string.
ENCRYPTION_KEY: "changeme"
# Comma-separated list of protocol+host origins allowed to reach the app (set this to your public URL behind a reverse proxy).
TRUSTED_ORIGINS: "http://localhost"
# Google OAuth client ID (optional; required to sync Google Calendar).
GOOGLE_CLIENT_ID: ""
# Google OAuth client secret (optional; required to sync Google Calendar).
GOOGLE_CLIENT_SECRET: ""
# Microsoft OAuth client ID (optional; required to sync Outlook/Office 365).
MICROSOFT_CLIENT_ID: ""
# Microsoft OAuth client secret (optional; required to sync Outlook/Office 365).
MICROSOFT_CLIENT_SECRET: ""
volumes:
- data:/var/lib/postgresql/data
volumes:
data:
Values set to changeme are required — replace them with your own
values before starting Keeper.sh.
Prefer a managed setup? WinterFlow installs, configures, and updates Keeper.sh for you using this same Docker Compose configuration.