Dockerize your NodeJS app with Nginx as reverse proxy

Normally Dockerizing the Node application is a simple task. We can use the direct on-build images available in Docker hub.

That Docker image is enough to deploy the NodeJS application. All versions of on-build Node image is available in hub.

If you are new to Docker containerisation area, I suggest you to read the basics that I shared/discussed in my previous blog. You will get some ideas by following those and you will be ready for this deployment. All the Docker things are added into this category.

Introduction to Docker containers – part 1

Docker can create containers for deploying those micro services. It’s a tool/software to create containers quickly and effectively from Linux command line.

Building Node container from on-build nodejs image

See the sample Docker file for onbuild Docker image. All these things are available in Github.

FROM node:8.13.0-stretch

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ONBUILD ARG NODE_ENV
ONBUILD ENV NODE_ENV $NODE_ENV
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install && npm cache clean --force
ONBUILD COPY . /usr/src/app

CMD [ "npm", "start" ]

This is an example for NodeJS version 8. Check this Github for all official Docker files.

I’m not explaining the lines in the above Docker file. I believe, you guys are familiar with that.

In this article, I am explaining a customised way of deployment. The actual requirement is like that.

Dockerize the NodeJS application running on a VM (Virtual Machine) which has Nginx reverse proxy. The Nginx is responsible for a few 301 redirection and main site SSL redirection. So we need to include this same configuration in our Docker container for Nginx.

We need to start Node (after pulling changes from repo, build ..) application and Nginx in this case. Normally we can start only one thing using Docker file. Otherwise, you need to start both process using a script.

Yeah, you can add the start commands for both NodeJS and Nginx in a text file as bash script and you can run that scrip using Docker.

Looks something like:

FROM ....

....
....
....
CMD [ "sh", "/root/start.sh"]

Here the start.sh file contains the startup commands for both NodeJS and Nginx applications.

Use of Linux supervisord

This is a standard way to start multiple process. We can add the start command of supervisord at the last line of Docker file. When the container starts, it will start the supervisord daemon and the supervisord will manage other processes.

Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems. More about supervisord.

In our case, we need to start the NodeJS application and Nginx.

The examples and snippet added in this post is just for explaining things. You need to modify thing according to your requirements.

As I mentioned you can alter all the lines in Dockerfile and other things as per your requirement.

Here the Dockerfile is ending with a start.sh file which contains the NodeJS start command and then supervisord start command. You can simply use the supervisord command as the start command of your docker container.

In my case it was not an “npm start” and I got some issues to execute the “node” command using supervisord.

So in this case you need to include following files in your code repository.

  • Dockerfile

  • Nginx configuration file

  • Start.sh file

  • Supervisord configuration file.

Keeping the configuration file in your repo will help you to make changes without issues. Consider, you want to add one more 301 redirect in the Nginx configuration file, as we are keeping the configuration in the repo, you can just add the line in that file. The next build will take care of the deployment of that rule.

Because, every-time the conf is copying from the repo to container.

Docker file to deploy NodeJS with Nginx proxy.

FROM ubuntu:16.04

# 80 = HTTP, 443 = HTTPS, 3000 = MEAN.JS server, 35729 = livereload, 8080 = node-inspector
EXPOSE 80 4000

# Install Utilities
RUN apt-get update -q  \
 && apt-get install -yqq \
 curl \
 git \
 ssh \
 gcc \
 make \
 build-essential \
 libkrb5-dev \
 sudo \
 vim \
 net-tools \
 apt-utils \
 supervisor \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Install nodejs
RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
RUN sudo apt-get install -yq nodejs \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Install and copy Nginx
RUN apt-get update \
    && apt-get install -y nginx

COPY default /etc/nginx/sites-enabled/

# Copy supervisord conf
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

# Copy start script
COPY start.sh /

# Node deployment steps
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install && npm cache clean --force
COPY . /usr/src/app
RUN npm run build:ssr    [change as per your app's build step]


CMD [ "/bin/sh", "/start.sh" ]

Things that you need to keep in mind:

1. # Install nodejs

In this section, you need to change the NodeJS version as you required.

2. # Install and copy Nginx

Here copying the nginx configuration file for your website / app running as proxy on NodeJS. This also you need to make sure the correct one.

3. # Copy supervisord conf

This is the supervisord configuration file.

4. # Copy start script

This is the start script. In my case I am starting Node and Supervisord using this bash script.

Sample supervisord configuration file

[supervisord]
nodaemon=true

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
priority=10
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
stdout_events_enabled=true
stderr_events_enabled=true

Sample start.sh file

#!/bin/bash
# Starting Node 

cd /usr/src/app
nohup node dist/server.js &
#Starting Nginx
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf

Again, this codes may not meet your exact requirement. However, it can help you.
Change it as per your requirements and deploy.

Thanks!!

Post navigation

Arunlal Ashok

Linux Systems Architect at Endurance International Group. Linux lover. Like to play on Linux console. I started this blog to share and discuss Linux thoughts.

Always happy for an open discussion! Write to arun (@) crybit (dot) com. Check about me for more details. About this blog and our strong members, check The team CryBit.com

Leave a Reply

Your email address will not be published. Required fields are marked *