Deploying Cal.com
Introduction
Cal.com (formerly Calendly alternative) is a powerful open-source scheduling and calendar platform that enables individuals, teams, and organizations to streamline appointment booking, meeting coordination, and time management. Built with modern web technologies including Next.js, Prisma, and tRPC, Cal.com offers a flexible, privacy-focused alternative to proprietary scheduling solutions with full control over your data and infrastructure.
Deploying Cal.com on Klutch.sh provides a production-ready, scalable infrastructure for your scheduling platform with automated Docker deployments, persistent storage for user data and configurations, secure PostgreSQL database integration, custom domain support with automatic SSL/TLS certificates, and enterprise-grade reliability. Whether you’re building a personal booking page, team scheduling system, or white-label scheduling solution for clients, Klutch.sh simplifies the deployment process and ensures your Cal.com instance is always available and performant.
This comprehensive guide walks you through deploying Cal.com on Klutch.sh using a Dockerfile, configuring PostgreSQL database connections, setting up persistent volumes for uploaded files and assets, managing critical environment variables for authentication and integrations, configuring calendar providers (Google Calendar, Microsoft Outlook, Apple Calendar), and implementing production best practices for a secure, scalable scheduling platform that handles thousands of bookings.
Prerequisites
Before you begin deploying Cal.com on Klutch.sh, ensure you have:
- A Klutch.sh account (sign up here)
- A GitHub repository for your Cal.com deployment configuration
- A PostgreSQL database instance (required for Cal.com)
- Basic understanding of Docker containers and environment variables
- (Optional) OAuth credentials for calendar integrations (Google, Microsoft, Apple)
- (Optional) SMTP server credentials for email notifications
- Access to the Klutch.sh dashboard
Understanding Cal.com Architecture
Cal.com consists of several key components that work together to provide a complete scheduling solution:
- Next.js Frontend: React-based application serving the booking interface, admin dashboard, and public booking pages
- tRPC API Layer: Type-safe API handling all business logic, booking management, and data operations
- Prisma ORM: Database abstraction layer managing PostgreSQL connections and migrations
- PostgreSQL Database: Primary data store for users, bookings, calendars, availability, and integrations
- Email Service: SMTP integration for booking confirmations, reminders, and notifications
- Calendar Integrations: OAuth connections to Google Calendar, Microsoft Outlook, Apple Calendar, and CalDAV providers
- Payment Processing: Optional Stripe integration for paid bookings and subscriptions
- Storage: File storage for user avatars, branding assets, and attachments
When deployed on Klutch.sh, Cal.com automatically detects your Dockerfile and builds a container image that includes all necessary components. The platform manages HTTP traffic routing, SSL certificates, environment variable management, and provides persistent storage options for uploaded files and assets.
Project Structure
A minimal repository structure for deploying Cal.com on Klutch.sh:
calcom-deployment/├── Dockerfile├── .dockerignore├── .gitignore├── .env.example└── README.mdThis simple structure allows Klutch.sh to automatically detect and build your Cal.com container. The official Cal.com Docker image comes pre-packaged with all necessary code, dependencies, and build artifacts, so you don’t need to include the source code in your repository.
Creating Your Dockerfile
Klutch.sh automatically detects a Dockerfile in the root directory of your repository. Create a Dockerfile that uses the official Cal.com image as the base:
Option 1: Simple Dockerfile (Recommended for Quick Start)
FROM calcom/cal.com:latest
# Expose the default Cal.com portEXPOSE 3000
# The official image includes a startup script# that handles database migrations and service startupCMD ["npm", "start"]Option 2: Production Dockerfile with Health Checks
FROM calcom/cal.com:latest
# Set working directoryWORKDIR /calcom
# Expose the application portEXPOSE 3000
# Add health check for monitoringHEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
# Start Cal.com with automatic database migrationsCMD ["npm", "run", "start"]Option 3: Custom Dockerfile with Build Optimizations
FROM calcom/cal.com:latest
# Install additional system dependencies if neededRUN apt-get update && apt-get install -y \ curl \ wget \ ca-certificates \ && rm -rf /var/lib/apt/lists/*
# Set working directoryWORKDIR /calcom
# Copy custom configuration files (optional)# COPY ./custom-config /calcom/config
# Expose the application portEXPOSE 3000
# Health check for production monitoringHEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
# Run database migrations and start the applicationCMD ["sh", "-c", "npx prisma migrate deploy && npm run start"]Important Notes:
- Cal.com listens on port 3000 internally by default
- Klutch.sh will route external HTTP traffic to port 3000 in your container
- The container includes the Next.js application, API routes, and scheduling engine
- Database migrations should run automatically on startup
- The official image is optimized for production deployments
Deploying to Klutch.sh
-
Create Your Repository
Create a new GitHub repository and add your Dockerfile:
Terminal window mkdir calcom-deploymentcd calcom-deployment# Create Dockerfilecat > Dockerfile << 'EOF'FROM calcom/cal.com:latestWORKDIR /calcomEXPOSE 3000HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1CMD ["sh", "-c", "npx prisma migrate deploy && npm run start"]EOF# Create .dockerignorecat > .dockerignore << 'EOF'node_modules.next.env.env.local.git.DS_StoredistEOF# Create .gitignorecat > .gitignore << 'EOF'node_modules/.env.env.local.DS_Store.next/dist/EOF# Initialize git and pushgit initgit add .git commit -m "Initial Cal.com deployment setup"git remote add origin https://github.com/YOUR_USERNAME/calcom-deployment.gitgit push -u origin main -
Set Up PostgreSQL Database
Cal.com requires a PostgreSQL database. You can either:
- Deploy PostgreSQL on Klutch.sh (see PostgreSQL deployment guide)
- Use a managed PostgreSQL service like AWS RDS, Google Cloud SQL, or DigitalOcean Managed Databases
- Use a free tier from services like ElephantSQL or Supabase
Create a database for Cal.com:
CREATE DATABASE calcom;CREATE USER calcom_user WITH PASSWORD 'your-strong-secure-password';GRANT ALL PRIVILEGES ON DATABASE calcom TO calcom_user;Note your connection details:
- Host: Your database hostname
- Port: 5432 (or 8000 if deployed on Klutch.sh with TCP traffic)
- Database: calcom
- Username: calcom_user
- Password: your-strong-secure-password
-
Access the Klutch.sh Dashboard
Navigate to klutch.sh/app and log in to your account.
-
Create a New Project
- Click “New Project” in the dashboard
- Enter a project name (e.g., “Scheduling Platform”)
- Select your preferred region for deployment
-
Create a New Application
- Within your project, click “New App”
- Name your application (e.g., “Cal.com”)
- Connect your GitHub repository containing the Dockerfile
-
Configure Build Settings
Klutch.sh automatically detects the Dockerfile in your repository root. If your Dockerfile is in a subdirectory, specify the build context path in the dashboard.
-
Set Up Persistent Storage
Cal.com benefits from persistent storage for user uploads and cache:
- In the app settings, navigate to the “Volumes” section
- Click “Add Volume”
- Set the mount path to
/calcom/.next/cache - Set the volume size (recommended: 5GB minimum)
- Click “Add” to attach the volume
Optionally add another volume for user uploads:
- Click “Add Volume” again
- Set the mount path to
/calcom/public/uploads - Set the volume size (recommended: 10GB minimum for production)
-
Configure Environment Variables
In the app settings, add the following required environment variables:
Essential Database Variables:
Terminal window DATABASE_URL=postgresql://calcom_user:your-password@your-db-host:5432/calcomFor databases deployed on Klutch.sh with TCP traffic:
Terminal window DATABASE_URL=postgresql://calcom_user:your-password@your-db-app.klutch.sh:8000/calcomApplication Configuration:
Terminal window NEXTAUTH_URL=https://your-app-name.klutch.shNEXTAUTH_SECRET=your-random-secret-key-min-32-charactersCALENDSO_ENCRYPTION_KEY=your-encryption-key-min-32-charactersEmail Configuration (SMTP):
Terminal window EMAIL_FROM=noreply@yourdomain.comEMAIL_SERVER_HOST=smtp.sendgrid.netEMAIL_SERVER_PORT=587EMAIL_SERVER_USER=apikeyEMAIL_SERVER_PASSWORD=your-sendgrid-api-keyOptional Google Calendar Integration:
Terminal window GOOGLE_API_CREDENTIALS={"web":{"client_id":"your-client-id","client_secret":"your-client-secret","redirect_uris":["https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback"]}}Optional Payment Integration (Stripe):
Terminal window STRIPE_PRIVATE_KEY=sk_live_your_stripe_keySTRIPE_PUBLIC_KEY=pk_live_your_stripe_keySTRIPE_WEBHOOK_SECRET=whsec_your_webhook_secretPAYMENT_FEE_PERCENTAGE=0.005PAYMENT_FEE_FIXED=10Security Best Practice: Always use the “Secret” checkbox for sensitive values like database passwords, API keys, and encryption keys.
-
Configure Traffic Settings
- In the “Networking” section, select HTTP as the traffic type
- Set the internal port to 3000 (Cal.com’s default port)
- Enable automatic HTTPS/SSL (provided by Klutch.sh)
-
Deploy the Application
- Review all settings
- Click “Deploy” to start the build process
- Klutch.sh will:
- Clone your repository
- Detect the Dockerfile
- Build the container image
- Deploy to your selected region
- Provision persistent storage
- Run database migrations automatically
- Configure networking and SSL
-
Monitor Deployment Progress
- View real-time build logs in the dashboard
- Wait for the deployment status to show “Running”
- Initial startup may take 3-5 minutes as Cal.com runs database migrations and initializes services
- Watch for successful migration messages in the logs
Once deployment completes, your Cal.com instance will be accessible at https://your-app-name.klutch.sh or your configured custom domain.
Database Configuration and Optimization
Cal.com requires PostgreSQL and benefits significantly from proper database configuration and optimization.
Connection String Format
The DATABASE_URL must follow PostgreSQL connection string format:
postgresql://[user]:[password]@[host]:[port]/[database]?[parameters]Examples:
Standard PostgreSQL:
DATABASE_URL=postgresql://calcom_user:password123@postgres.example.com:5432/calcom?schema=publicWith SSL enabled:
DATABASE_URL=postgresql://calcom_user:password123@postgres.example.com:5432/calcom?schema=public&sslmode=requireKlutch.sh TCP deployment:
DATABASE_URL=postgresql://calcom_user:password123@postgres-app.klutch.sh:8000/calcom?schema=publicDatabase Performance Optimization
-
Configure Connection Pooling
Add connection pool parameters to your DATABASE_URL:
Terminal window DATABASE_URL=postgresql://user:pass@host:5432/calcom?schema=public&connection_limit=20&pool_timeout=20 -
Add Database Indexes
Connect to your PostgreSQL database and create performance indexes:
-- Index for booking lookupsCREATE INDEX idx_bookings_user_id ON "Booking"("userId");CREATE INDEX idx_bookings_event_type_id ON "Booking"("eventTypeId");CREATE INDEX idx_bookings_status ON "Booking"("status");CREATE INDEX idx_bookings_start_time ON "Booking"("startTime");-- Index for availability checksCREATE INDEX idx_availability_user_id ON "Availability"("userId");CREATE INDEX idx_availability_event_type_id ON "Availability"("eventTypeId");-- Index for user lookupsCREATE INDEX idx_users_email ON "User"("email");CREATE INDEX idx_users_username ON "User"("username"); -
Set Appropriate Connection Limits
For production deployments, configure your PostgreSQL server:
max_connections = 100shared_buffers = 256MBeffective_cache_size = 1GBwork_mem = 16MB -
Enable Query Logging for Debugging
During initial setup, enable slow query logging:
log_min_duration_statement = 1000
Database Backup Strategy
-
Automated Daily Backups
Set up a cron job or scheduled task:
#!/bin/bashDATE=$(date +%Y%m%d_%H%M%S)pg_dump -h your-db-host -U calcom_user -d calcom > /backups/calcom_$DATE.sql# Compress the backupgzip /backups/calcom_$DATE.sql# Upload to S3 or object storageaws s3 cp /backups/calcom_$DATE.sql.gz s3://your-backup-bucket/calcom/# Delete local backups older than 7 daysfind /backups -name "calcom_*.sql.gz" -mtime +7 -delete -
Test Restore Procedures
Periodically test restoring from backups:
Terminal window # Download backupaws s3 cp s3://your-backup-bucket/calcom/calcom_20240115_120000.sql.gz .# Decompressgunzip calcom_20240115_120000.sql.gz# Restore to test databasepsql -h test-db-host -U calcom_user -d calcom_test < calcom_20240115_120000.sql -
Point-in-Time Recovery
For critical deployments, enable PostgreSQL WAL archiving for point-in-time recovery.
Environment Variables Reference
Required Variables
| Variable | Description | Example |
|---|---|---|
DATABASE_URL | PostgreSQL connection string (required) | postgresql://user:pass@host:5432/calcom |
NEXTAUTH_URL | Full URL where Cal.com is hosted | https://cal.example.com |
NEXTAUTH_SECRET | Random secret for session encryption (min 32 chars) | openssl rand -base64 32 |
CALENDSO_ENCRYPTION_KEY | Encryption key for sensitive data (32 chars) | openssl rand -hex 16 |
Email Configuration
| Variable | Description | Example |
|---|---|---|
EMAIL_FROM | Sender email address | notifications@example.com |
EMAIL_SERVER_HOST | SMTP server hostname | smtp.sendgrid.net |
EMAIL_SERVER_PORT | SMTP server port | 587 |
EMAIL_SERVER_USER | SMTP username | apikey |
EMAIL_SERVER_PASSWORD | SMTP password/API key | SG.xxxxx |
Calendar Integrations
| Variable | Description |
|---|---|
GOOGLE_API_CREDENTIALS | JSON credentials for Google Calendar OAuth |
MS_GRAPH_CLIENT_ID | Microsoft Graph API client ID |
MS_GRAPH_CLIENT_SECRET | Microsoft Graph API client secret |
APPLE_CALENDAR_CLIENT_ID | Apple Calendar client ID |
APPLE_CALENDAR_CLIENT_SECRET | Apple Calendar client secret |
Payment Integration (Stripe)
| Variable | Description |
|---|---|
STRIPE_PRIVATE_KEY | Stripe secret key |
STRIPE_PUBLIC_KEY | Stripe publishable key |
STRIPE_WEBHOOK_SECRET | Stripe webhook signing secret |
PAYMENT_FEE_PERCENTAGE | Platform fee percentage (0.005 = 0.5%) |
PAYMENT_FEE_FIXED | Fixed fee in cents (10 = $0.10) |
Optional Advanced Configuration
| Variable | Description | Default |
|---|---|---|
NEXT_PUBLIC_WEBAPP_URL | Public-facing URL | Value of NEXTAUTH_URL |
NEXT_PUBLIC_WEBSITE_URL | Marketing website URL | Value of NEXTAUTH_URL |
NEXT_PUBLIC_APP_URL | App URL for redirects | Value of NEXTAUTH_URL |
CRON_API_KEY | Secret key for cron endpoints | Random string |
DAILY_API_KEY | Daily.co API key for video | - |
ZOOM_CLIENT_ID | Zoom OAuth client ID | - |
ZOOM_CLIENT_SECRET | Zoom OAuth client secret | - |
Setting Up Calendar Integrations
Cal.com’s power comes from its deep calendar integrations. Here’s how to configure the most popular providers:
Google Calendar Integration
-
Create Google Cloud Project
- Go to Google Cloud Console
- Create a new project or select an existing one
- Enable the Google Calendar API
-
Configure OAuth Consent Screen
- Navigate to “APIs & Services” → “OAuth consent screen”
- Choose “External” user type
- Fill in application name, user support email, and developer contact
- Add scopes:
https://www.googleapis.com/auth/calendar - Save and continue
-
Create OAuth 2.0 Credentials
- Go to “APIs & Services” → “Credentials”
- Click “Create Credentials” → “OAuth client ID”
- Application type: “Web application”
- Add authorized redirect URI:
https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback - Save and copy the client ID and client secret
-
Configure Cal.com Environment Variable
Create the JSON credentials structure:
Terminal window GOOGLE_API_CREDENTIALS={"web":{"client_id":"123456789.apps.googleusercontent.com","client_secret":"your-client-secret","redirect_uris":["https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback"]}} -
Test Integration
- Log into your Cal.com instance
- Go to Settings → Integrations
- Connect Google Calendar
- Authorize the application
- Verify calendar events sync correctly
Microsoft Outlook/Office 365 Integration
-
Register Application in Azure
- Go to Azure Portal
- Navigate to “Azure Active Directory” → “App registrations”
- Click “New registration”
- Name: “Cal.com Scheduling”
- Redirect URI:
https://your-app-name.klutch.sh/api/integrations/office365calendar/callback
-
Configure API Permissions
- In your app registration, go to “API permissions”
- Add permissions for Microsoft Graph:
Calendars.ReadWriteCalendars.ReadWrite.SharedUser.Read
- Grant admin consent
-
Create Client Secret
- Go to “Certificates & secrets”
- Create a new client secret
- Copy the secret value immediately (it won’t be shown again)
-
Configure Environment Variables
Terminal window MS_GRAPH_CLIENT_ID=your-application-client-idMS_GRAPH_CLIENT_SECRET=your-client-secret-value -
Test Integration
- In Cal.com Settings → Integrations
- Connect Office 365 Calendar
- Sign in with Microsoft account
- Grant permissions and verify sync
Custom Domain Configuration
To use your own domain (e.g., cal.yourdomain.com) with Cal.com on Klutch.sh:
-
Add Domain in Dashboard
- Navigate to your Cal.com app in the Klutch.sh dashboard
- Go to “Domains” section
- Click “Add Custom Domain”
- Enter your domain (e.g.,
cal.yourdomain.com)
-
Configure DNS Records
Add a CNAME record in your DNS provider:
Type: CNAMEName: calValue: your-app-name.klutch.shTTL: 3600 -
Update Environment Variables
Update the URL variables to use your custom domain:
Terminal window NEXTAUTH_URL=https://cal.yourdomain.comNEXT_PUBLIC_WEBAPP_URL=https://cal.yourdomain.comNEXT_PUBLIC_WEBSITE_URL=https://cal.yourdomain.com -
Redeploy Application
- Trigger a new deployment in the Klutch.sh dashboard to apply the environment variable changes
-
Enable SSL/TLS
- Klutch.sh automatically provisions and manages SSL certificates using Let’s Encrypt
- SSL activation typically takes 5-15 minutes after DNS propagation
-
Verify Configuration
- Wait for DNS propagation (usually 5-15 minutes)
- Visit
https://cal.yourdomain.com - Verify SSL certificate is active and trusted
- Test booking flow to ensure all redirects work correctly
For detailed domain configuration, see the Klutch.sh Custom Domains guide.
Getting Started with Cal.com
After deploying your Cal.com instance, follow these steps to set up your first event type and start accepting bookings:
Initial Setup
-
Create Your Account
- Navigate to
https://your-app-name.klutch.sh(or your custom domain) - Click “Sign up” or “Get Started”
- Enter your email address and choose a strong password
- Verify your email (if email is configured)
- Complete your profile with name and username
- Navigate to
-
Configure Your Profile
- Go to Settings → Profile
- Upload a profile photo
- Set your display name and bio
- Choose your username (this becomes your booking page URL:
/username) - Set your timezone
-
Connect Your Calendar
- Go to Settings → Integrations
- Connect your primary calendar (Google Calendar, Outlook, etc.)
- Follow the OAuth flow to authorize access
- Select which calendar should receive new bookings
- Configure conflict checking to prevent double-bookings
Creating Your First Event Type
-
Navigate to Event Types
- From the dashboard, click “Event Types”
- Click “New Event Type” button
-
Configure Basic Details
- Title: “30 Minute Meeting” (or your preferred name)
- URL:
/30min(becomesexample-app.klutch.sh/username/30min) - Description: Describe what this meeting is for
- Duration: 30 minutes
- Location: Choose from:
- Zoom (if integrated)
- Google Meet (if using Google Calendar)
- Microsoft Teams
- Phone call
- In-person address
-
Set Your Availability
- Click “Availability” tab
- Set your working hours:
- Monday-Friday: 9:00 AM - 5:00 PM
- Set timezone for display
- Add buffer time before/after meetings
- Set minimum notice period (e.g., 4 hours)
- Configure date range limits
-
Customize Booking Questions
- Add custom questions:
- Name (required by default)
- Email (required by default)
- Phone number (optional)
- Company name
- Meeting purpose
- Custom questions specific to your needs
- Add custom questions:
-
Configure Advanced Settings
- Confirmation: Require manual confirmation or auto-confirm
- Reminders: Set email reminders (24h, 1h before)
- Redirect: After booking confirmation page
- Payment: Require payment via Stripe (optional)
- Limits: Max bookings per day
-
Save and Test
- Click “Save” to create the event type
- Visit your booking page:
your-app-name.klutch.sh/your-username/30min - Test the booking flow by creating a test booking
Sample Event Type Configurations
1. Quick 15-Minute Call
Title: Quick ChatDuration: 15 minutesBuffer: 5 minutes before and afterMinimum Notice: 2 hoursLocation: Phone callAuto-confirm: Yes2. Discovery Call
Title: Discovery CallDuration: 60 minutesBuffer: 10 minutes beforeMinimum Notice: 24 hoursLocation: ZoomAuto-confirm: No (manual confirmation)Questions: Company name, Project description3. Paid Consultation
Title: Expert ConsultationDuration: 45 minutesPrice: $150Payment: Stripe (required)Location: Google MeetMinimum Notice: 48 hoursTeam Features and Collaborative Scheduling
Cal.com supports team scheduling for organizations:
Setting Up a Team
-
Create a Team
- Go to Settings → Teams
- Click “Create Team”
- Enter team name and slug
- Invite team members via email
-
Configure Team Event Types
- Create event types at the team level
- Options:
- Round Robin: Distribute bookings evenly
- Collective: All members must be available
- Managed Event: Assigned to specific members
-
Team Availability
- Set team working hours
- Individual members can override with their schedules
- System automatically finds available slots across all members
-
Team Booking Page
- Access at:
your-app.klutch.sh/team/team-name - Shows all team event types
- Displays team members and bios
- Access at:
Production Best Practices
Security Hardening
-
Use Strong Secrets
Generate cryptographically secure secrets:
Terminal window # Linux/macOSNEXTAUTH_SECRET=$(openssl rand -base64 32)CALENDSO_ENCRYPTION_KEY=$(openssl rand -hex 16)CRON_API_KEY=$(openssl rand -base64 32) -
Enable Rate Limiting
Protect against abuse by configuring rate limits in your environment:
Terminal window RATE_LIMIT_ENABLED=trueRATE_LIMIT_MAX_REQUESTS=100RATE_LIMIT_WINDOW_MS=60000 -
Implement IP Allowlisting
For admin sections, consider using Klutch.sh network policies or reverse proxy rules.
-
Configure Content Security Policy
Set appropriate CSP headers to prevent XSS attacks.
-
Regular Security Updates
Update your Dockerfile to use specific Cal.com versions:
FROM calcom/cal.com:v3.5.0Then regularly update to newer stable versions and redeploy.
-
Database Connection Security
Always use SSL for database connections:
Terminal window DATABASE_URL=postgresql://user:pass@host:5432/calcom?sslmode=require -
Monitor Authentication Logs
Regularly review authentication attempts and failed login logs.
Performance Optimization
-
Enable Next.js Output Caching
Ensure your Dockerfile properly handles Next.js cache:
# Leverage build cacheENV NEXT_TELEMETRY_DISABLED 1 -
Configure Database Connection Pool
Optimize database connections:
Terminal window DATABASE_URL=postgresql://user:pass@host:5432/calcom?connection_limit=20&pool_timeout=20 -
Use CDN for Static Assets
Configure Cal.com to serve static assets from a CDN:
Terminal window NEXT_PUBLIC_STATIC_CDN_URL=https://cdn.yourdomain.com -
Monitor Performance
- Set up monitoring in the Klutch.sh dashboard
- Watch CPU, memory, and database connection usage
- Monitor booking page load times
- Track API response times
-
Optimize Images
Cal.com automatically optimizes images, but ensure:
- User avatars are reasonably sized
- Brand assets are compressed
- Use WebP format when possible
-
Enable Query Caching
Cal.com uses tRPC with built-in caching. Monitor cache hit rates.
Monitoring and Logging
-
Application Logs
View logs in the Klutch.sh dashboard under your app’s “Logs” section.
-
Set Up Alerts
Configure alerts for:
- Application downtime
- High error rates (500 errors)
- Database connection failures
- Failed payment processing
- Email delivery failures
-
Booking Analytics
Cal.com includes built-in analytics:
- Go to Insights → Analytics
- Track:
- Total bookings
- Booking conversion rate
- Popular time slots
- Event type performance
- Revenue (if using payments)
-
Database Monitoring
Monitor PostgreSQL:
- Active connections
- Slow queries
- Database size growth
- Index usage
-
Uptime Monitoring
Use external uptime monitoring:
- UptimeRobot
- Pingdom
- Monitor:
https://your-app.klutch.sh/api/health
Troubleshooting Common Issues
Application Won’t Start
Symptoms: Container starts but Cal.com UI is not accessible, or crashes shortly after startup
Solutions:
-
Check logs in the Klutch.sh dashboard for error messages
-
Verify
DATABASE_URLis correctly formatted:Terminal window # Should be:postgresql://username:password@host:port/database# NOT:postgres://... (use 'postgresql://') -
Ensure database is accessible:
Terminal window # For TCP on Klutch.sh, use port 8000:postgresql://user:pass@db-app.klutch.sh:8000/calcom -
Verify all required environment variables are set:
- DATABASE_URL
- NEXTAUTH_URL
- NEXTAUTH_SECRET
- CALENDSO_ENCRYPTION_KEY
-
Check that NEXTAUTH_URL matches your actual domain (no trailing slash)
-
Ensure database migrations completed successfully in the logs
Database Migration Errors
Symptoms: “Migration failed” or “P1001: Can’t reach database server” in logs
Solutions:
-
Verify database connection by testing connection string:
Terminal window psql "postgresql://user:pass@host:port/database" -
Check PostgreSQL version compatibility (Cal.com requires PostgreSQL 12+)
-
Ensure database user has sufficient privileges:
GRANT ALL PRIVILEGES ON DATABASE calcom TO calcom_user;GRANT ALL ON SCHEMA public TO calcom_user; -
For TCP deployments on Klutch.sh, ensure you’re using port 8000
-
Manually run migrations if needed:
Terminal window npx prisma migrate deploy
Calendar Integration Not Working
Symptoms: Can’t connect Google Calendar, bookings not syncing
Solutions:
-
Verify OAuth credentials are correctly formatted in
GOOGLE_API_CREDENTIALS -
Check redirect URI matches exactly:
https://your-app-name.klutch.sh/api/integrations/googlecalendar/callback -
Ensure Google Calendar API is enabled in Google Cloud Console
-
Verify OAuth consent screen is published (not in testing mode)
-
Check that calendar scopes are approved:
https://www.googleapis.com/auth/calendarhttps://www.googleapis.com/auth/calendar.events
-
Try disconnecting and reconnecting the integration
Email Notifications Not Sending
Symptoms: Booking confirmations and reminders not being sent
Solutions:
-
Verify all email environment variables are set:
- EMAIL_FROM
- EMAIL_SERVER_HOST
- EMAIL_SERVER_PORT
- EMAIL_SERVER_USER
- EMAIL_SERVER_PASSWORD
-
Test SMTP credentials manually:
Terminal window telnet smtp.sendgrid.net 587 -
Check that EMAIL_FROM is a verified sender in your SMTP provider
-
Review email logs in your SMTP provider dashboard
-
Ensure firewall allows outbound connections on SMTP ports (587, 465, or 25)
-
Try a different SMTP provider to isolate the issue
Performance Issues
Symptoms: Slow page loads, booking page timeouts
Solutions:
-
Check resource usage in Klutch.sh dashboard:
- CPU usage
- Memory usage
- Database connections
-
Upgrade to a larger instance size if resources are constrained
-
Optimize database performance:
-- Check slow queriesSELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 10;-- Add missing indexesCREATE INDEX idx_bookings_start_time ON "Booking"("startTime"); -
Enable connection pooling in DATABASE_URL:
Terminal window ?connection_limit=20&pool_timeout=20 -
Monitor database connection count:
SELECT count(*) FROM pg_stat_activity; -
Clear Next.js cache and redeploy:
Terminal window rm -rf .next/cache
Booking Conflicts
Symptoms: Double bookings, availability showing incorrectly
Solutions:
-
Verify calendar integration is active and connected
-
Check calendar sync status in Settings → Integrations
-
Ensure event type has “Check for conflicts” enabled
-
Verify timezone settings match your actual timezone
-
Manually sync calendars:
- Disconnect calendar integration
- Reconnect and reauthorize
- Wait 5 minutes for initial sync
-
Check that working hours are set correctly in availability settings
Scaling Your Cal.com Deployment
As your booking volume grows, consider these scaling strategies:
Vertical Scaling
Increase resources for your Cal.com instance:
- Upgrade to a larger instance type in the Klutch.sh dashboard
- Recommended specs based on usage:
- Small (< 100 bookings/day): 1 CPU, 2GB RAM
- Medium (100-500 bookings/day): 2 CPU, 4GB RAM
- Large (500-2000 bookings/day): 4 CPU, 8GB RAM
- Enterprise (2000+ bookings/day): 8+ CPU, 16+ GB RAM
Database Scaling
- Use managed PostgreSQL with read replicas for high traffic
- Enable connection pooling with PgBouncer
- Separate read and write operations
- Implement database query caching
High Availability Setup
For mission-critical deployments:
- Deploy multiple Cal.com instances behind a load balancer
- Use managed PostgreSQL with automatic failover
- Implement Redis for session storage
- Set up monitoring and automatic restarts
Migration from Other Platforms
If you’re migrating from Calendly, Cal.com Cloud, or self-hosted Cal.com:
-
Export Your Data
If migrating from Cal.com Cloud:
- Contact Cal.com support for data export
- Receive database dump file
If self-hosted:
-
Create PostgreSQL backup:
Terminal window pg_dump -h localhost -U calcom -d calcom > calcom_backup.sql
-
Prepare New Database
Create a fresh PostgreSQL database on Klutch.sh or managed service.
-
Deploy Cal.com on Klutch.sh
Follow the deployment steps in this guide to create a new instance.
-
Import Data
Restore your database backup:
Terminal window psql -h your-new-host -p 8000 -U calcom_user -d calcom < calcom_backup.sql -
Update Integrations
Reconnect all calendar integrations:
- Google Calendar
- Microsoft Outlook
- Payment providers
- Video conferencing tools
-
Update Environment Variables
Ensure all API keys and secrets are transferred to new deployment.
-
Test Thoroughly
- Verify all event types work correctly
- Test booking flow end-to-end
- Confirm email notifications send
- Check calendar sync
- Test payments (if applicable)
-
Update DNS
Point your domain to the new Klutch.sh deployment.
-
Monitor
Watch logs and metrics for the first 24-48 hours to catch any issues.
Advanced Customization
Custom Branding
Customize Cal.com’s appearance to match your brand:
-
Upload Brand Assets
- Go to Settings → Appearance
- Upload your logo
- Upload favicon
- Set brand color (primary color for buttons and accents)
-
Custom CSS
For advanced customization, inject custom CSS:
/* Example custom styles */:root {--brand-color: #6366f1;--brand-text-color: #ffffff;} -
White Label Configuration
Remove Cal.com branding (requires pro/enterprise plan):
Terminal window NEXT_PUBLIC_HIDE_BRANDING=true
Webhook Integrations
Connect Cal.com to external systems via webhooks:
-
Configure Webhooks
- Go to Settings → Integrations → Webhooks
- Add new webhook subscriber
- Enter endpoint URL:
https://your-api.com/webhooks/calcom - Select events to subscribe to:
- BOOKING_CREATED
- BOOKING_CANCELLED
- BOOKING_RESCHEDULED
- BOOKING_CONFIRMED
-
Implement Webhook Handler
Example Node.js webhook receiver:
app.post('/webhooks/calcom', express.json(), (req, res) => {const { triggerEvent, payload } = req.body;switch(triggerEvent) {case 'BOOKING_CREATED':console.log('New booking:', payload.id);// Send to CRM, notify team, etc.break;case 'BOOKING_CANCELLED':console.log('Booking cancelled:', payload.id);// Update CRM, send internal notificationbreak;}res.status(200).send('OK');}); -
Secure Webhooks
Verify webhook signatures to prevent spoofing.
Cost Optimization Tips
- Right-size your instance: Start with smaller resources and scale up based on actual usage
- Optimize database queries: Ensure proper indexing to reduce compute time
- Use managed PostgreSQL free tiers: Services like Supabase offer generous free tiers for development
- Monitor resource usage: Use Klutch.sh monitoring to identify optimization opportunities
- Implement caching: Reduce database queries with proper caching strategies
- Clean up old data: Archive or delete old bookings and cancelled events periodically
Example Deployment Repository
For a complete working example, reference this sample repository structure:
calcom-on-klutch/├── Dockerfile├── .dockerignore├── .gitignore├── .env.example└── README.mdDockerfile:
FROM calcom/cal.com:v3.5.0
WORKDIR /calcom
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s --start-period=90s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:3000/api/health || exit 1
CMD ["sh", "-c", "npx prisma migrate deploy && npm run start"].env.example:
# Database (Required)DATABASE_URL=postgresql://username:password@host:5432/calcom?schema=public
# Application URLs (Required)NEXTAUTH_URL=https://your-app-name.klutch.shNEXT_PUBLIC_WEBAPP_URL=https://your-app-name.klutch.sh
# Security (Required - Generate with: openssl rand -base64 32)NEXTAUTH_SECRET=your-nextauth-secret-min-32-charsCALENDSO_ENCRYPTION_KEY=your-encryption-key-32-charsCRON_API_KEY=your-cron-api-key
# Email Configuration (Required for notifications)EMAIL_FROM=noreply@yourdomain.comEMAIL_SERVER_HOST=smtp.sendgrid.netEMAIL_SERVER_PORT=587EMAIL_SERVER_USER=apikeyEMAIL_SERVER_PASSWORD=your-sendgrid-api-key
# Google Calendar (Optional)# GOOGLE_API_CREDENTIALS={"web":{"client_id":"...","client_secret":"...","redirect_uris":["..."]}}
# Microsoft Outlook (Optional)# MS_GRAPH_CLIENT_ID=your-ms-client-id# MS_GRAPH_CLIENT_SECRET=your-ms-client-secret
# Stripe Payments (Optional)# STRIPE_PRIVATE_KEY=sk_live_...# STRIPE_PUBLIC_KEY=pk_live_...# STRIPE_WEBHOOK_SECRET=whsec_...README.md:
# Cal.com on Klutch.sh
Production-ready Cal.com deployment for scheduling and appointment booking.
## Quick Start
1. Clone this repository2. Copy `.env.example` to `.env` and configure all variables3. Set up a PostgreSQL database4. Push to GitHub5. Deploy on Klutch.sh following the official guide
## Required Setup
- PostgreSQL 12+ database- SMTP credentials for email- OAuth credentials for calendar integrations (optional)
## Support
See the full deployment guide at <a href="https://docs.klutch.sh/guides/open-source-software/cal?utm_source=docs" target="_blank">docs.klutch.sh</a>Additional Resources
- Official Cal.com Documentation
- Cal.com GitHub Repository
- Cal.com Community Slack
- Cal.com Feature Requests
- Klutch.sh Quick Start Guide
- Klutch.sh Persistent Volumes
- Klutch.sh Deployments
- Klutch.sh Networking
- PostgreSQL on Klutch.sh
Conclusion
Deploying Cal.com on Klutch.sh provides a powerful, scalable scheduling platform without the complexity of managing infrastructure. With automatic Dockerfile detection, PostgreSQL integration, persistent storage, secure environment management, calendar provider integrations, and production-ready configurations, you can focus on building your scheduling business and serving your customers.
Whether you’re creating a personal booking page, team scheduling system, or white-label scheduling solution for clients, Cal.com on Klutch.sh offers the reliability, performance, and flexibility you need. Start accepting bookings today and streamline your appointment management with open-source scheduling software that respects your privacy and gives you complete control.
For additional help or questions, reach out to the Cal.com community or Klutch.sh support.