Self-Hosting Guide: Deploy Cal.com for Scheduling

# calcom# scheduling# selfhosting# docker
Self-Hosting Guide: Deploy Cal.com for SchedulingRoyce

Self-Hosting Guide: Deploy Cal.com for Scheduling Cal.com is the open source Calendly...

Self-Hosting Guide: Deploy Cal.com for Scheduling

Cal.com is the open source Calendly alternative. Self-hosting gives you unlimited booking pages, unlimited event types, and team scheduling — all without per-user pricing.

Requirements

  • VPS with 2 GB RAM minimum
  • Docker and Docker Compose
  • Domain name (e.g., cal.yourdomain.com)
  • 10+ GB disk
  • SMTP service for booking notifications

Step 1: Clone and Configure

git clone https://github.com/calcom/cal.com.git
cd cal.com

# Copy environment
cp .env.example .env
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure Environment

Edit .env:

# App
NEXT_PUBLIC_WEBAPP_URL=https://cal.yourdomain.com
NEXTAUTH_SECRET=your-random-secret-min-32-chars
CALENDSO_ENCRYPTION_KEY=your-random-encryption-key-32-chars

# Database
DATABASE_URL=postgresql://calcom:your-strong-password@db:5432/calcom
DATABASE_DIRECT_URL=postgresql://calcom:your-strong-password@db:5432/calcom

# Email
EMAIL_FROM=cal@yourdomain.com
EMAIL_SERVER_HOST=smtp.resend.com
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=resend
EMAIL_SERVER_PASSWORD=re_your_api_key

# Calendar integrations (get from Google Cloud Console)
GOOGLE_API_CREDENTIALS={"client_id":"...","client_secret":"..."}

# Microsoft Calendar (get from Azure Portal)
# MS_GRAPH_CLIENT_ID=your-client-id
# MS_GRAPH_CLIENT_SECRET=your-client-secret
Enter fullscreen mode Exit fullscreen mode

Generate secrets:

openssl rand -hex 32  # NEXTAUTH_SECRET
openssl rand -hex 16  # CALENDSO_ENCRYPTION_KEY (must be 32 chars)
Enter fullscreen mode Exit fullscreen mode

Step 3: Docker Compose Setup

# docker-compose.yml
services:
  calcom:
    image: calcom/cal.com:latest
    container_name: calcom
    restart: unless-stopped
    ports:
      - "3000:3000"
    env_file: .env
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    container_name: calcom-db
    restart: unless-stopped
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=calcom
      - POSTGRES_USER=calcom
      - POSTGRES_PASSWORD=your-strong-password

volumes:
  postgres_data:
Enter fullscreen mode Exit fullscreen mode

Step 4: Start Cal.com

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Step 5: Reverse Proxy (Caddy)

# /etc/caddy/Caddyfile
cal.yourdomain.com {
    reverse_proxy localhost:3000
}
Enter fullscreen mode Exit fullscreen mode
sudo systemctl restart caddy
Enter fullscreen mode Exit fullscreen mode

Step 6: Initial Setup

  1. Open https://cal.yourdomain.com
  2. Create your admin account
  3. Set your timezone and availability

Step 7: Connect Calendars

Google Calendar:

  1. Go to Google Cloud Console
  2. Create a project and enable Calendar API
  3. Create OAuth 2.0 credentials
  4. Add https://cal.yourdomain.com/api/integrations/googlecalendar/callback as redirect URI
  5. Add credentials to .env

Microsoft Outlook:

  1. Go to Azure Portal
  2. Register an application
  3. Add Calendar.ReadWrite permissions
  4. Add https://cal.yourdomain.com/api/integrations/office365calendar/callback as redirect URI

Apple Calendar:

  • Connect via CalDAV in Cal.com settings

Step 8: Create Event Types

Event Type Duration Use Case
Quick Chat 15 min Initial calls, quick questions
Discovery Call 30 min Sales conversations
Team Meeting 30 min Internal sync
Deep Dive 60 min Technical discussions
Pair Programming 90 min Collaborative coding

For each event type, configure:

  • Duration and buffer time
  • Availability windows (e.g., Mon-Fri 9am-5pm)
  • Minimum notice (e.g., 4 hours)
  • Questions for invitees
  • Confirmation email template
  • Meeting location (Zoom, Google Meet, phone)

Step 9: Team Scheduling (Optional)

Set up team features:

  1. SettingsTeams → create a team
  2. Invite team members
  3. Create team event types:
    • Round Robin — distributes bookings evenly across team
    • Collective — requires all team members to be available
    • Managed Event Types — admin controls event type settings for all members

Step 10: Embed on Your Website

<!-- Inline embed -->
<iframe
  src="https://cal.yourdomain.com/your-username/30min"
  width="100%"
  height="700"
  frameborder="0"
></iframe>

<!-- Or use Cal.com embed snippet -->
<script>
  (function (C, A, L) {
    let p = function (a, ar) { a.q.push(ar); };
    let d = C.document;
    C.Cal = C.Cal || function () { let cal = C.Cal; let ar = arguments;
      if (!cal.loaded) { cal.ns = {}; cal.q = cal.q || []; d.head.appendChild(d.createElement("script")).src = A;
        cal.loaded = true; }
      if (ar[0] === L) { const api = function () { p(api, arguments); };
        const namespace = ar[1]; api.q = api.q || [];
        typeof namespace === "string" ? (cal.ns[namespace] = api) && p(api, ar) : p(cal, ar);
        return; }
      p(cal, ar);
    };
  })(window, "https://cal.yourdomain.com/embed/embed.js", "init");
  Cal("init");
  Cal("ui", {"styles":{"branding":{"brandColor":"#000000"}}});
</script>
Enter fullscreen mode Exit fullscreen mode

Production Hardening

Backups:

# Database backup (daily cron)
docker exec calcom-db pg_dump -U calcom calcom > /backups/calcom-$(date +%Y%m%d).sql
Enter fullscreen mode Exit fullscreen mode

Updates:

docker compose pull
docker compose up -d
Enter fullscreen mode Exit fullscreen mode

Monitoring:

  • Monitor port 3000 with Uptime Kuma
  • Set up alerts for failed email delivery
  • Monitor PostgreSQL disk usage

Resource Usage

Users RAM CPU Disk
1-10 2 GB 2 cores 10 GB
10-50 4 GB 2 cores 20 GB
50+ 8 GB 4 cores 30 GB

VPS Recommendations

Provider Spec Price
Hetzner 2 vCPU, 4 GB RAM €4.50/month
DigitalOcean 2 vCPU, 2 GB RAM $12/month
Linode 1 vCPU, 2 GB RAM $12/month

Compare scheduling tools on OSSAlt — features, integrations, and pricing side by side.