Training analytics, coaching, and ride intelligence built for cyclists
2.1K
Self-hosted cycling analytics platform. Training insights, coaching engine, and activity tracking — all on your own hardware. No subscriptions, no data harvesting.
mkdir cadiv && cd cadiv
Create a docker-compose.yml:
version: "3.9"
services:
postgres:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_USER: cadiv
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-cadiv123}
POSTGRES_DB: cadiv
volumes:
- cadiv-pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U cadiv"]
interval: 5s
timeout: 3s
retries: 5
cadiv:
image: lukevinskywynn/cadiv:latest
restart: unless-stopped
depends_on:
postgres:
condition: service_healthy
env_file: .env
ports:
- "4000:4000"
- "4321:4321"
volumes:
cadiv-pgdata:
Create a .env file:
# Account credentials (your login for the web & mobile apps)
CADIV_USERNAME=admin
CADIV_PASSWORD=your_strong_password
POSTGRES_PASSWORD=your_secure_db_password
SESSION_SECRET=your_session_secret
# Strava integration (optional — connect after login from Settings)
STRAVA_CLIENT_ID=your_strava_client_id
STRAVA_CLIENT_SECRET=your_strava_client_secret
# Optional: use an external database instead of the bundled Postgres
# DATABASE_URL=postgresql://user:pass@host:5432/cadiv
Start it up:
docker compose up -d
Open http://localhost:4321 and sign in with your CADIV_USERNAME / CADIV_PASSWORD credentials.
A single container running the full Cadiv stack:
On startup, the container automatically runs database migrations, starts the API server, and launches the web client.
| Variable | Required | Description |
|---|---|---|
CADIV_USERNAME | Yes | Your login username (auto-created on first startup) |
CADIV_PASSWORD | Yes | Your login password (bcrypt hashed, updated if changed) |
POSTGRES_PASSWORD | Yes | Password for the bundled Postgres container. Not needed if using DATABASE_URL |
SESSION_SECRET | Yes | Express session secret. Generate with openssl rand -hex 32 |
DATABASE_URL | No | Full PostgreSQL connection string. If set, uses this instead of the bundled Postgres container |
STRAVA_CLIENT_ID | No | From Strava API settings |
STRAVA_CLIENT_SECRET | No | From Strava API settings |
STRAVA_REDIRECT_URI | No | Default: http://localhost:4000/api/auth/strava/callback |
APP_ORIGIN | No | Default: http://localhost:4321 |
WHOOP_CLIENT_ID | No | For Whoop integration |
WHOOP_CLIENT_SECRET | No | For Whoop integration |
docker compose up -d # Start
docker compose down # Stop
docker compose pull && docker compose up -d # Update
docker compose logs -f cadiv # View logs
docker compose exec postgres pg_dump -U cadiv cadiv > backup.sql # Backup
Content type
Image
Digest
sha256:1f827ed36…
Size
407 MB
Last updated
8 months ago
docker pull lukevinskywynn/cadiv