DEV Community

Brandon Benefield
Brandon Benefield

Posted on

How to Dockerize an ExpressJS Application

What this is

  • This is a short example on how to Dockerize an ExpressJS application.
  • This post also assumes you are working from a *NIX based OS such as Ubuntu 18.10

What this is not

  • This is not a thorough guide on Docker, NodeJS, ExpressJS, or any other technologies that may be used.
  • This does not explain or walk you through the installation process of Docker or any technologies used.

Create Directory

We need to create a directory. This is where we are going to place all of our Docker Images' files as well as our ExpressJS files.

foo@foo:~/path/to/current/directory$ mkdir node_docker_project

Create Dockerfile

CD into the new directory and create a new file and name it Dockerfile without any extension name.

foo@foo:~/path/to/current/directory$ cd node_docker_project
foo@foo:~/node_docker_project$ touch Dockerfile

Place the next piece of code inside of the Dockerfile.

# Tell Docker to use the "node" Docker Image at version "10.15.3"
FROM node:10.15.3
# Create our containers WORKDIR and "node_modules" directory.
# Give the user:group "node" ownership of all files/directories in our containers WORKDIR
RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app
# Tell our container which directory to use as the WORKDIR
WORKDIR /home/node/app
# Copy over our local version of "package.json" and "package-lock.json" into our container
COPY package*.json ./
# Creates a user for our container
USER node
# Installs our NPM packages from the "package.json" file we moved from local in to our container
RUN npm install
# Tells our container who owns the copied content
COPY --chown=node:node . .
# Exposes the port "3000" from our container
# This is also how we can connect to our container from our host machine (the one you're reading this from now)
EXPOSE 3000
# An array of commands our container needs to run when we start it
CMD ["npm", "run", "start"]

Create app.js

const express = require('express')
const app = express()
app.get('/', (req, res) => {
  res.send('Hello, world!')
})
app.listen(3000, () => console.log('Server listening @ 3000'))

Create package.json

Let's create our package.json file to hold our dependencies.

foo@foo:~/node_docker_project$ npm init -y

Then we need to install those dependencies.

foo@foo:~/node_docker_project$ npm i express
foo@foo:~/node_docker_project$ npm i --save-dev nodemon

We need Express as that is going to be the framework we are using for our server and we need Nodemon so that we can have automatic server restart by default. This will come in handy as you change files from local to the container. Without Nodemon, you would need to restart your container every time you make a change just to see the changes.

Create our Docker Image

Think of a Docker Image as the recipe and a Docker Container as the meal. In order to eat the meal we need to cook it using a recipe.

foo@foo:~/node_docker_project$ docker build -t node_project
foo@foo:~/node_docker_project$ docker images
REPOSITORY     TAG      IMAGE ID     CREATED          SIZE
node_project   latest   3esadssa     10 Seconds Ago   908MB

foo@foo:~/node_docker_project$ docker run --name myNodeProject -v $(pwd):/home/node/app -d -p 3000:3000 node_project
foo@foo:~/node_docker_project$ docker ps
CONTAINER ID  IMAGE         COMMAND          CREATED
123klasdkj    node_project  "npm run start"  6 seconds ago

STATUS        PORTS                   NAMES
Up 4 seconds  0.0.0.0:3000->3000/tcp  myNodeProject

Check your work

Now that we've created our container and it's up and running, we are able to connect to our container via the opened port(s). In our case we opened one port at 3000.

Open your browser and navigate to http://localhost:3000 and you should be greeted with our Hello, World! message that we place in the app.get('/' ...) request in the app.js file we created earlier.

Check that we can change the container files from our host machine

Go ahead and change the response text in our app.js file from Hello, World! to Docker is amazing!.

const express = require('express')
const app = express()
app.get('/', (req, res) => {
  res.send('Docker is amazing!')  // change this line
})
app.listen(3000, () => console.log('Server listening @ 3000'))

Back in your browser, either refresh with f5 or navigate back to http://localhost:3000 and you should see the new response.


Summary

The basics of Docker is actually pretty simple. All you need to do is:

  • Get a Docker Image
  • Create a Docker Container
  • Connect to your container via the opened port(s)

Resources

Top comments (2)

Collapse
 
albglhk profile image
al-bglhk

You might have forgotten what command(s) need to be set in scripts.start. By default (npm init -y), it's not even defined. I could only assume the npm run start script command should be nodemon node app.js.

Collapse
 
geekhart profile image
George Kephart

I agree this would not work unless npm run start was defined in the package.json that was not shared.