Deploying a Node application to Heroku, part 2

Defining a port for our application

In the previous article we talked about defining a PORT variable used by our application to run on.

Our application needs different PORT numbers for different environments (development, production, and so on) so we cannot hard code a specific value, like 4000, but we need to set up an environment variable that may have different values, depending on where our application is running.

Heroku, like many other hosting platforms, will provide an environment variable called PORT that allows them to manage a port where the application will listen on, and make that port available to us.
We can then use the value of the PORT variable as the port number for our application, which is accessible through process.env.PORT.

As a reminder, process is an object made available by Node, and env is a property on that object that collects all the environment variables defined for this project.
Instead of hard coding port 4000 into our application, we can use the port variable instead.

Here's the code:

// index.js

const port = process.env.PORT

server.listen(port, () => {
  console.log(`Server Running on port: ${port}`);
});

Here we have defined a port variable that takes its value from process.env.PORT.
Note that by convention environment variables are written in uppercase.

Defining the port

If we start our development server now, with yarn server, we notice that the message printed out in the console tells us the port is undefined:

Server Running on port: undefined

That's because we didn't actually define the PORT environment variable on our system yet.
The way we go about this is: we want to use PORT if it exists or use a default port if it doesn't.
In our code we use a conditional expression that checks if the PORT variable is defined. If it is, we can use it; if not, we will use port 4000.

const port = process.env.PORT ? process.env.PORT : 4000;

Now, when we restart the server, it will detect that process.env.PORT is undefined, so it will switch to port 4000 as a fallback. The message printed out confirms this fact:

Server Running on port: 4000

Defining environment variables through the .env file

This pattern of checking if an environment variable named PORT exists, and of defining a fallback port if it doesn't, works, but a better way to set environment variables is through a file called .env.

In .env we could define separate variables for each environment we use if we need to.
Instead of dealing with hard coded port numbers (or other type of variables, like database connection details or passwords), our application simply references .env so when it's loaded in a different environment it will have access to each specific set of variables automatically.

All this said, we create a .env file in our project and add the PORT variable to it. In .env, variables are listed as variable name, equal sign, variable value, each variable on its own line.

# .env

PORT=4000

Now, all we have to do is set up our application so it can use the .env file, and consequently, all the environment variables defined in it.

The way we do it is through a Node package called dotenv that will take care of all the implementation details.
We install dotenv the usual way with yarn add dotenv and once installed, we require it into our application:

require('dotenv').config()

Upon requiring, we immediately call its config() method, and by default dotenv will look for a .env file in our project and create environment variables in our system based on what's in that file.
That will allow the environment where the application will be deployed to control what the port number is.

The .env file is not just for setting the port. In it, we can define variables for database connections, secrets, passwords, and so on.

Ignore .env

In order to prevent putting this file on GitHub, where it would be visible to anyone, we need to add .env to the .gitignore file, so it will be ignored when committing our changes to the Git repository.

## .gitignore

# dotenv environment variables file
.env

If we restart our application now, it will be listening to the port defined inside .env, no matter what the value of PORT is.


Did you like this article? Share it with your friends.
I write daily about front-end and back-end web technologies.
You can receive all my articles in your inbox by subscribing to my newsletter. Just click the button below. No spam, just good, useful content. Guaranteed!


Follow me on Twitter