Avatar of Faraz PatankarFaraz Patankar

Deploy Calendso (cal.com) on Railway

In this post, we go over the process of deploying Calendso (an open-source alternative to Calendly) connected to a PostgreSQL database on Railway!


Calendso is an open-source alternative to Calendly which you can either self-host or use their hosted version of for $12/user/month. This post will talk about taking the self-hosted version from Github and deploying it on Railway.

To self-host your instance of Calendso, you need a PostgreSQL database (which Railway automagically sets up for you) and Google API credentials.

Deploying with Railway

To deploy your Calendso instance to Railway, simply click the button above (source code). Before you can finish your deployment, you need to add the GOOGLE_API_CREDENTIALS environment variable which we will set up in the next step so we can proceed with the deployment!

💡
Calendso also requires you to set up a PostgreSQL database but we automagically do that for you!

NOTE: If your Calendso fails to deploy with dependency issues, you'll likely need to pin Node to 14. Example here. Related thread here

Google API credentials

To allow Calendso to read from and write to our Google calendar, we need to create API credentials and provide them to Calendso.

Enable API

To do that, head to the Google API console and create a new project. It might take a little bit for Google to set up your project but once that's done, head over to the project and click the Enable APIs and Services button.

Once you click the button, you'll be taken to the API library. In the search box, look for calendar and select the Google Calendar API result and then enable it.

Enabling the Google Calendar API

Enabling the Google Calendar API

Set scopes

Next, head to the OAuth consent screen and select your app type (Internal or External) and enter the basic required details on the first page.

On the second page, you'll have to set up scopes. Scopes will define the things that this particular API would have access to. In this case, we want auth/calendar.events, auth/calendar.readonly, auth/calendar. Select these scopes and hit Update and move on to the next page.

Scopes

Scopes

On the third page, you will add test users. I only added myself but feel free to add others who might be testing/using the app with you. Once that's done, double-check that everything is fine on the summary page and head back to the dashboard.

Create credentials

Next, head over to the Credentials section and select Create Credentials. We want the type to be OAuth Client ID. For the application type, select Web Application and set a name.

Next, add the authorized origins and redirect URIs. For now, we'll add http://localhost:3000 to our Authorized JavaScript origins and http://localhost:3000/api/integrations/googlecalendar/callback to our Authorized redirect URIs and click Create.

💡
We will come back to this part later to add our production URIs once we've deployed our application on Railway!
Authorized origin and redirect uri for development

Authorized origin and redirect uri for development

Your key will be created and you'll be redirected back to the Credentials page where you will see your newly generated OAuth 2.0 Client ID. Select the download option, save this file to your computer and open it in your editor of choice. Copy all the contents of the file and add that as the value for the GOOGLE_API_CREDENTIALS environment variable and hit the deploy button!

Setting up locally

Once your project is deployed, clone the repository that was created for you during the deployment step and link it to your Railway project using railway link.

Next, to set up the database schema, run railway run npx prisma db push.

💡
railway run injects all your environment variables for you, this way, you don't need to set anything up locally and everything just works.

Next, head over to your project dashboard by running railway open in the CLI. Navigate to the PostgreSQL option from the sidebar and click the User model to add a new row to it. Make sure you encrypt your password with BCrypt when you enter it into the password field.

Create user

Create user

In the GIF above, I demonstrate the process of creating the user. Make sure you delete the extra trailing space when you paste your password in from BCrypt.

Now that the user is created, run railway run yarn dev to start the server and visit http://localhost:3000/ to log in using the user you just created. After logging in, you should be able to add the Google Calendar integration, set your available times, and also create new events.

Adding an integration and an event

Adding an integration and an event

Moving to production

Given the fact that we set everything up to work locally, we are going to have to make a couple of minor changes before our self-hosted instance of Calendso is ready to be shared with the world.

First, let's head over to the project dashboard and update our NEXTAUTH_URL variable from http://localhost:3000 to our production domain for our app. You can find yours under the Deployments tab.

NOTE: There should be NO TRAILING SLASH IN THE NEXTAUTH_URL

Next, let's head back to our credentials page in the Google API console so we can edit the Calendso OAuth ID we created earlier and add our production origin and redirect URI.

Authorized origin and redirect uri for production

Authorized origin and redirect uri for production

Hit save and download the updated JSON. Then, just like before, copy the contents of the JSON and update the value of the GOOGLE_API_CREDENTIALS environment variable on Railway.

Once you've updated both the environment variables, just run railway up from the CLI and your self-hosted instance of Calendso should be ready to use!

Caveats

The changes we made in the previous step to make our app work in production ironically stop it from working in development. I personally am okay with that outcome as I will only be using this in production.

But, if you'd like to make changes and work on the codebase in development, you can create an additional environment on Railway and set the environment variables we had previously. That way, everything should work as expected both in development and in production.

Closing

And with that, our self-hosted instance of Calendso should be fully functional. You should be able to create events, share those links and have people booking slots on your calendar just fine. Feel free to reach out to us if you run into any issues.

If you have any suggestions for more open-source self-hosted solutions you'd like to see guides for, let us know. Or even better, submit a pull request to our starters repository on Github!