Normally Dockerizing the Node application is a simple task. We can use the direct on-build images available in Docker hub directly in most cases. 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 technology, 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!!