Docker has made our lives as developers easier. With just a few commands, we can start all kinds of programs and services without having to deal with the tedious installation of dependencies. Countless Docker images are freely available on Docker Hub. Whether you want to start your own open-source continuous integration & deployment server, such as Strider, or your own NPM registry with https://verdaccio.org/, the possibilities are endless.
But these are mostly ready-made Docker images I was talking about. But for your own projects, you have to build your own Docker image. And in this article, I will show and describe in a few words how you can put your next NodeJS application into a Docker image. Here we go.
A simple Dockerfile
looks something like this:
# We use the latest nodejs@14 image as our base image FROM node:14-alpine # set the default NODE_NEV to production ENV NODE ENV=production # make sure everything happens inside the /app folder WORKDIR/app # now we cache the node_modules layer COPY ["package.json", "package-lock.json", "./"] # install your dependencies RUN npm install # copy the source COPY /src . # and start the app CMD ["node", "server. js"]
But what if you need to build the app first before you can run it? Let's take a look at this by using a multi-stage build.
# We make use of ARG to set some variables that we # can use in the Dockerfile ARG node_version=14 ARG node_image=node:${node_version}-alpine # STAGE 1: This is the "builder" stage where we build the # application and give this step a name: "builder" FROM $node_image as builder ENV NODE ENV=production WORKDIR/app COPY ["package.json", "package-lock.json", "./"] # compared to the first example we now install # _all_ dependencies including devDependencies RUN npm install # copy the source COPY /src . # now build the app RUN npm build # STAGE 2: in this stage, we reduce the size of the # image by only installing production dependencies FROM $node_image as production WORKDIR /app/ # install _only production_ dependencies to keep the # docker image small COPY --from=builder /app/package.json /app/package-lock.json ./ RUN npm install --production # copy the build from the first stage (e.g. the dist folder) COPY --from=builder /app/dist ./dist # and start the bundled app CMD ["node", "dist/index. js"]
This is it. You now have the option to choose between a multi-stage or a single-stage Dockerfile for your next project. Of course, we could optimize some things still and apply different approaches, but that's maybe part of another story of my #90DaysOfProse challenge.
Cu,
Stefan
PS: Thanks Oliver for the inspiration for this article.
Top comments (0)