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
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
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",
[...]
}
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");
});
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}`);
});
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
If you want to log in through the command line instead, add the -i flag.
heroku login -i
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
Afterwards, follow the following steps to add and commit files to Git.
git status
git add .
git commit -m "<your-commit-message>"
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
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>
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)
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 });
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.
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"
The final step is to push to our Heroku master branch.
git push heroku master
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
Thanks for reading! I hope this article is helpful.
Top comments (2)
Great first post! 👏👏 Definitely going to refer to it when I'll try to deploy express/mongoDB. Thanks for sharing!
Thanks :) Hope this helps !!