How to Dockerize a NodeJS app? (With Typescript, Nginx, and Docker Compose) Step-by-step guide.
In this video, I will show you and explain how to wrap a Node.js app into a set of containers and launch with Docker compose. I will automate a build with Dockerfile, launch 2 containers with the Node.app and Nginx as a Load balancer.
Code sample: https://github.com/kirill-zhirnov/video-node-docker-deploy
Let's take a look on the scheme:
![Application Scheme](https://images.prismic.io/boundless/8729ccea-dfff-4f5e-86bd-69beed426d43_containers-scheme.png?auto=compress,format)
Inside Docker there are 2 containers with the Node.js app. In front of them is Nginx server. It is used as a load balancer to distribute requests across Node's containers. The Nginx exposes port to the public - it could be internet gateway (e.g. another Nginx server) or just the internet. Our application is isolated - Treat it like a bubble.
I created a simple Express App with Typescript. The App has one route. Locally, I can launch it with "yarn run dev" - it executes ts-node and server.ts file. Let's see - it works.
On the production, the app should be built before the run: TypeScript should be compiled into JavaScript. After that I will use a pure Node.js (not a Typescript) to launch the application. I prepared 2 commands: build and start.
"yarn run build" - compiles project into the build folder.
"yarn run start" - Launches the app.
Now let's add Docker. I already created Dockerfiles, let's take a look on Node's Dockerfile.
So, What we are having here. I'm using an Alpine version of Node.js image - since I'm preparing for the production and the smaller size is better. I split the build process on multiple small steps. I'm doing it to have cached layers. Treat a step who makes changes in the file system like a layer. For example, If I need to rebuild the image and there is no changes in package.json - a cached version of node_modules will be used. It reduces building time. The Faster build is cheaper.
The next moment I would like to highlight - is installing dependencies. For example, I need ImageMagick library - imagine - our application executes the convert command. We need to supply a Docker image with all the dependecies, remember - it is like a bubble where the dependencies is incapsulated. So install all your system dependencies here.
The next step - is installing NPM packages and launching the build process. After that - our image is ready. We can test it.
Now let's launch the image with the Docker Compose. Few words about the Docker Compose. It is a very handy tool for launching a Set of containers. Remember, we will have 2 containers with Node and one Container with Nginx. Docker compose use a YAML file.
What is important to understand on this stage - that the docker compose creates an internal network, where containers can use their names for communication.
For example, from the nginx config we refer to nodejs hosts. This is an environment variable - it will be replaced during the build. Environment variables are specified in the .env file.
But let's skip it for a moment and test only the Node.js container. So I comment all unnecessary lines, expose port and then type in the terminal: docker compose up. The server is started, lets open in the browser: localhost:3000 - it works.
Now we are ready for the final launch. I uncommented everything, then I type docker compose up. As you can see from the log - Nginx is also started and there are 2 node's containers: node-1 and node-2.
Let's test local port 8080. It works, just great.
Some useful commands:
If you want to run it on the production - add "-d" - you see - docker ran containers in the background. To see runned containers I type docker ps. Sometimes you need to connect to active container and do some actions there. How to do it? Easy. Once you have a list, type:docker exec -it fun-with-docker-node-1 /bin/sh . Alpine version has only sh, normal version contains bash.
To upgrade. You can use these commands: docker compose build and then execute the fresh build: docker compose up -d. And the containers will be replaced.
If you want to down it, type: docker compose down.
About the Nginx - not sure if it is reasonable to explain in this video. If you have questions - email me.
This approach is ready for production, it automates build and incapsulate all the dependencies.
I hope it was useful. Thats probably it. If you have any question - please leave a comment below.
If you need a ecommerce solution - consider Boundless Commerce. It's an API First Headless Ecommerce Platform. Please star our repositories on the GitHub - it helps a lot!
If you are looking for IT services - Website Development, Custom Software Development, DevOps services or whatever - please contact me - I will take care of your project.
Don't forget to press Thumb's up.
And thank you so much for watching! I really appreciate it!
See you soon, Good bye!
![Kirill Zhirnov](https://images.prismic.io/boundless/032637d2-5eb4-431b-9bee-b609662b76d6_2022-06-12+12.43.59.jpg?auto=compress,format&rect=0,319,960,960&w=150&h=150)