How to deploy a node.js docker image on Google cloud
What it is and why you might need it

General description

Yes, I know. Docker can be scary. Deployment can be scary. Google cloud can be scary. How do we approach this 3-headed hydra without being devoured?

To be honest, for a very long time I was also quite apprehensive about topics like Docker, the google cloud etc.. Somehow I always found it better to set up my own server with providers like Digital Ocean (still a great service in my opinion) or other providers. Then manually deploying my application there via SFTP or continuous integration, setting up the firefall etc. But seriously - if that didn't "scare" me - then why the simple deployment of a docker container?

Apart from the fact that it's obviously a great way to learn more about how servers work, it's all always been a pretty laborious process unfortunately. Manual updates of packages, lots of googling what is the "safest" way to manage the server, etc. All this was not very satisfying.

So it was time to look around and find alternatives.

Docker

Docker has become the quasi-standard for application containerization. And - it is damn easy to handle, once you dare to do it. I don't want to belittle the complexity - if you want, you can do extremely complex things with docker - but for the simple deployment of a server-side application with Node.js you really don't need expert knowledge.

In this article, we'll go step by step through the stages from a local Node.js Express application to a Docker container deployed on Google cloud.

Google cloud

Google cloud run

Container to production in seconds

What sounds already is even more beautiful. Deployment with the google cloud is incredibly simple. Create a container, run the command line and set a few configurations - and the application is up and running. So let's take a look at how we create a container with docker.

Creating a simple express app


First we create a simple Express application


/** app.js */

const express = require("express");

// initialize
const app = express();

// basic get route
app.get("/", (req, res) => {
	res.status(200).json({ message: "hello world!" });
});

// configure a port - important
const port = 5000;

// listen on the port
app.listen(port, () => {
	console.log("running on port: ", port);
});

Dockerfile


The dockerfile is the entry point of the app

FROM node:12-slim

# Env variables
ENV WDR=/app

# working directory in container
WORKDIR ${WDR}

# copy the package.json into the container
COPY package.json ${WDR}
COPY . ${WDR}

# install all dependencies
RUN npm install

# run the start command
CMD ["npm", "start"]

This is basically everything we have to do, to get the container running. Now we can run the container locally by using the docker CLI.

docker cli


The docker cli is used when managing individual containers on a docker engine. It is the client command line to access the docker daemon api.


docker-compose cli


The docker-compose cli can be used to manage a multi-container application. It also moves many of the options you would enter on the docker run cli into the docker-compose.yml file for easier reuse. It works as a front end "script" on top of the same docker api used by docker, so you can do everything docker-compose does with docker commands and a lot of shell scripting.

commands


Build image from current directory

first we will build the docker image:

docker build -t node-tutorial .

run interactively with file changes

We can then run the build in interactive mode and map the internal port to a port different defined port. This means, all requests that we are sending through port 8000 will be forwarded to the port 5000 in the docker container.

docker run -it -p 8080:5000 -v $(pwd):/app node-tutorial

list containers

docker ps

Google cloud run

After verifying that our container is running locally as expected, we can start providing the build to google cloud run.

Make sure that you exclude unnecessary files with a .dockerignore file from the container image

node_modules
npm-debug.log
.git
.gitignore

Next, you need to make sure that you have the google cloud SDK installed on your machine. As of today, you will find instructions here: https://cloud.google.com/sdk/docs/install

Once the installation is completed, create a project in your google cloud. You will need the project ID to attach the container-image to this project. Replace "Project-ID" with your project id.

gcloud builds submit --tag gcr.io/PROJECT-ID/node-tutorial

Next, you can deploy your project

gcloud run deploy --image gcr.io/PROJECT-ID/helloworld --platform managed

Thats it. After all processes finish, you will have your deployed server ready. By defalt it comes with a predefined URI but has SSL enabled. For private APIs thats already perfect.

Public APIs would need a custom domain, but that is a topic for another time. Have fun building with the google cloud!