Quick Intro to Dockerizing Your Node App
Tags: docker, beginners, node
Published: 2019-12-15 15:48:55

If you building a node app and want to publish it, you need to upload and run it on the server. But it does not guarantee you, that the app will work the same on the server as on your machine. Small differences to runtime environment (your laptop vs. server) can influence how your app will behave. Building an app in the container will solve that problem. In this short article, I will show you how to use Docker to run a node app, making sure it will run as expected regardless of the server.

## Docker

Docker, in short, is a container platform that keeps your runtime environment the same for development, testing and production. In other words, it solves the "it works on my machine" problem.
It makes sure that your applications are securely isolated in a container, packaged with all its dependencies and libraries.
Containers are run from a Docker image, which is a filesystem with dependencies, runtimes, code and everything that is required to run an application. Every container is isolated from the others and interacts with its own filesystem.

## Building a Docker Image

Let's assume that we have a simple Express app:

```js
// index.js
const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => res.send('Hello Docker!'))

app.listen(port, () => console.log(`Server started and listening on port ${port}!`))
```
To put everything into a Docker container we need to build an image.

For that, you need to install Docker on your machine. It can be a [desktop version](https://www.docker.com/products/docker-desktop) or a CLI. After installation, you should be able to check its version with `docker -v` command in the terminal.

Second, create a `Dockerfile`, it's an actual file name, in the root directory of the app. `Dockerfile` holds configuration settings, of how the image supposed to be built.

```docker
FROM node:13.3.0

WORKDIR /usr/src/app
COPY . /usr/src/app
RUN npm install
CMD [ "npm", "start" ]   
```
`FROM` -  specifies from which image build the container. I have specified the latest version. You can pick any supported node version by the Docker from the [image repository](https://hub.docker.com/_/node/).
`WORKDIR` - sets the location in the image where the app's code will live.
`COPY` - copy all the source code to the image directory.
`RUN` - the command will run the image filesystem, which reads the package.json to determine and install dependencies.
`CMD` - metadata, that describes, how the container should run. Make sure to have a script `start` in your package.json file, that specifies how the app will start (e.x. `"script": "node index.js"`).

Now that Dockerfile is setup, we need to run a command from the terminal to build the image and give it a name optionally with the flag `-t`:

```
docker build -t hello-docker .
```
The dot at the end of the command line specifies the path to Dockerfile.

## Running a Container

After the image is built, we can start a container from it with the following terminal command:

```
docker run -p 8000:3000 hello-docker
```
`-p` option will bind an app port 3000 to your localhost 8000.
`hello-docker` is the image name to run a container from.

Now you should see a printed message that `Server started and listening on port 3000!` and test the Express route with the terminal command `curl localhost:8000`.

## Running on a Server 

To run an app on a server, you can rebuild the image there, save it as a file from your local machine with the Docker save and put it on the server, or publish to the Docker registry.s

That's it. Now you have a running app with the same runtime environment, no matter which machine it is running on.