CalendarAdvanced is a self-hosted, local-first calendar web application for private servers. It follows the same practical architecture style as RailKeeper2: one Go service, a built React frontend, SQLite as the default database, Docker Compose deployment, first-run setup, local authentication, hardened containers, audit logs and an explicit update-check flow.
- Go backend as a modular monolith with
net/httpand clear internal package boundaries. - React + TypeScript frontend built with Vite and served by the production Go binary.
- SQLite primary storage with migrations in
backend/migrations. - No default credentials. The first user is created through the setup screen.
- Argon2id password hashing through the system Argon2 library.
- HTTP-only sessions, CSRF tokens, role checks, setup/login/password-reset rate limits and audit logging.
- Calendars, events, recurring events, attendees, reminders, invitations, calendar sharing, local exports and free/busy/conflict data.
- CalDAV/DAVx⁵ adapter under
/dav/and/.well-known/caldavwith separate revocable CalDAV tokens. - Dark theme by default with German and English UI translations.
- Flutter mobile client foundation in
mobile/for Android first and later iOS.
docker compose up -d --buildOpen http://localhost:8090. On first start, CalendarAdvanced opens the setup screen for the first admin account. No default user exists.
For a small private server, clone the repository and start the service. Create .env from .env.example when you want to override production settings:
git clone https://github.com/ichwars/CalendarAdvanced.git
cd CalendarAdvanced
cp .env.example .env
docker compose up -d --buildImportant production settings:
- Set
CALENDAR_PUBLIC_URLto the URL users open in the browser. - Set
CALENDAR_COOKIE_SECURE=truewhen serving through HTTPS. - Set
CALENDAR_TOKEN_ENCRYPTION_KEYto a stable 32-byte base64 value before first production use, or keep the generated/data/calendaradvanced.keybacked up. - Configure
CALENDAR_SMTP_HOSTandCALENDAR_SMTP_FROMwhen CalendarAdvanced should send event invitation and reminder e-mail. - Keep the
calendaradvanced_datavolume in your backup plan.
Check the running container:
docker compose ps
docker compose logs -f calendaradvancedStart backend and UI together:
start-dev.cmdBackend:
cd backend
go test ./...
go run ./cmd/calendaradvancedFrontend:
cd frontend
npm ci
npm run devMobile app:
cd mobile
flutter pub get
flutter create --platforms=android,ios .
flutter runThe mobile client currently targets the JSON API and uses secure local storage for the server URL, session cookie and CSRF token. See docs/mobile.md for the mobile roadmap.
Production frontend build:
cd frontend
npm ci
npm run buildUseful development defaults:
CALENDAR_ADDR=:8080
CALENDAR_HOST_PORT=8090
CALENDAR_DATA_DIR=./data
CALENDAR_MIGRATIONS_DIR=./migrations
CALENDAR_SEEDS_DIR=./seeds
CALENDAR_STATIC_DIR=../frontend/dist
CALENDAR_PUBLIC_URL=http://localhost:8090
CALENDAR_COOKIE_SECURE=falseCalendarAdvanced does not self-modify containers. The admin update screen checks a GitHub-Releases-compatible endpoint and shows the current version, available version, release notes and release URL. Update with:
git pull
docker compose up -d --buildDatabase migrations run on application start.
CalendarAdvanced is designed for trusted self-hosted installations, but avoids the dangerous defaults: no default admin, no clear-text tokens in the database, role checks server-side, strict security headers and audit logs for security-relevant activity. Read docs/security.md before exposing the app outside a private network.