Self-Host Cal.com With Coherence
This guide demonstrates how to use Coherence and Google Cloud Platform (GCP) to host an instance of Cal.com, a scheduling application that helps users plan and track meetings with integrations for various calendars and communication tools.
What you'll learn
This guide will show you how to:
- Set up a Coherence environment and services
- Connect Coherence to GCP
- Provision new infrastructure
- Configure environment variables
- Integrate Google Calendar
- Permit Cal.com to send emails on your behalf
- Build and push a Cal.com Docker image
- Deploy the self-hosted Cal.com instance
By the end of this guide, you will have a self-hosted version of Cal.com running:
Coherence will create and manage the required infrastructure in your cloud environment to streamline building and deploying your app while simplifying resource management.
Prerequisites
To follow along, you'll need:
- A Coherence account
- A Google Cloud Platform (GCP) account and project
- Docker and Docker Compose
- Docker Hub or another artifact registry
1. Set up a Coherence environment and services
Start by setting up a Coherence and services for your application.
Create a new application
- On the Coherence dashboard, click New application.
- Name the application a name.
- Select your cloud provider and architecture.
- Click Create application.
Create a collection
- On the application's landing page, click Create collection.
- Name the collection.
- Click Create collection.
Configure an environment
- On the collection dashboard, click New environment.
- Name the environment.
- Select the appropriate environment type (Staging is recommended for initial testing) from the dropdown.
- Click Create.
For more information on creating applications, collections, and environments, refer to our quick start guide.
Add a Cal.com service to the environment
-
Navigate to the environment homepage and select the Services tab.
-
Click the New service button. In the Containers section, select Other. Complete the popup form as follows:
- Name:
Calcom
(Any meaningful name will work) - Start command: Clear any entries and leave the field blank
- URL Path:
/
- Health Check Path: Clear and leave blank
- Container source: Select the
Existing Image
option - Image:
<registry>/calcom
– the Cal.com registry and image that you will push your image to - Tag source:
Static
- Tag:
latest
to pull the newest version of the image - CPU: Leave unchanged at
1
- Memory: Leave unchanged at
2G
- Name:
-
Click the Create service button.
Note: Depending on your needs, you may need to increase the CPU and Memory resource limits. If you change these values after the infrastructure has been provisioned and the application has been deployed, you'll need to provision the infrastructure again and redeploy the application.
Create a service for the database
- Click New service.
- In the Database section, select Postgres.
- Give the database a name, like
db
, and click Create service.
2. Connect Coherence to GCP
-
In the Ready to deploy? banner at the top of the page, click Connect.
-
Follow the prompts to connect to your GCP instance and add the relevant user role.
- When you are prompted to import variables, you can click Skip this.
3. Provision new infrastructure
-
In the Provision task needed notice at the top of the page, click Go.
-
Click Submit new task to queue a task to create the required infrastructure. Provisioning may take a few minutes to complete.
4. Configure environment variables
- After the infrastructure has been provisioned, navigate to the Variables tab of your Coherence environment hompepage.
-
Create two secrets by clicking New variable, selecting Secret from the dropdown, filling in the form as follows, and clicking Create.
- Enter
CALENDSO_ENCRYPTION_KEY
as the Name andopenssl rand -base64 24
as the Value. - Enter
NEXTAUTH_SECRET
as the Name andopenssl rand -base64 32
as the Value.
- Enter
-
Add aliases for existing environment variables by expanding the System section, selecting the three-dot menu for each variable, and clicking Create Alias. Use the following aliases for these database variables:
- DB_HOST:
DATABASE_HOST
- DB_NAME:
POSTGRES_DB
- DB_USER:
POSTGRES_USER
- < name >_DB_PASSWORD:
POSTGRES_PASSWORD
- DB_HOST:
At this point, you can decide whether to enable integrations with Google Calendar and set up emails from Cal.com.
5. Integrate Google Calendar
To enable integration with Google Calendar, add a new environment variable for GOOGLE_API_CREDENTIALS
in Coherence, and follow these steps to get the Value for the key:
- Open the GCP API Console.
- Click the + Enable APIs and Services button.
- Type
calendar
in the search box, select the Google Calendar API result to view the Product Details page, and click Enable. - Use the APIs and Services side panel to navigate to the OAuth consent screen.
- Select your application User Type, fill out the form on the first page to register your app, and click Save and Continue.
- On the Scopes page, select Add or Remove Scopes.
- Search for
Calendar.event
, select the scopes with the scope values.../auth/calendar.events
and.../auth/calendar.readonly
, then click Update. - Select Credentials from the APIs and Services side panel and click + Create Credentials.
- Select OAuth client ID from the dropdown.
- Select Web Application as the Application Type.
- Under Authorized redirect URIs, select + Add URI, and add the URIs,
<URL>/api/integrations/googlecalendar/callback
and<URL>/api/auth/callback/google
, replacingURL
with theURI
where the application will be hosted. - The key will be created and you will be redirected to the Credentials page.
- Select the newly generated client ID under OAuth 2.0 Client IDs.
- Select Download JSON.
- Under OAuth consent screen, click Publish App.
When you've completed these steps, copy the entire contents of the downloaded JSON file and paste it in the Value field for the GOOGLE_API_CREDENTIALS
key you created.
6. Permit Cal.com to send emails on your behalf
Add the following environment variables with the appropriate settings:
EMAIL_FROM=notifications@example.com
EMAIL_SERVER_HOST=smtp.example.com
EMAIL_SERVER_PORT=587
EMAIL_SERVER_USER=email_user
EMAIL_SERVER_PASSWORD=email_password
Note: The EMAIL_FROM
address must have the necessary permissions enabled for sending emails via your SMTP server.
7. Build and push a Cal.com Docker image
Clone the repository
-
Clone the Cal.com docker repository:
git clone --recursive https://github.com/calcom/docker.git calcom-docker
-
Navigate into the cloned directory:
cd calcom-docker
-
Update the Cal.com repository submodule:
git submodule update --remote --init
Build image
Ensure you have an artifact registry ready to push your image to. If you are new to Docker containers, we recommend using Docker Hub as a starting point. Consult the Docker reference documentation to learn more about using docker compose push
to push images to Docker Hub.
Platform-specific configuration
If you use macOS with Apple Silicon or another ARM-based system that may encounter compatibility issues with the x86-based Docker image, add a platform
tag to all services in your docker-compose.yml
file to ensure the correct image architecture is used for the build:
services:
database:
container_name: database
image: postgres
platform: linux/amd64 # Add this line
# ... other configurations ...
calcom:
image: <registry>/calcom:latest
platform: linux/amd64 # Add this line
# ... other configurations ...
studio:
image: calcom.docker.scarf.sh/calcom/cal.com
platform: linux/amd64 # Add this line
# ... other configurations ...
Set up the environment
The Cal.com Docker repository uses docker compose
to build and publish Docker images. One of these images is Prisma Studio, which is responsible for applying database migrations and other database management operations.
-
In the root folder of the
calcom-docker
repository, rename the.env.example
file to.env
:mv .env.example .env
-
Open the
.env
file with any text editor and find the following two variables:NEXT_PUBLIC_WEBAPP_URL=http://localhost:3000 NEXT_PUBLIC_API_V2_URL=http://localhost:5555/api/v2
-
Replace the
localhost
URL with the domain found in your Coherence environment.The values should look similar to this once you are done:
NEXT_PUBLIC_WEBAPP_URL=https://<env>.<hash>.<org>.cncsites.com NEXT_PUBLIC_API_V2_URL=https://<env>.<hash>.<org>.cncsites.com/api/v2
-
Now find the following variables in the
.env
file:POSTGRES_USER=unicorn_user POSTGRES_PASSWORD=magical_password POSTGRES_DB=calendso DATABASE_HOST=database:5432
POSTGRES_USER
,POSTGRES_PASSWORD
, andPOSTGRES_DB
can all be found under theDB_USER
,<name>_DB_PASSWORD
, andDB_NAME
variables respectively in your Coherence environment.Because the database connection occurs via a local machine when you run the container, you will need to set up remote database connections and find the public IP address for the
DATABASE_HOST
key.
Enable remote connections to the Postgres database
-
In the GCP project connected to Coherence, navigate to the SQL menu option, select the database, open Connections from the menu, and select the Networking tab.
-
Under the Authorized networks section, click the Add a network button.
-
Name the network
remote connection
and enter0.0.0.0/0
in the Network field.
Add the database public IP
-
In the Overview of your SQL database, find the Connect to this instance section and note the Public IP address.
-
Add the public IP for the database to the
DATABASE_HOST
key. If you are unsure which port to use, find theDB_PORT
in your Coherence environment variables. -
Run the image:
docker compose up
You will notice migrations being run in the log, wait for these to complete before moving on.
NOTE: Once all the migrations have been completed, you can remove the authorized network you added to GCP SQL to help prevent unwanted access to your database.
-
Close the session with
ctrl + c
when done.
Edit docker-compose.yaml
-
Open the
docker-compose.yaml
and make the following changes:- Under
services
->calcom
, replace the value for theimage
key with the registry you want to push to. - Change the
ports
to8080:3000
Your
docker-compose.yaml
should now look something like this:# Use postgres/example user/password credentials version: '3.8' volumes: database-data: networks: stack: name: stack external: false services: database: container_name: database image: postgres restart: always volumes: - database-data:/var/lib/postgresql/data/ env_file: .env networks: - stack calcom: image: <registry>/calcom:latest build: context: . dockerfile: Dockerfile args: NEXT_PUBLIC_WEBAPP_URL: ${NEXT_PUBLIC_WEBAPP_URL} NEXT_PUBLIC_API_V2_URL: ${NEXT_PUBLIC_API_V2_URL} NEXT_PUBLIC_LICENSE_CONSENT: ${NEXT_PUBLIC_LICENSE_CONSENT} CALCOM_TELEMETRY_DISABLED: ${CALCOM_TELEMETRY_DISABLED} NEXTAUTH_SECRET: ${NEXTAUTH_SECRET} CALENDSO_ENCRYPTION_KEY: ${CALENDSO_ENCRYPTION_KEY} DATABASE_URL: ${DATABASE_URL} DATABASE_DIRECT_URL: ${DATABASE_URL} network: stack restart: always networks: - stack ports: - 8080:3000 env_file: .env environment: - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} - DATABASE_DIRECT_URL=${DATABASE_URL} depends_on: - database # Optional use of Prisma Studio. In production, comment out or remove the section below to prevent unwanted access to your database. studio: image: calcom.docker.scarf.sh/calcom/cal.com restart: always networks: - stack ports: - 5555:5555 env_file: .env environment: - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${DATABASE_HOST}/${POSTGRES_DB} - DATABASE_DIRECT_URL=${DATABASE_URL} depends_on: - database command: - npx - prisma - studio # END SECTION: Optional use of Prisma Studio.
- Under
-
Tag the image:
docker tag calcom.docker.scarf.sh/calcom/cal.com <your-registry>/<your-image-name>:<tag>
-
Push the image to a registry:
docker push <your-registry>/<your-image-name>:<tag>
7. Deploy the self-hosted Cal.com instance
-
To deploy the Cal.com application, navigate to the Deployments tab of your environment homepage, then click New Deployment and Submit deployment.
-
Monitor the status of the queued Build and Deploy pipelines.
When the pipelines have run, you should see a Success notification in the Latest deployments list indicating that Cal.com has been deployed.
-
Navigate to the URL under Domains to fill out the form to create an administrator account.
-
On the next page, choose the type of license you would like to use. Select AGPLv3 License if you are unsure.
-
Next, you'll see a list of apps you can connect to. Scroll down to select the Google Calendar option. Click the pen icon to ensure the credentials you added as environment variables are reflected.
-
Upon completion, you will be redirected to the Cal.com landing page. Follow the prompts to set up a Cal.com profile by creating a URL for your meetings, adding integrations, linking existing calendars, and customizing your availability schedule.
-
Click + New on the top right of the page to add a new event.
-
After creating an event, select the link button as shown:
-
Paste that link in another browser tab, then schedule a time and confirm the booking.
If you have added email integration, an email will be sent to all parties involved.
For more information on using Cal.com, refer to the Cal.com documentation.