
Cal.com is an open-source scheduling platform for creating and sharing booking links for meetings, appointments, and events. It serves as a self-hosted alternative to Calendly, giving full control over user data and customization. Cal.com supports individual scheduling, team workflows, and organization-level management.
This article explains how to deploy Cal.com using Docker Compose with PostgreSQL for persistent data storage and Traefik as a reverse proxy. It covers Hypertext Transfer Protocol Secure (HTTPS) configuration with automatic certificate provisioning through Let's Encrypt using a custom domain.
Before you begin, you need to:
cal.example.com).Cal.com runs as a web application container connected to a PostgreSQL database for persistent storage. Traefik operates as the reverse proxy, handling Transport Layer Security (TLS) termination and automatic certificate provisioning through Let's Encrypt.
Create a project directory for Cal.com.
Navigate into the directory.
Navigate into the directory. It stores the Docker Compose configuration, environment variables, and application data.
Generate a random secret for authentication.
Generate a second random secret for data encryption.
Use the first output for NEXTAUTH_SECRET and the second for CALENDSO_ENCRYPTION_KEY when creating the .env file in the next step.
Create a .env file to store environment variables.
Add the following configuration:
Replace:
cal.example.com with your registered domain name (in both DOMAIN and the URL variables)admin@example.com with your email address for Let's Encrypt certificate notificationsREPLACE_WITH_GENERATED_SECRET with the first generated secretREPLACE_WITH_GENERATED_ENCRYPTION_KEY with the second generated secretNEXT_PUBLIC_WEBAPP_URL is a build-time variable. It is baked into the Next.js build when the container starts for the first time. If you change it later, recreate the container with docker compose up -d --force-recreate rather than restarting it, otherwise the change has no effect.
Save and close the file.
(Optional) Configure SMTP variables for outgoing email. Cal.com starts and runs without email configured, but booking confirmations, password resets, and team invitations are disabled. Refer to the .env.example file in the Cal.com repository and add the required SMTP variables to the .env file before starting the containers.
Docker Compose coordinates the application, database, and reverse proxy layers. Traefik discovers the Cal.com container via Docker labels, applies domain-based routing rules, and manages TLS termination using certificates provisioned automatically through Let's Encrypt.
Add your user to the Docker group so that Docker commands run without sudo.
Apply the new group membership to the current shell session.
Create the Docker Compose file.
Add the following manifest:
Save and close the file.
In the above manifest:
services: Defines three containers managed by Docker Compose.traefik: Functions as the reverse proxy and TLS termination point, handling incoming HTTP and HTTPS traffic and forwarding requests to the Cal.com container.postgres: Provides the PostgreSQL database for storing user accounts, scheduling configurations, and application metadata.calcom: Hosts the Cal.com web application and connects to the PostgreSQL service.image: Specifies the container image for each service.container_name: Assigns predictable names to containers, simplifying log inspection and service management.command (Traefik): Configures Traefik with Docker provider integration, HTTP and HTTPS entry points, automatic HTTP-to-HTTPS redirection, and Let's Encrypt certificate acquisition.ports (Traefik): Maps host ports 80 and 443 to Traefik to receive incoming web traffic.env_file (Cal.com): Loads environment variables from the .env file, including authentication secrets, encryption keys, application URLs, and database connection strings.expose (Cal.com): Exposes port 3000 to other containers on the shared Docker network without publishing it to the host, allowing Traefik to reach Cal.com internally.labels (Cal.com): Instructs Traefik to route HTTPS requests matching the configured domain to the Cal.com container on port 3000.volumes:./postgres-data bind mount stores PostgreSQL data on the host between container restarts../calcom-data bind mount stores application-level configuration and state for Cal.com on the host./var/run/docker.sock) enables Traefik to detect and configure routes for running containers automatically../letsencrypt bind mount stores TLS certificates across container restarts.restart: unless-stopped: Configures all containers to restart automatically after crashes or server reboots, unless explicitly stopped.Start the containers in detached mode.
Verify that all containers are running.
The output displays three running containers with Traefik listening on ports 80 and 443.
View the Cal.com logs to confirm the application started successfully.
The output shows Next.js startup messages including a line starting with Ready in followed by a startup duration, confirming the application is serving traffic on port 3000.
For more information on managing Docker Compose stacks, see the How to Use Docker Compose article.
Open your web browser and navigate to https://cal.example.com/auth/setup, replacing cal.example.com with your configured domain name.
Complete the administrator setup wizard. Enter a username, full name, email address, and password, then click Next.
Choose a license. Select AGPLv3 license for the free open-source license, or enter a commercial license key if you have one. Click Skip step to proceed with the AGPLv3 license.
Enable apps. Toggle the integrations you want to make available to users, organized by category such as Calendar, Conferencing, and Payment. Click Finish.
Cal.com redirects you to the user onboarding wizard.
Set up your profile. Confirm your username and full name, and select your timezone. Click Connect your calendar.
Connect a calendar. Select a calendar provider such as Apple Calendar or CalDav and follow the prompts to connect it. Click I'll connect my calendar later to skip.
Connect a video app. Select a video conferencing app such as Campfire or Discord and follow the prompts. Click Set up later to skip.
Set your availability. Adjust your available hours for each day of the week. The default is Monday through Friday, 9:00 a.m. to 5:00 p.m. Click Complete your profile.
Complete your profile. Upload a profile photo and add a short bio. Click Finish setup and get started to access the dashboard.
A Cal.com deployment is fully functional when it accepts bookings, persists them to PostgreSQL, and surfaces them in the dashboard. Create a test booking to confirm that the scheduler, database, and UI are operating correctly.
From the sidebar, navigate to Event Types and click + New.
In the Add a new event type modal, enter a title, an optional description, and a duration in minutes. The URL slug is filled in automatically from the title. Click Continue.
Review the event type settings in the editor and click Save.
Copy the booking URL by clicking the link icon in the top-right toolbar of the event type editor.
Open the booking URL in an incognito window or a different browser to simulate a visitor.
Select an available date, choose a time slot, enter a name and email address, and confirm the booking.
Return to the Cal.com dashboard and refresh it. Verify that the booking appears under Bookings.
You have successfully deployed Cal.com on your Linux server using Docker Compose with PostgreSQL for persistent data storage and Traefik providing automatic HTTPS through Let's Encrypt. Traefik handles all inbound traffic on ports 80 and 443 and forwards requests to the Cal.com container over the shared Docker network. For more information, refer to the official Cal.com documentation.
0 Comments
Be the first to comment and share your perspective with the community.