Deploying a Monorepo to Railway
What is a Monorepo?
A monorepo is a project directory structure in which multiple, co-dependent codebases (such as a frontend and a backend) are maintained within the same repository, and in some cases, share common packages.
About This Tutorial
Deploying a monorepo in Railway requires some extra configuration to get the applications up and running.
This tutorial aims to provide a simple step-by-step on how to deploy a frontend and backend from an isolated monorepo, one of the most commonly deployed types of monorepo.
The procedure outlined in this tutorial can easily be adapted to deploy different apps that are contained within a isolated monorepo as well.
For more information on deploying a shared monorepo check out our guide that explains some of the specific configurations you would need.
Objectives
In this tutorial, you will learn how to -
- Create an empty project.
- Rename a project.
- Create empty services.
- Rename services.
- Generate domains for services.
- Set variables on a service.
- Connect a GitHub repo to a service.
Prerequisites
For the sake of this tutorial, we have a simple example monorepo with a frontend and a backend service. In practice, your monorepo is probably alot more complicated, but the principles here will enable you to wire up each of your applications in your monorepo to a service and network those services together.
The frontend is built with React and Vite, and the static files are served with Caddy.
The backend, built with Go, will stream quotes that will be displayed on the frontend.
Before you start:
- Fork the repo: https://github.com/railwayapp-templates/monorepo-example
- Connect your GitHub to Railway. This will enable you to deploy any of your repositories to Railway in the future as well!
Let's get started!
1. Create a New Empty Project
- From your dashboard click
+ New Project
or⌘ k
- Choose
Empty project
Note: We chose an empty project instead of deploying from a GitHub repo since we want to set up the project before deploying.
2. Project Setup
- You'll notice Railway automatically named the project, but we want something more recognizable. Open the Settings tab to
Update
the name of your project. You'll also notice the Danger tab here, when you want to delete your project after you're done with the tutorial.
- Click
Update
3. Service Creation
- Add two new empty services from the
+ Create
button in the top right of the project canvas.
Note: We chose an empty service instead of deploying from a GitHub repo since we want to configure the service before deploying.
The result will look like this -
-
Give them both applicable names.
Note: This can be done easiest via the right-click context menu.
In the case of this tutorial, they will be named Frontend
and Backend
- Click the
Deploy
button or⇧ Enter
to create these two services.
4. Directory Setup
Both of our apps deploy from subdirectories of our monorepo, so we need to tell Railway where they are located.
- Open the Frontend service to its service settings and you will see a Root Directory option, in this case, we will set it to
/frontend
- Open the Backend service settings and we will set its root directory to
/backend
- Click the
Deploy
button or⇧ Enter
to save these changes.
5. Connecting the Repo
Now we need to configure the source of the service where the code is deployed.
- Open the service settings for each service and connect your monorepo.
Frontend
Backend
- Click the
Deploy
button or⇧ Enter
to deploy your applications
Your services will now build and deploy.
6. Domain Setup
Even though the services are now running, the frontend and backend aren't networked together yet. So let's setup domains for each service.
Both the Vite Frontend and the Go Backend are already configured so that Railway will ✨automagically detect the port they're running on. Railway does this by detecting the env.$PORT
variable that the service is binding. For simplicity's sake, we will connect these two services over their public domain so you can get a handle on the basics. In practice, you may need to configure your networking a bit differently. You can read more about networking in the docs.
Let's add public domains to both services.
- Click on the service and then open the Settings tab.
-
Click on
Generate Domain
. Railway will ✨automagically assign the port based on the deployed service. -
Do these steps for both services, so that they both have public domains.
Notes:
- Setting a Custom
$PORT
: Adding the domain after the service is deployed allows Railway to detect the boundenv.$PORT
. You could instead decide to manually set the$PORT
variable on the Variables tab, and set the Domain to use that custom port instead.
7. Variable Setup
For our example monorepo the Frontend service needs a VITE_BACKEND_HOST
variable, and our backend needs an ALLOWED_ORIGINS
variable.
Let's add the Frontend variable first.
-
Click on Frontend service, then the
Variables
tab -
Add the required variable -
VITE_BACKEND_HOST=${{Backend.RAILWAY_PUBLIC_DOMAIN}}
It should look like this once added:
Now let's add the Backend variable.
-
Click on the Backend service, then the
Variables
tab -
Add the required variable -
ALLOWED_ORIGINS=${{Frontend.RAILWAY_PUBLIC_DOMAIN}}
It should look like this once added:
-
Click the
Deploy
button or⇧ Enter
to save these changes. -
Your services should be deployed and available now! Click on your frontend service on the Deployment tab and you can click your domain to see the webapp.
Notes:
-
The variables used here are reference variables, learn more about them here.
-
Both the Frontend and Backend variables reference each other's public domains. The
RAILWAY_PUBLIC_DOMAIN
variable will be automatically updated whenever you deploy or re-deploy a service. -
See a list of additional variables here.
Conclusion
Congratulations! You have setup a project, setup services, added variables and deployed your monorepo project to Railway. The Frontend service should be accessible on its public domain to access the deployed website.
Edit this file on GitHub