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!
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
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
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
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
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
Expose Port (Optional)
By default, Docker exposes port 80. If needed, use an EXPOSE instruction for additional ports.
# Expose a port
EXPOSE 8081
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.