From Chaos to Containers

Docker uses containers to simplify the process of creating, deploying, and running applications. With containers, a developer can pull together an application with all of its dependencies and ship it as one package.

Think of Docker containers like perfectly packed care packages - everything your application needs is bundled together in one tidy container, ready to run anywhere! In this guide, I'll walk you through creating and running a simple Docker image of a Node.js application (aka "Dockerizing"). ๐Ÿ“ฆโœจ

What You'll Need

๐Ÿณ

Docker Installed

First, you'll need to install Docker on your system.

๐Ÿ“ฑ

Node.js Application

A Node.js app to containerize. Don't have one? You can fork the saySomething NodeOnlyVersion branch.

๐Ÿ’ป

Command Line Access

These code snippets work in bash. If you're using a different shell, you may need to adjust commands accordingly.

Let's Start Dockerizing!

1

Create the Dockerfile

In your main application folder, create the Dockerfile. This file contains instructions to help Docker create an image of your Node.js application.

$ cd saySomething
$ touch Dockerfile
2

Set the Base Image

Edit the Dockerfile and add the base image. We'll use the official Node.js image as our foundation.

FROM node:boron
3

Create Working Directory

Add instructions for Docker to create and set the working directory for the container.

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
4

Install Dependencies

The node:boron image comes with Node.js and NPM already installed. Now we install your application dependencies.

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
5

Bundle Application Source

Docker needs to bundle your application's source code inside the Docker image using the COPY instruction.

# Bundle app source
COPY . /usr/src/app
6

Expose Port (Optional)

By default, Docker exposes port 80. If needed, use an EXPOSE instruction for additional ports.

# Expose a port
EXPOSE 8081
7

Define Entry Point

Finally, Docker needs instruction on what to execute when the image launches. Since our start instructions are in package.json, we'll call the start command.

ENTRYPOINT [ "npm", "start" ]

The Complete Dockerfile

Putting it all together, your final Dockerfile should look like this:

FROM node:boron

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8081

ENTRYPOINT [ "npm", "start" ]

Note: You can remove the EXPOSE line if you don't need to expose a specific port.

Build Your Docker Image

๐Ÿ—๏ธ Build the Image

Now that you have the instructions in place, you can build your Docker image. Move to the directory containing the Dockerfile and run:

$ docker build -t <your-username>/<your-node-app-name> .

Replace <your-username> with your username and <your-node-app-name> with your app name.

๐Ÿ“‹ Verify the Image

Your new image should now appear in the Docker image list:

$ docker images

๐Ÿš€ Run Your Container

Test your containerized application by running it:

$ docker run -p 8081:8081 <your-username>/<your-node-app-name>

Grandma's Docker Wisdom

๐Ÿ“ฆ

Package.json First

Copy package.json before copying your entire app - this way Docker can cache the npm install step and speed up subsequent builds!

๐Ÿ”ง

Layer Optimization

Order your Dockerfile commands from least to most frequently changed. This maximizes Docker's layer caching benefits.

๐Ÿšช

Port Mapping

Don't forget to map your container port to a host port when running (using the -p flag) so you can access your application!

๐Ÿงน

Clean Builds

Use a .dockerignore file to exclude unnecessary files (like node_modules, .git) from your Docker context for faster builds.