How to Containerize Express.js
This is the third installment of my series, Can You Containerize It? Today, I will be teaching you how to use Docker to containerize an Express.js app! Express is a Node.js framework used to build API's. You can easily scale a containerized API to handle dynamic traffic. You can also take advantage of technologies that allow for zero-downtime deployment and are self-healing! Let's get started.
TLDR: Here is the fulling working code on my Github.
git clone https://github.com/fourgates/blog-express-ts-docker.git cd blog-express-ts-docker/ git checkout part-2-typescript npm i npm run start
You should have express running locally!
server started at http://localhost:8080
Next, let's create a Dockerfile in the root directory of the project (same folder where
package.json is). We will use this to create our "base" image.
FROM node:12 # Create app directory WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json ./ # remove this line if you are not using TypeScript COPY tsconfig.json ./ COPY tslint.json ./ RUN npm install EXPOSE 8080
A couple of notes.
FROM node:12- This is the base image we are using to build our own Express base image.
WORKDIR /usr/src/app- This sets a default directory for the image. Anytime you run a command for this image it will get run in this folder.
COPY- We want to copy dependency related files into our image. We need
nodeknow what dependencies to install when running
npm i. Also, if you are using TypeScript you need to copy the
nodehow to compile your TypeScript and
tslint.jsonto be able to lint your project.
Now that we have instructions for Docker to build a base image. Next, we need to create a
docker-compose.yml file to encapsulate commands for building a base image to develop our code in.
version: '3.7' services: express: build: context: . dockerfile: Dockerfile image: express/builder:0.0.1 container_name: express-container ports: - '8080:8080' volumes: - ./src:/usr/src/app/src command: npm run start
A couple of notes.
version- This is the version of
docker-composeto use. Newer versions add improved capabilities.
services- You can have docker start multiple containers for full-stack applications. A good use case for multiple services would be if you want to start up an Express server and a DynamoDb instance for your local API to interact with.
build- This is the build section of the compose. We are using
contextto point to where the Docker files are located. In this case, they are in the current directory.
dockerfileis used to point to the correct file with instructions on how to build the image.
image- This is the name Docker will give to your image once it is created.
container_name- This is the name that is used for the container when the images start.
Build Base Image
Let's build the base image!
Finally, start your server!
docker-compose up dev
express-container | server started at http://localhost:8080
That's it! You can now develop code as you would any other Express app. You don't need to install any dependencies~ There are a few things we can do to improve the build time and image size but I will leave that exercise for a future post. You can also push this image to your favorite Docker repo and use it anywhere you would like. Happy Container, Happy Developer!
Here is the fulling working code on my Github.
Remember to bump the
image version number and push a new base image any time dependencies change! This means anytime you update package.json there needs to be a new base image.
docker ps- This is a useful command to list all running containers.
docker ps -a- List all containers, including those that are not running.