A self-hosted Google Calendar viewer for multiple accounts, running in Docker on a Raspberry Pi.
-
Go to Google Cloud Console
-
Create a new project (or use an existing one)
-
Enable the Google Calendar API:
- APIs & Services → Library → search "Google Calendar API" → Enable
-
Enable the Google People API (for fetching email addresses):
- APIs & Services → Library → search "Google People API" → Enable
(or use "OAuth2 API" — the
userinfo.emailendpoint)
- APIs & Services → Library → search "Google People API" → Enable
(or use "OAuth2 API" — the
-
Create OAuth credentials:
- APIs & Services → Credentials → Create Credentials → OAuth client ID
- Application type: Desktop app ← important, not "Web application"
- Name: HeroCal (or anything)
- No redirect URIs needed — Google automatically allows
localhostfor Desktop apps - Copy the Client ID and Client Secret
-
Configure the OAuth consent screen:
- APIs & Services → OAuth consent screen
- User type: External (unless you have Google Workspace)
- Add your three Google account email addresses as Test users
cp .env.example .envEdit .env:
GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
GOOGLE_CLIENT_SECRET=your-client-secret
APP_URL=http://localhost:7777
docker compose up -d --buildOpen http://<PI_IP>:7777 in your browser.
Google doesn't allow private LAN IPs as OAuth redirect URIs, so the initial account connection must go through localhost. You only need to do this once — tokens are saved and auto-refreshed from then on.
Open an SSH tunnel from your laptop:
ssh -L 7777:localhost:7777 pi@<PI_IP>Keep that terminal open, then open http://localhost:7777 (not the Pi IP) in your browser. Click Connect for each account and complete the Google sign-in. Once all 3 accounts show as connected, close the SSH terminal.
From now on, access the app normally at http://<PI_IP>:7777 — no tunnel needed.
| Feature | How |
|---|---|
| Switch views | Month / Week / Agenda buttons (top right) |
| Create event | Click any date or time slot |
| Edit event | Click on an event |
| Delete event | Click event → Delete button |
| Toggle calendars | Checkboxes in the sidebar |
| Toggle all for an account | ◉ button next to the account |
| Drag to reschedule | Drag & drop events |
| Resize to change duration | Drag the bottom edge of an event (week view) |
docker compose pull
docker compose up -d --buildTokens are stored in ./data/tokens.json and persist across container restarts.