DEV Community

Cover image for How to deploy a MEN stack app from our local machines to Heroku
Phyllis
Phyllis

Posted on • Updated on

How to deploy a MEN stack app from our local machines to Heroku

Alt Text

Introduction

Recently when I deployed a web application on Heroku, I spent a lot of time debugging and researching. A seemingly simple process turned into a few hours task. Hence, I would like to share my experience.

In this article, I will describe how to deploy an existing web application that is built using MongoDB, Express.js and Node.js from our local machines to Heroku.

Prerequisites

You'll need to have:

  • An existing MEN stack app
  • Git installed. Read this guide if you need to install Git. Learn about how to set up Git here
  • Heroku Command Line Interface (CLI) installed. This CLI will make it easier to create and manage your Heroku apps directly from the terminal. The simplest way to install it on macOS machines is using brew.
brew tap heroku/brew && brew install heroku
Enter fullscreen mode Exit fullscreen mode

For other operating systems, please refer to here
After you go through the installation process, you can check if the CLI has installed correctly by running:

heroku --version
Enter fullscreen mode Exit fullscreen mode

If it has been installed successfully, you should see heroku/x.y.z (x, y, z are numbers) in the output.

  • You will also need an account at Heroku website.

1. Configure package.JSON

We need to check if package.JSON has all the correct dependencies, as Heroku will need the list to know what to install for the app to work. Then modify the file by adding the following script. This will tell Heroku how to start the app.

"scripts": {
        "start": "node server.js",
        [...]
    }
Enter fullscreen mode Exit fullscreen mode

2. Using process.env.PORT

When we test our Express.js app in the local environment, it is usually configured to bind to a port instead of the one provided by Heroku via the $PORT environment variable. For example in app.js file,

app.listen(3000, function (){
  console.log("App is listening on port 3000");
});
Enter fullscreen mode Exit fullscreen mode

However, When Heroku's port for the app to bind to is dynamic, its value is exposed in the $PORT env var. To make sure our app bind to this port instead, we need to change our code to:

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Our app is running on port ${PORT}`);
});
Enter fullscreen mode Exit fullscreen mode

By using this code, the app will use the $PORT env var if available or fallback to a default port 3000 if we are running locally.

3. Connecting with Database using MongoDB Atlas

I am going to use mongoDB Atlas to host the database of our application on the cloud.

After registering, we can login and create a new database cluster.
If you want a free option, make sure 'FREE TIER AVAILABLE' options are selected and it says FREE on the bottom-left corner, before clicking the green button to create our cluster.

After the cluster is created (which would take some time), we can click CONNECT button.

Then we need to paste 0.0.0.0/0 for IP address and click the green "Add IP Address" button. This will enable access to our database server from any IP.

Create a user by entering a new username and a strong password. Make sure to remember our credentials as we would need that for our SRV address later. Press the "Create MongoDB User" button.

After this is done, we can press the "Choose a connection method" button on the bottom right.

Click the "Connect Your Application" button in the next window.

Choose the "Short SRV connection string" and click COPY button.

In the SRV address we need to replace PASSWORD with the password we chose when we created a user. Then remember to save the address somewhere for later usage.

4. Login to Heroku

You can login to Heroku using the Heroku CLI. If you would like to login through the web browser, use the following command in the terminal.

heroku login
Enter fullscreen mode Exit fullscreen mode

If you want to log in through the command line instead, add the -i flag.

heroku login -i
Enter fullscreen mode Exit fullscreen mode

5. Initialise a Git repository, add and commit files to Git

When we are in the project folder, initialise a new Git repository (if we have not done it) by using the following command in the terminal.

This step is very important because Heroku relies on Git for deploying app from our local machine to its cloud servers.

git init
Enter fullscreen mode Exit fullscreen mode

Afterwards, follow the following steps to add and commit files to Git.

git status
Enter fullscreen mode Exit fullscreen mode
git add .
Enter fullscreen mode Exit fullscreen mode
git commit -m "<your-commit-message>"
Enter fullscreen mode Exit fullscreen mode

6. Create a new Heroku project

Now, we can create a new Heroku project with a name we choose. I name mine as demo_app.

  • If we don't name our project, Heroku will create a random name for our project.
  • The name will form part of the URL which can be used to access our project. It means we need to choose a special name for our project that no one has used.
  • It is possible to rename our project later so don't need to worry too much. Read here for more details.
heroku create demo_app
Enter fullscreen mode Exit fullscreen mode

7. Setting up environment variables for database URL

At the moment one database is shared between development and production environments. This is not good practise because if we lose any data in our development environment, the same data will be lost in production. We also do not want to expose sensitive data such as MongoDB Atlas SRV address on Github.

To prevent these issues, we need to set up environmental variables of DATABASEURL locally and on Heroku.

To set up DATABASEURL locally to localhost, run the following script on the terminal. Remember to plug in name of your app folder in the URL.

export DATABASEURL=mongodb://localhost:27017/<name_of_your_app_folder>
Enter fullscreen mode Exit fullscreen mode

Add the following after variable declaration in app.js file. process.env is the way Node.js used to access environment variable. Then start the server to see if the correct localhost URL appears in the output on terminal.

console.log(process.env.DATABASEURL)
Enter fullscreen mode Exit fullscreen mode

If the correct URL appears, modify mongoose.connect script in app.js file to the following. This allows localhost acts as a backup if something goes wrong with the environment variable.

var url = process.env.DATABASEURL || "mongodb://localhost:27017/<name_of_your_app_folder>"
mongoose.connect(url, { useNewUrlParser: true }); 
Enter fullscreen mode Exit fullscreen mode

To set up a separate DATABASEURL for Heroku, go to our application settings after we logged in Heroku on web browser.

Scroll down to Config Vars section and click Reveal Config Vars button.

Enter DATABASEURL as key and your MongoDB Atlas SRV address as value. Then click Add.

Alt Text

8. Add and commit files to Git and push to Heroku

Before we deploy to Heroku, make sure we have Git added all the relevant files and committed them.

git add .
git commit -m "ready to deploy"
Enter fullscreen mode Exit fullscreen mode

The final step is to push to our Heroku master branch.

git push heroku master
Enter fullscreen mode Exit fullscreen mode

We should see a bunch of information prints out in the terminal as Heroku builds and deploys our app.

If Verifying deploy...done appears, it means our build was successful.

Congratulations! Now you app is hosted on your-project-name.herokuapp.com for all to visit!

If there is "application error" appears when you visit your app, I would recommend checking logs with the following command and referencing Heroku docs.

heroku logs
Enter fullscreen mode Exit fullscreen mode

Thanks for reading! I hope this article is helpful.

Buy Me A Coffee

Top comments (2)

Collapse
 
ljcdev profile image
ljc-dev

Great first post! 👏👏 Definitely going to refer to it when I'll try to deploy express/mongoDB. Thanks for sharing!

Collapse
 
phyllis_yym profile image
Phyllis

Thanks :) Hope this helps !!