Deploying a Node.js App with a Database to Heroku, for the Uninitiated, Part 1.

James McCormack
Queers In Tech
Published in
4 min readDec 6, 2017
You will scale this wall soon! — Photo by Lance Anderson on Unsplash

I may not be the first to broach this subject, but I am going to attempt to break my process down as clearly as possible, define my set-up, and hopefully provide enough pretty pictures to get you on your way.

Section 0: (Because everything is zero-indexed.) First of all, congratulations. You have come a long way from declaring your first variable. Did you ever think you would have built a full stack app that queried your own database? Now you’re here, and ready to share it with the world. Treasure that.

Section 1: The specs I used:

My terminal: oh-my-zsh. Bash will work equally well.

The back end is written in Node.js, with Express as the router and ejs for the templating language.

The database is PostgreSQL, and I used pg-promise to connect to it. I also use Postico as a GUI tool for Postgres, so I can obsessively refresh it and see my users populating the database in real time.

Session management happened with express-session and connect-pg-simple, and I stored my sessions in a separate table in my database.

Finally, I used git and Github as my version control, and this is a pretty integral part of how we’re going to deploy to Heroku.

If any of these are different for you, you may be able to follow along with some of this, but there will be a point where you’ll have to go off and find docs for your variant. I’m sorry — I’ve been there and know the pain.

Section 2: Preparing your app for its first day at school…

Does your project have a .env file?

If it does and you are familiar with process.env variables, you can probably scroll a bit. Otherwise, this is important!

A .env file hides the process.env variables in your project. You do NOT commit this file to git, ever. Create it in the root of your project, and then immediately go to your .gitignore file (if you don’t have one, create it now, also in root, and type node_modules with no quotation marks as the first line) and put your .env file in there.

Are you back? Good! npm install dotenv and then require it at the VERY TOP of your main server.js file like this: require('dotenv').config() Note that you have to call config at the end of the statement. You do not need to assign this to a variable like most other requires.

There is at least one that you’re going to have to create, and it has a standard name. It’s called process.env.DATABASE_URL and the caps there are intentional. The connection string that you used to connect to pg or pg-promise probably looks like this: postgres://localhost:5432/yourproject

You will now want to change that line to this:

const db = pgp(process.env.DATABASE_URL || "postgres://localhost:5432/yourproject")

And in your .env file, do this:

process.env.DATABASE_URL="postgres://localhost:5432/yourproject"

Here’s why, in a nutshell. On your localhost, you are telling the program to either go to your .env file to find connection string, and in case of failure, to fall back to a hard-coded version. You can omit the “or” and just direct your connection string to your .env file, and as long as everything is set up, you’re fine. Test it out either way, and it should run. Then why does it matter? Heroku sets its own process.env.DATABASE_URL to the connection string you will need to connect to the database on their servers, and this bit of code allows you to run your app on localhost or Heroku without a problem.

If you used express-session or a similar package, you will have a session secret inside of a session object. It usually looks like this:

app.use(session({
store: new pgSession({
conString: process.env.DATABASE_URL || "postgres://localhost:5432/yourproject",
}),
key: 'user_sid',
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: { maxAge: 10 * 10 * 6000000 },
}));

If the new pgSession thing looks unfamiliar, it’s a connect-pg-simple thing, and your configuration may vary. In any case, if your secret is exposed in your app, change it to a process.env variable, too: process.env.SESSION_SECRET="macandcheese4ever"

Whew! We’re done with that. Other important little things that can cause your app to go haywire when it’s deployed: 1) If you’re making an AJAX/Fetch call to an api, make sure you’re using https instead of http. 2) Check your absolute versus relative paths. 3) I’m sure there are more, but we will learn how to discover them with heroku logs . Spoilers!

Next up is Part 2, where we get started on Heroku and do some Bash scripting! I promise it won’t hurt…

--

--

James McCormack
Queers In Tech

JavaScript wrangler, board game lover, and nerdy believer in love and spreading knowledge.