Deploy an ExpressJS app with PostgreSQL database
This post walks you through building and hosting your ExpressJS backend with Railway. From deploying the barebones example to setting up a database (and adding dummy data to it) to working with it locally, we have got you covered!
Express is a fast, unopinionated, minimalist web framework for Node.js. You can use it to build web applications and APIs, and we will cover the latter here. Let's start by deploying our Express starter.

Deploying the Express starter on Railway
Yep, that's how easy it is. Most of our starters involve one-click deployments. We take care of the boring work so you can focus on building your core product.
In the section above, we deployed a barebones Express app to Railway. For any real-world application, we want to connect our app to a database so we can store and retrieve data.
The good thing is that with Railway, provisioning a database is as simple as the deployment we just did, if not easier.

Provisioning a PostgreSQL database
In the GIF above, we provisioned a PostgreSQL database which we can now use with our Express application. We also provide plugins for MySQL, MongoDB, and Redis.
Let's add some dummy data to our database so that we can consume it within our application. To do this, you would normally need to SSH into your database or download a tool that allows you to interact with it.
But with Railway, we have built a neat little UI where you can interact with your database as you would with any GUI. We even have a handy function in our command palette to generate dummy data for you!

Generate dummy data
So far, we have deployed an Express app, provisioned a PostgreSQL database, and added some dummy data to it. Next, we will clone our project locally and start adding features. Here's mine if you're following along.
Let's start by adding and configuring the node-postgres package so we can interact with our database.
yarn add pg
yarn add -D @types/pgNext, let's set up and use the package to show some jokes to our users.
import pg from "pg";
const pool = new pg.Pool();
app.get('/jokes', async (req, res) => {
const { rows } = await pool.query("SELECT * FROM jokes")
res.json(rows)
})At this point you're probably thinking "hang on a minute, we haven't even set up the database locally". That's the thing with Railway: you don't have to. All your environments live in the cloud, and this is where the Railway CLI comes in.
If you head over to the Setup section on your project's dashboard, you'll see the instructions for installing the CLI and linking to your project on Railway.

Project setup instructions
Once you've linked your project, you prepend your commands with railway run. This allows us to run the code using your selected Railway environment and inject all your environment variables. This way you don't have to do any fiddling with .env files at all, and you can switch environments and automatically have the respective variables available to use.
railway vars to view all the environment variables for your selected environment!Let's try running our development server and visiting http://localhost:3333/jokes to see this in action.
railway run yarn dev
Jokes from our database
We've now built our jokes API and want to showcase it to the world. To do that, we need to deploy our code to the cloud. We can either use the CLI and run railway up to deploy our selected environment, or we can set up Github triggers that automatically trigger deployments whenever we push our code to the selected branch.
We can also set up custom domains by heading over to the Deployments tab in our project dashboard. You can check out our jokes API here and feel free to reach out to us on Twitter with yours!
We hope this guide gave you an idea about what the workflow with Railway looks like. Our main goal is for you to only have to worry about building your core app while we take care of everything else.
We also have a couple of other examples using Express in our starters repository that you might be interested in, and if there's something you feel should be there but isn't, we're happy to receive PRs for the same. 🤗
Happy shipping.
Angelo
Angelo Saraceno is a Solutions Engineer at Railway. Before Railway he was at Citrix, working inside Verizon and Lockheed environments, so he has seen what "enterprise IaaS" looks like after the slides come down. He writes about infrastructure, deployment, and the gap between how cloud is sold and how it runs in practice.