DEV Community

Cover image for How to host your Node app in a Docker Container on Heroku
Wachira
Wachira

Posted on • Originally published at wwachira.hashnode.dev

How to host your Node app in a Docker Container on Heroku

Introduction

This is the third part of the series for Docker meets NodeJS.

We got to add a mongo database as a service and maybe you added a couple of endpoints to test it out, but the whole app is in runs locally and you might want to let the whole world have the opportunity to test out your Node app well not to worry, Werick is here.

In this part, we are going to host our application on Heroku.

Note: Since we are introducing a new database service, by doing so this also makes our Node app also a service

Note: Ensure you go through the first part of this series and the second part too.

Note: Remember to clone the docker_nodejs_app repo here

Why Heroku?

You might ask yourself why I chose Heroku instead of Digital Ocean, Linode, GCP or AWS...🤔the reason is that Heroku allows you to get up and running quickly and deploy your code without worrying about how your infrastructure runs underneath.

For the other platforms well you will be assigned a CPU(s) in which you will set up the whole thing including installing software, libraries, securing your server with SSH which will kinda consume most of your time and you just want to host your simple express server.

Getting Started

Well enough promoting let host something. First of all, you will have to create an account on Heroku

Screenshot 2019-06-16 at 12.02.19 PM.png

After creating your account on Heroku, you will have to install its CLI. The Heroku CLI makes it easy to create and manage your Heroku apps directly from the terminal. It’s an essential part of using Heroku.

Mac

To install the CLI on Mac you can do it in two ways:

Windows

To install it on Windows you just need to know which type works with your computer, is it a 32-bit or 64-bit

Ubuntu

For Ubuntu, you will need to install it with snap:

$ sudo snap install --classic heroku
Enter fullscreen mode Exit fullscreen mode

Let's get into deploying

To check if you successfully installed it globally, type this in your terminal

$ heroku --version
Enter fullscreen mode Exit fullscreen mode

In your terminal cd into the directory where our node app is housed. Next, we have log in to Heroku through the CLI.

$ heroku login
Enter fullscreen mode Exit fullscreen mode

Press any key to log in, this launches your default browser where you will log in successfully return to your terminal.

You will also need to log in to the container registry, basically, this is a service that Heroku offers to host our docker container.

$ heroku container:login
Enter fullscreen mode Exit fullscreen mode

We have to create our Heroku app where our code will be held and built.

$ heroku create docker-nodejs-app
Enter fullscreen mode Exit fullscreen mode

You should see something similar on your terminal
Screenshot 2019-06-16 at 11.03.13 PM.png

Before we build and deploy our app we need to change the port our Express server runs on. The default port was 3000 but when we build and deploy our app on Heroku we might get an error about our PORT already being used, so we need to create a condition whereby if Heroku does not give us a port we use our default 3000.

Change the line you set your port default to this:

app.set("port", process.env.PORT || 3000);
Enter fullscreen mode Exit fullscreen mode

Your app.js file should look like this

"use strict"; // Ensures our code is compiled in strict mode

// Lets import our web framework
var express = require("express");
var mongoose = require("mongoose");

// Initialise our app
const app = express();

// Lets set our port
/**
 * The default port number is `3000` if Heroku does not provide us a port
 * Take note on that as we will come to that.
 */
app.set("port", process.env.PORT || 3000);


// Connect to database
mongoose.connect("mongodb://mongo:27017/docker_nodejs_app", {
  useNewUrlParser: true,
  useCreateIndex: true
});

mongoose.connection.on("open", err => {
  if (err) console.log("Error connecting to our mongo database");
  console.log("Connected to mongo database successfully");
});

/**
 * To ensure works as it should we will create a
 * simple endpoint to return a json response
 */

// Define our json response
const data = {
  blog_name: "docker_nodejs_app",
  blog_author: "wachira (tesh254)",
  blog_author_twitter: "@wachira_dev"
};

// Define out GET request endpoint
app.get("/", (req, res) => {
  res.status(200).json(data);
});

// Initialize our server
app.listen(app.get("port"), () => {
  console.log(`Server listening on port ${app.get("port")}`);
});

Enter fullscreen mode Exit fullscreen mode

Next, we will build our image and push to Container Registry

$ heroku container:push web
Enter fullscreen mode Exit fullscreen mode

You should see something similar on your terminal

Screenshot 2019-06-16 at 11.07.24 PM.png

What happens in the background?

  • First, Our whole app was built according to the Dockerfile and the docker-compose.yml configuration.
  • Heroku CLI pushes our built image to our created app through git.

Next, we need to release our app so that it can be accessible to the whole world.

$ heroku container:push web
Enter fullscreen mode Exit fullscreen mode

This should appear in your terminal

Screenshot 2019-06-16 at 11.24.08 PM.png

You have successfully deployed your app on Heroku🎉🍾🎊🙌

Summary

To summarise, in this awesome post we have:

  • Successfully built and deployed our app to Heroku

Next

In the next part:

  • Push our repo to the Docker repository.

  • Other commands in Docker that will make your experience worthwhile such as:

    • Clearing container cache
    • Deleting, Stopping Docker containers

Extras

Top comments (9)

Collapse
 
wchr profile image
Wachira

Heroku is a platform that allows you to deploy your apps and not worry about the infrastructure thus giving you time to focus on writing awesome features for your app. If you use a VPS such as Linode, you will have to decide which OS to use, installing software or libraries so that your app can run successfully e.g. Nodejs, Git, Docker and so many more. Basically, with a VPS you will have to handle a lot and think about your infrastructure while you still have to build features for your app.

 
wchr profile image
Wachira

If you are a DevOps then Digital Ocean/or any VPS is best suited for you but for a dev who does not want to worry about infrastructure or setting up your Ubuntu server from scratch then, Heroku is your way to go.

 
misterhtmlcss profile image
Roger K.

Thank you so much for the answer. I'll definitely keep my mind open the next time around. This time I'm so focused at becoming more competent at Docker that I need to see it through as part of solidifying those skills. However you've convinced me to make an effort to learn more about Heroku's approach. Thank you for sharing and going that extra mile in sharing your thoughts. As a junior I survive off the kindness of our community.

 
bvmcode profile image
bvmcode

the cut of your jib matches your profile picture haha

 
wchr profile image
Wachira

I dont mind, infact i am happy that you asked that so that other devs might know the reason why😁

Thread Thread
 
misterhtmlcss profile image
Roger K. • Edited

Actually I'm doing this right now. I don't think the reasoning is as strong for Heroku, but I still find deployment is easier using a tool that you know will give you the end results you wanted.

Maybe I'm wrong; I'm new to Heroku and therefore that's what drew me to this article, but what I have found is still I need to set many things on Heroku to ensure I get the same outcome for my stack as I had on my machine. Is this not still the case? Perhaps using Docker is overkill when compared to this 'procfile', but I don't know what that is and so I'd rather avoid it personally. I am always seeking to reduce my technical burden when and where reasonable. I don't want to learn more about Heroku than I need to to use it effectively.

So I ask you guys. Is it not reasonable to just use Docker to deploy on Heroku and avoid learning these other platform specific methods?

Ps. Loved the banter!

 
misterhtmlcss profile image
Roger K. • Edited

Thank you for confirming my thoughts. Really appreciated! Have a great week. All the best you and your family :)

Collapse
 
wchr profile image
Wachira

Thanks...means a lot

Collapse
 
rafi_me91 profile image
Mohammad Rafi

waiting for the next part!!!