Self-Host Cal.com (Cal.diy) with Docker
Is Cal.com still open source? The product Cal.com sells is not. Cal.com Inc. announced on 14 April 2026 that its commercial codebase was going closed source, citing how easily AI tools can now scan public code for vulnerabilities, and published the technical details on 15 April. The open-source, self-hostable project is now calcom/cal.diy, relicensed from AGPL-3.0 to MIT. It keeps the scheduling engine, booking flows, app store and API v2. Teams, Organizations, round-robin, Routing Forms, Workflows, SAML/SSO, Insights, Instant Booking and API v1 are gone. You self-host it with Docker Compose against PostgreSQL and Redis, and because no image is published, the compose file builds the app from source.
TL;DR
- Cal.com went closed-source in April 2026. Self-host calcom/cal.diy (MIT), not the old
calcom/cal.com(AGPL-3.0). That repo now redirects tocal.diyand is no longer where releases ship. - Stack: Next.js app + PostgreSQL + Redis + a separate API service, fronted by Caddy. No packaged Docker Hub image exists (checked 2026-09-26), so the compose file builds from source on first run.
- Cal.diy's own site calls it a use-at-your-own-risk community edition, recommended for personal, non-production use, and tells commercial users to run Cal.com instead. The MIT license allows commercial use; the vendor just doesn't stand behind it.
- Cal.com Inc. raised a $25M Series A led by Seven Seven Six in April 2022, so it's a funded, actively developed company, even though the OSS edition is now community-maintained on its own repo.
- Calendly Standard: $10/seat/mo billed annually ($12 billed monthly). Cal.com: $0/seat, host it yourself on a Liquid Web VPS.
Cal.com is a scheduling platform: individual booking pages, event types, availability rules, and calendar integrations (Google Calendar, Outlook, iCal). Read that as individual deliberately — the self-hosted MIT edition is genuinely good for one person's booking page, but it's no longer the team-scheduling replacement it used to be. Keep reading before you build on this guide if a team, not a solo calendar, is what you're replacing. It's one piece of the self-hosted CRM & GTM stack, alongside Twenty CRM and Chatwoot.
What the MIT edition can't do: Teams and Organizations — round-robin routing, collective events, team availability, and everything else that needs more than one person on a booking page — moved to the closed-source cloud product in the April 2026 split, along with Routing Forms, automated Workflows, SSO/SAML, Insights analytics, Instant Booking, AI Phone, role-based permissions (PBAC), and API v1. What's still in cal.diy: individual booking pages, event types, availability rules, the app store, calendar integrations, and API v2. If you need round-robin or team scheduling, self-hosting Cal.diy no longer covers you; that now requires Cal.com's cloud plans. Our open-source Calendly alternatives roundup compares Cal.diy with the other schedulers you can self-host.
Docker note (checked 2026-09-26): there is no Cal.diy image to pull. The calcom/cal.diy repository on Docker Hub was registered on 14 April 2026 but has no tags and zero pulls. The older calcom/cal.com image stopped at v6.2.0 on 2 March 2026, before the split, and the calcom/docker compose repo is archived (last push October 2025). The docker-compose.yml in the cal.diy repo names an image but also carries a build: section, so docker compose up builds the app locally, which is slower and heavier than a pull; this guide's footprint numbers below are marked pending for that reason. One trap: the cal.diy/docker page still tells you to run docker compose pull and cites a v5.6.19-arm tag, which doesn't exist on Docker Hub. Check that page on the day you deploy anyway, since the project split from the commercial repo in April 2026 and has not tagged a release since.
Cal.diy vs Cal.com: what you get where
| Cal.diy (self-hosted) | Cal.com (cloud) | |
|---|---|---|
| License | MIT | Closed source |
| Price | $0, plus your server | Free (1 user); Teams $12/user/mo; Organizations $28/user/mo (annual billing) |
| Booking pages, event types, availability | ✓ | ✓ |
| Calendar and video apps (app store) | ✓ | ✓ |
| Teams, round-robin, collective events | ✗ | Teams plan and up |
| Routing forms | ✗ | Teams plan and up |
| SAML SSO / SCIM | ✗ | Organizations plan |
| Security guarantee | None ("use at your own risk") | Vendor-run, SOC 2 on Organizations |
| Who patches and upgrades | You | Cal.com |
Cal.com prices from cal.com/pricing, annual billing, checked 2026-09-26. If you are one person and don't need the data on your own server, Cal.com's free cloud plan already gives you unlimited event types without any of the setup below.
Prerequisites
- A Liquid Web 4 GB Managed VPS (verify pricing) — a starting point, not a guarantee; see the Docker note above about the local build step
- Docker Engine 25+, Docker Compose V2, and
git - A domain with its A record pointing to the VPS IP
- (Optional) Google/GitHub OAuth app credentials for social login
- (Optional) SMTP credentials for booking confirmation emails
- 45-60 minutes:
cal.diybuilds its Docker image from source on first run, which takes longer than pulling a prebuilt tag
Clone and configure cal.diy
git clone https://github.com/calcom/cal.diy.git
cd cal.diy
cp .env.example .env
Edit .env and set at least these before you build. .env.example is 483 lines carrying about 174 variables for Stripe billing, Sentry, Twilio, and other integrations this guide doesn't cover — read it once before you run anything. You don't need a license key: the file's own header says "Cal.diy is fully open source — no license key is required." NEXT_PUBLIC_LICENSE_CONSENT appears only as an unset Docker build arg in docker-compose.yml and can be left empty.
# Domain and auth
NEXT_PUBLIC_WEBAPP_URL=https://cal.yourdomain.com
NEXTAUTH_URL=https://cal.yourdomain.com
NEXTAUTH_SECRET= # openssl rand -base64 32
CALENDSO_ENCRYPTION_KEY= # openssl rand -base64 24 (the README's value) -- required at build time
# Database — these four are NOT in .env.example; add them yourself.
# Compose interpolates them into the app's DATABASE_URL, and cal.diy's
# `database` service hardcodes the first three, so they must match it exactly.
POSTGRES_USER=unicorn_user
POSTGRES_PASSWORD=magical_password
POSTGRES_DB=calendso
DATABASE_HOST=database:5432
CALCOM_TELEMETRY_DISABLED=1
# SMTP (optional — required for booking confirmation emails)
EMAIL_FROM=noreply@yourdomain.com
EMAIL_SERVER_HOST=smtp.postmarkapp.com
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=your-postmark-server-token
EMAIL_SERVER_PASSWORD=your-postmark-server-token
# Google OAuth (optional — for Google Calendar + Google login)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
Those are cal.diy's upstream defaults, hardcoded as literals in the database service (docker-compose.yml lines 20-22, checked 2026-09-09). That service reads no .env file, so changing POSTGRES_PASSWORD in .env alone changes only the connection string the app dials with, and the first run fails with password authentication failed for user "unicorn_user". To use a password of your own, change it in both places — add a database block to the docker-compose.override.yml below and set the same value in .env:
services:
database:
environment:
- POSTGRES_USER=unicorn_user
- POSTGRES_PASSWORD=your-strong-password
- POSTGRES_DB=calendso
Do this before the first docker compose up: the postgres image applies POSTGRES_PASSWORD only when it initialises an empty data directory, so once the database-data volume exists you have to change the password with ALTER USER instead.
Add a Caddy reverse proxy
cal.diy's own docker-compose.yml runs Postgres, Redis, the web app (calcom), a separate API service (calcom-api), and an optional Prisma Studio admin UI — but it doesn't ship a reverse proxy or TLS. Drop this next to it as docker-compose.override.yml; Compose merges override files with the main one automatically, so it's the only compose file this guide asks you to write yourself:
# docker-compose.override.yml
# Adds Caddy (automatic HTTPS) and a health check in front of cal.diy's own
# docker-compose.yml. Adapted 2026-09-09 -- verify service and network names
# at https://github.com/calcom/cal.diy/blob/main/docker-compose.yml before
# you deploy; cal.diy split from the commercial repo in April 2026 and
# its compose file can still change.
services:
calcom:
healthcheck:
# Uses node directly instead of curl/wget -- neither is guaranteed to be
# installed in the app image, node is.
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/', r => process.exit(r.statusCode < 500 ? 0 : 1)).on('error', () => process.exit(1))"]
interval: 20s
timeout: 10s
retries: 5
start_period: 180s
caddy:
image: caddy:2-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
calcom:
condition: service_healthy
networks:
- stack
volumes:
caddy_data:
caddy_config:
Caddyfile
# Caddyfile — Cal.com reverse proxy
cal.yourdomain.com {
reverse_proxy calcom:3000 {
health_uri /
health_interval 20s
}
encode gzip
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains"
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
}
}
First-run setup
# 1. Start the database and cache first
docker compose up -d database redis
docker compose ps database # wait until healthy
# 2. Build and start Cal.com (the first build compiles the Next.js app --
# this is the slow step, expect several minutes, not seconds)
docker compose up -d calcom
# 3. Watch the logs until the app is listening on port 3000
docker compose logs calcom -f --tail 30
# 4. Start Caddy once Cal.com is healthy
docker compose up -d caddy
# 5. Visit https://cal.yourdomain.com
# Complete the setup wizard to create your admin account
Skip calcom-api and studio for now. Add them later with docker compose up -d calcom-api studio if you need API v2 endpoints or a database admin UI — a solo booking page doesn't require either.
Verify the stack
# All services should be Up and healthy
docker compose ps
# HTTP check -- cal.diy's health-endpoint path isn't confirmed stable yet,
# so a 200 here is what to look for rather than a specific JSON body
curl -s -o /dev/null -w "%{http_code}\n" https://cal.yourdomain.com
# Resource usage
docker stats --no-stream
Connect Google Calendar
For Google Calendar sync, you need a Google Cloud OAuth app:
- Go to console.cloud.google.com → Create project
- Enable the Google Calendar API and Google People API
- Create OAuth 2.0 credentials → Web application
- Add
https://cal.yourdomain.com/api/auth/callback/googleas an authorized redirect URI - Copy Client ID and Client Secret into
.envasGOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET - Rebuild and restart Cal.com:
docker compose up -d --build calcom - Users connect their calendar via Settings → Calendars → Connect a new calendar
Runtime footprint
We measured 900 MB idle RAM for the old single-container v4.9.0 setup in May 2026. That number no longer applies. The current cal.diy stack adds a Redis cache and a separate API service on top of Postgres and the web app, and the first run compiles the Next.js app from source instead of pulling a finished image — we haven't re-run a clean measurement against this heavier stack yet.
Treat the 4 GB VPS in Prerequisites as a floor, not a target. Run docker stats --no-stream after your first week of real usage and size up if you're consistently over 70% of the VPS's RAM. Paired with Twenty CRM (the Twenty CRM self-hosting guide) or Chatwoot for support, budget more headroom than this page's old 3 GB estimate gave you. We'll publish fresh numbers here once cal.diy has run in production long enough to trust them.
Upgrading cal.diy
There's no CALCOM_VERSION to bump anymore — the image builds from a git checkout, not a pulled tag. As of 2026-09-26 the latest tagged release is v6.2.0 (2026-03-01); no newer tag has shipped since the April 2026 split, so most upgrades right now mean tracking main rather than a release.
# Check for new releases at github.com/calcom/cal.diy/releases
# Read the changelog first -- major changes can rename env vars
git pull
# Rebuild and restart with the new code (migrations run automatically)
docker compose up -d --build calcom
# Watch for migration completion
docker compose logs calcom -f --tail 30
# Restart Caddy if needed
docker compose restart caddy
Cost vs Calendly
Compare against Calendly Standard, not Teams — cal.diy lost round-robin and team scheduling in the April 2026 split, so it isn't a fair swap-in for a Calendly Teams seat anymore. If your team needs round-robin routing, self-hosting doesn't cover you; see when this isn't right for you below.
| Calendly Standard (1 seat) | Cal.com on Liquid Web | |
|---|---|---|
| Monthly cost | $10/mo billed annually ($12 billed monthly) | ~$14/mo VPS |
| Per-seat cost | $10/mo | $0 (unlimited individual users) |
| Round-robin / team routing | ✗ (Teams plan only, $16/seat/mo annually) | ✗ (removed from the OSS edition) |
| Calendar integrations | ✓ | ✓ |
| Embeddable widget | ✓ | ✓ |
| Zapier/webhooks | ✓ | ✓ |
| SSO / SAML | ✗ | ✗ (cloud-only now) |
| Self-hostable | ✗ | ✓ |
| License | Proprietary | MIT |
Prices verified live at calendly.com/pricing on 2026-09-26; they change without notice, so check before you decide. Liquid Web pricing at liquidweb.com/vps-hosting/managed-vps/.
When this isn't right for you
- You're running a business on it and want someone accountable for security. Cal.diy's site says it is recommended for personal, non-production use, that Cal.com Inc. does not guarantee its security, and that commercial users should run Cal.com instead. You can still use it commercially under MIT, but you own the patching, the backups and the risk.
- You need round-robin or team scheduling. This is the one that changed in 2026:
cal.diy's MIT edition dropped Teams and Organizations along with SSO, so a booking page that routes across several people isn't available self-hosted anymore. That functionality now lives only in Cal.com's cloud product, or in Calendly Teams. - You need SAML/SSO for your team. Neither the old AGPL-3.0 edition nor the current MIT edition includes SSO self-hosted. It moved to Cal.com's commercial cloud product in the April 2026 split. If SSO is a hard requirement, compare Cal.com's cloud pricing against Calendly Teams rather than assuming self-hosting gets you there.
- You need HIPAA compliance for healthcare booking. Self-hosted Cal.com on Liquid Web can be HIPAA-compliant with a Liquid Web BAA, but Cal.diy itself comes with no compliance commitment (Cal.com lists HIPAA only on its paid cloud Organizations plan and up, checked 2026-09-26). The Liquid Web HIPAA hosting page covers what's included in the signed BAA.
- Your team is non-technical.
cal.diy's setup is more involved than it used to be. There's no prebuilt image to pull, so someone needs to own a git checkout, a local build, and Docker Compose. Calendly's no-infrastructure cloud version has zero operational overhead by comparison. - You need guaranteed uptime for customer-facing booking. If your booking page going down means lost revenue, add monitoring (uptime checks, alerting) and a tested restore procedure before going live.
Exit strategy
# Export your event types and scheduling data via the Cal.com API
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://cal.yourdomain.com/api/v2/event-types > event_types.json
# Dump the full database
docker compose exec database pg_dump -U unicorn_user calendso > calcom_export.sql
Cal.com stores all data in PostgreSQL. Bookings, event types, and availability rules are all in the dump. Importing into a new instance requires restoring the PostgreSQL dump and updating DATABASE_URL.
Not the commercial product. In mid-April 2026 Cal.com Inc. took its production codebase closed source. The open-source project continues as calcom/cal.diy under the MIT license (it was AGPL-3.0), and github.com/calcom/cal.com now redirects there. Cal.diy keeps the scheduling engine, booking flows, app store and API v2, but not Teams, round-robin, Routing Forms, Workflows, SSO, Insights or API v1.
No, as of 2026-09-26. The calcom/cal.diy repository on Docker Hub exists but has no tags, and the old calcom/cal.com image stopped at v6.2.0 in March 2026. Clone the cal.diy repo and run docker compose up, which builds the image locally from the repo's Dockerfile.
The MIT license allows it. Cal.diy's own site recommends it for personal, non-production use, says Cal.com Inc. does not guarantee its security, and points commercial users to Cal.com. If you self-host it for customer bookings, plan for your own patching, monitoring and backups.
Yes. Cal.com integrates with Google Meet, Zoom, Microsoft Teams, Jitsi Meet (self-hosted, no API key needed), Whereby, Daily.co, and others, each configured per event type. Jitsi Meet is the self-hostable option: it generates a meeting link automatically for each booking with no external API dependency.
No, not anymore. Round-robin routing, collective events, and Teams/Organizations moved out of the open-source edition when Cal.com Inc. relicensed calcom/cal.diy to MIT in April 2026 -- they're now cloud-only. The self-hosted edition covers individual booking pages well; for team scheduling you're comparing against Calendly Teams or Cal.com's own cloud plans, not against self-hosting.
Cal.com detects visitor time zones automatically via the browser and displays availability in the booker's local time. Event reminders and confirmation emails use the time zone of each party. Your availability rules are set in your configured time zone in Settings → Availability.
On self-hosted, you control the data completely: no data leaves your VPS. Cal.com has a telemetry option (disabled by setting CALCOM_TELEMETRY_DISABLED=1 in .env, as shown in this guide). For GDPR purposes: provide a privacy policy on your booking page, honour data deletion requests via the admin API, and ensure your VPS provider has a GDPR-compliant data processing agreement. Liquid Web covers this for EU processing.
Common mistakes and fixes
Cal.com shows a database connection error on first start.
Cal.com uses Prisma and runs migrations automatically on startup, but Postgres must be healthy first. The `depends_on` with `service_healthy` in cal.diy's compose file handles the ordering. If you started services manually without the healthcheck condition, run: `docker compose down && docker compose up -d`. If the error persists, check that DATABASE_URL in .env uses the correct postgres container name (`database`), not `localhost`.
OAuth login (Google, GitHub) returns 'redirect_uri_mismatch'.
OAuth providers require the redirect URI to exactly match what's registered in their developer console. Your NEXTAUTH_URL must match the scheme + domain you access Cal.com on (e.g., `https://cal.yourdomain.com`). In your OAuth app settings, add `https://cal.yourdomain.com/api/auth/callback/google` (for Google) as an authorized redirect URI. HTTP vs HTTPS mismatch is the most common cause.
Email notifications are not sent after booking confirmation.
Cal.com sends transactional emails via the SMTP settings configured in Settings → Developer → SMTP. Verify EMAIL_SERVER_HOST, EMAIL_SERVER_PORT, EMAIL_SERVER_USER, EMAIL_SERVER_PASSWORD, and EMAIL_FROM are set in your .env file and that the SMTP server accepts connections from your VPS IP. Test with: `docker compose exec calcom node -e "require('./packages/emails/email-manager').sendEmail({to:'test@example.com',subject:'test',html:'<p>test</p>'})"`. If the issue is with Calendly-originated booking notifications, those require the SMTP credentials to be set in the Cal.com admin UI as well.