Self-Host Your Scheduling: Cal.com on Ubuntu with a Pangolin VPS Proxy (Revised)
Want to take control of your scheduling with a private, open-source alternative to Calendly? This guide will walk you through installing Cal.com on an Ubuntu Virtual Machine (VM). To make it securely accessible from anywhere, we’ll use Pangolin on a Virtual Private Server (VPS) and the Newt tunnel client to create a secure link, all managed cleanly within a single file.
This revised guide includes a crucial fix to prevent common performance issues when accessing your instance over the internet.
Let’s get started!
Part 1: Initial Setup on Your Ubuntu VM
First, we need to prepare your Ubuntu environment by installing Docker and Docker Compose.
Step 1.1: Install Docker & Docker Compose
-
Install Docker. The official script is the simplest method:
curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh -
Add your user to the Docker group. This avoids having to type
sudofor every Docker command.sudo usermod -aG docker ${USER}Crucially, you must log out and log back in for this change to take effect.
-
Install the Docker Compose Plugin. This tool lets you manage multi-service applications like Cal.com with ease.
sudo apt-get update sudo apt-get install docker-compose-plugin -y
Part 2: Configuring Cal.com and Newt
Now we’ll create the configuration files that tell Docker how to run Cal.com, its database, and the Newt tunnel client.
Step 2.1: Create Your Project Directory and Files
-
Create a dedicated folder for your Cal.com setup.
mkdir ~/calcom-setup cd ~/calcom-setup -
Inside this directory, create two files:
docker-compose.ymlfor the service definitions and.envfor your secrets and configuration variables.touch docker-compose.yml touch .env
Step 2.2: Configure the Environment Variables (.env file)
-
Open the
.envfile with a text editor.nano .env -
Copy and paste the following configuration. This file holds all your secrets and settings.
# --- Cal.com Configuration --- # !! IMPORTANT: Set your public Cal.com URL here. This must be the final address you will use. NEXT_PUBLIC_WEBAPP_URL=https://meet.myurl.co.uk # !! PREVENT PERFORMANCE ISSUES: This line is crucial. # It tells the Cal.com backend to use its local address for internal API calls, # preventing the "CLIENT_FETCH_ERROR" that causes slowness over a tunnel. NEXTAUTH_URL=http://localhost:3000/api/auth # !! IMPORTANT: Generate unique, random secrets for these keys. # Use `openssl rand -base64 32` in your terminal to generate each one. NEXTAUTH_SECRET=YOUR_UNIQUE_NEXTAUTH_SECRET CALENDSO_ENCRYPTION_KEY=YOUR_UNIQUE_ENCRYPTION_KEY # Agree to the license terms NEXT_PUBLIC_LICENSE_CONSENT=agree # Database Credentials (can leave as default) POSTGRES_USER=unicorn_user POSTGRES_PASSWORD=magical_password POSTGRES_DB=calendso DATABASE_HOST=database:5432 DATABASE_URL=postgresql://unicorn_user:magical_password@database:5432/calendso DATABASE_DIRECT_URL=postgresql://unicorn_user:magical_password@database:5432/calendso # --- Newt Tunnel Client Configuration --- # !! IMPORTANT: These values will come from your Pangolin dashboard in the next part. # Leave them blank for now. PANGOLIN_ENDPOINT=https://your-pangolin-domain.com NEWT_ID= NEWT_SECRET= -
Update the placeholder values:
https://meet.myurl.co.uk: Change this to the final, public URL you will use.YOUR_UNIQUE_NEXTAUTH_SECRET: Replace with a long, random string.YOUR_UNIQUE_ENCRYPTION_KEY: Replace with another long, random string.https://your-pangolin-domain.com: Change this to the domain of your Pangolin VPS instance.
-
Save the file and exit (
Ctrl+X, thenY, thenEnter).
Step 2.3: Define the Services (docker-compose.yml file)
-
Now, open the
docker-compose.ymlfile.nano docker-compose.yml -
Copy and paste the following service definitions. This sets up the Cal.com app, the PostgreSQL database it needs, and the Newt client.
version: '3.8' services: database: image: postgres:15 container_name: calcom-db restart: always volumes: - database-data:/var/lib/postgresql/data env_file: .env networks: - calcom-stack calcom: image: calcom/cal.com:latest container_name: calcom-app restart: always ports: # We only expose the port to the local machine, not the public internet. - "127.0.0.1:3000:3000" env_file: .env depends_on: - database networks: - calcom-stack newt: image: fosrl/newt:latest container_name: calcom-newt restart: unless-stopped env_file: .env depends_on: - calcom # This allows Newt to talk to the other containers on the same network. networks: - calcom-stack volumes: database-data: networks: calcom-stack: driver: bridge -
Save and exit the editor.
Part 3: Connecting to Pangolin
Now, let’s get the credentials from your Pangolin VPS to allow the newt container to connect.
- In your Pangolin dashboard, navigate to Sites and click Add Site.
- Give it a name (e.g.,
Ubuntu VM Calcom) and click Create Site. - Pangolin will immediately display the credentials for this site. You will see a Newt ID and a Newt Secret.
- Back on your Ubuntu VM, edit your
.envfile one last time.nano .env - Carefully copy the
Newt IDandNewt Secretfrom the Pangolin dashboard and paste them into theNEWT_IDandNEWT_SECRETvariables. - Save and close the file.
Part 4: Launching and Exposing Cal.com
With the configuration complete, it’s time to bring everything online.
Step 4.1: Launch the Services
- Make sure you are in your project directory (
~/calcom-setup). - Run the following command to download the images and start all three containers.
This may take several minutes the first time as Docker downloads the Cal.com and PostgreSQL images. Thedocker compose up -d-dflag runs it in the background.
Step 4.2: Expose the Cal.com App in Pangolin
- In your Pangolin dashboard, go to Resources and click Add Resource.
- Fill out the form:
- Name:
Cal.com App - Site: Select the site you just created (e.g.,
Ubuntu VM Calcom). - Resource Type:
HTTP Resource. - HTTP Settings > Sub-domain:
meet(or whatever matches theNEXT_PUBLIC_WEBAPP_URLyou set).
- Name:
- Click Create Resource.
- On the next page, under Target Configuration:
- Method:
http - Host: Use the container name of your Cal.com app:
calcom-app. Becausenewtis on the same Docker network, it can find the app by its name. - Port:
3000
- Method:
- Click Add Target and then Save Targets.
Part 5: Final Setup
You’re done! Open a web browser and navigate to the public URL you configured (e.g., https://meet.myurl.co.uk). Cal.com’s initial setup wizard should greet you, allowing you to create your first user account. With the added configuration, your instance should now be fast and stable.
Enjoy your new, private, self-hosted scheduling platform!