Ultimate Guide: NestJS Dockerfile for Production [2022] (2023)

Ultimate Guide: NestJS Dockerfile for Production [2022] (1)Ultimate Guide: NestJS Dockerfile for Production [2022] (2)

This is a step-by-step guide to writing a Dockerfile for a NestJS project that creates a production-optimized image.

Then it's configured with this Dockerfilelocal developmentas well as deployment in containers, for example withrun in the cloud.

Set up? let's go diving

PS: If you just want to copy-paste the production-ready Dockerfile, just go ahead with thisSection.

Ultimate Guide: NestJS Dockerfile for Production [2022] (3)

Get a free NestJS cheat sheetGet access to my free NestJS cheat sheet and learn advanced tips and techniques to improve developer workflow and NestJS applications in production.

index
  • Writing the Dockerfile
  • Test the container locally
  • Optimize the Dockerfile for production
  • Using images of alpine knots
  • Add a NODE_ENV environment variable
  • Use npm ci instead of npm install
  • USER Declaration
  • Using Layered Builds
  • put it all together
  • Troubleshooting
  • Error: Could not find module 'webpack'
  • Error: nest command not found
  • Dockerfile with pnpm package manager
  • NestJS Dockerfile con Fastify
  • Conclution

Writing the Dockerfile

A container image is an isolated software package that contains everything you need to run your code. You can define container images by writing aDockerfilecontaining the instructions for creating the image.

Now let's add the Dockerfile:

toqueDockerfile

And then we add the instructions to the Dockerfile. See the comments that explain each step:

Dockerfile

# basic imageVONus: 18# Create application directoryWORKED/usr/src/application# Use a wildcard to ensure that "package.json" and "package-lock.json" are copiedCOPY OFPackage*.json ./# Install application dependenciesCORREinstall npm# Source of the package applicationCOPY OF. .# Create a "dist" folder with the production buildCORREnpm-Run-Create# Start the server with the production buildCMD["That","dist/principal.js"]

resembling a.ignore.gitfile we can add a.dockerignoreFile that prevents certain files from being included in the image build.

(Video) Getting production ready. Create docker image for NestJS app. NestJs course [pt. 8]

toque.dockerignore

Then exclude the following files from imaging:

.dockerignore

Dockerfile.dockerignorenode_modulesnpm-debug.logDistance

Test the container locally

Now let's test locally that the Dockerfile behaves as expected.

First, let's create the image using your terminal command in the root of your project (you can change itnest-cloud-runwith the name of your project). don't forget those.!

stevedorecompile -t nest-cloud-run.

You can verify that the image was created by runningdockable imagesThis will produce a list of Docker images you have on your local machine:

stevedorePhotosREPOSITORY TAG ID SIZE OF CREATED IMAGEnest-cloud-run spätestens 004f7f22213931seconds before10,24 GB

Now, let's start the container and run the image with this command (make sure to use the same image name as above):

stevedorerun -p80:3000 nest-cloud-run

You can now access the NestJS application by visitinghttp://localhostin your browser (onlyhttp://localhostno port numbers).

While running the container, I ran into some problems on my computer, mainly due to port conflicts on other containers I was running.

If you encounter similar problems, try running the commanddocker rm -f $(docker ps -aq)which stops and kills all running containers.

Optimize the Dockerfile for production

Now that we've confirmed that the image works locally, let's try to reduce the size of the image and make it more efficient for production. We also want to make sure that the image is as safe as possible.

Deployment tools like Cloud Run take image size into account when calculating charges, so it's a good idea to keep the image size as small as possible.

Running the commanddockable imagesgives us the size of our image:

(Video) How to setup a local development for NestJS projects with PostgreSQL using Docker Compose

stevedorePhotosREPOSITORY TAG ID SIZE OF CREATED IMAGEnest-cloud-run spätestens 004f7f22213931seconds before10,24 GB

1.24 GB is too big! Let's dive back into ourDockerfileand make some adjustments.

Using images of alpine knots

That's itrecommendedto use images of alpine knots when trying to optimize image size. Wearus: 18-alpineInstead ofus: 18It single-handedly reduces the image size from 1.24 GB to 466 MB.

Add a NODE_ENV environment variable

Many libraries have built-in optimizations when theNODE_ENVThe environment variable is set toProduction, so we can set this environment variable on the Dockerfile build by adding the following line to our Dockerfile:

ENVProduction NODE_ENV

By the way, checkit's tutorialif you are interested in using environment variables with configuration files in NestJS.

Use npm ci instead of npm install

npm recommends using itI like youInstead ofinstall npmin building your image. Here is a quote fromyour websiteto the reason:

"I like youThis is similar toinstall npm, except that it's designed to be used in automated environments such as test platforms, continuous integration, and deployment, or in any situation where you want to make sure you're doing a clean install of your dependencies.

This fits perfectly with what we're doing, so let's use it.I like youInstead ofinstall npmin our dockerfile.

CORREI like you

USER statement

By default, if youOF THE USERstatement in your Dockerfile, the image will run with root privileges. This is a security risk, so let's add oneOF THE USERInstructions for our Dockerfile.

The node image we are using already has a username created for us.that, then we use this:

OF THE USERthat

as long as you use themCOPY OFIt's also a good idea to add a flag to ensure the user has the correct permissions.

You can achieve this using--chown=it:itas long as you use themCOPY statement, for example:

COPY OF --chown=that thatPackage*.json ./

Using Layered Builds

In your Dockerfile you can definemulti-level structuresThis allows you to sequentially create the most optimized image by creating multiple images.

(Video) NestJS Crash Course - Build a Complete Backend API

In addition to using a small image, multi-stage builds are where the biggest optimizations can be made.

Dockerfile

################### BUILD FOR LOCAL DEVELOPMENT##################VONus: 18-alpineSedeveloping# ... your build instructions for development here################### BUILD FOR PRODUCTION################### Base image for productionVONus: 18-alpineSebuild up# ... your build instructions here################### PRODUCTION################### Base image for productionVONus: 18-alpineSeProduction# ... here are your production instructions

This multi-stage construction uses 3 stages:

  1. developing- This is the stage where we build the image for local development.
  2. build up- This is the stage where we create the image for production.
  3. Production- We copy the relevant production build files and start the server.

If you're not interested in using Docker to run your NestJS application locally, you can combine step 1 and step 2 into one phase.

However, the beauty of the multi-step setup above is that you have a single Dockerfile that you can use in local development (combined with adocker-compose.ymlfile) and also creates a production-optimized Docker image.

If you're interested in using this Dockerfile layered with Docker Compose for local development (with hot reload), take a lookthis post.

put it all together

Using all the techniques described above, here is the Dockerfile we will use to build our production-optimized image:

Dockerfile

################### BUILD FOR LOCAL DEVELOPMENT##################VONus: 18-alpineSedeveloping# Create application directoryWORKED/usr/src/application# Copy the application dependency manifests to the container image.# A wildcard is used to ensure that "package.json" and "package-lock.json" (if available) are copied.# Copying this first will prevent npm installation from being rerun every time the code changes.COPY OF --chown=that thatPackage*.json ./# Install the application dependencies using the "npm ci" command instead of "npm install".CORREI like you# Source of the package applicationCOPY OF --chown=that that. .# Use image node user (instead of root user)OF THE USERthat################### BUILD FOR PRODUCTION##################VONus: 18-alpineSebuild upWORKED/usr/src/applicationCOPY OF --chown=that thatPackage*.json ./# To run "npm run build", we need access to the Nest CLI, which is a developer dependency. In the development phase above, we ran `npm ci` which installed all the dependencies so we could copy the node_modules directory from the development imageCOPY OF --chown=that that --von=developing/usr/src/app/node_modules ./node_modulesCOPY OF --chown=that that. .# Run the build command that creates the production packageCORREnpm-Run-Create# set the environment variable NODE_ENVENVProduction NODE_ENV# Running `npm ci` removes the existing node_modules directory and passing --only=production ensures that only production dependencies are installed. This ensures that the node_modules directory is as optimized as possible.CORREnpm ci --only=producción && npm cache clean --forceOF THE USERthat################### PRODUCTION##################VONus: 18-alpineSeProduction# Copy the packaged code from the build phase to the production imageCOPY OF --chown=that that --von=build up/usr/src/app/node_modules ./node_modulesCOPY OF --chown=that that --von=build up/usr/src/app/dist./dist# Start the server with the production buildCMD["That","dist/principal.js"]

After updating yourDockerfile, you need to run the commands again to create your image:

stevedorecompile -t nest-cloud-run.

And then the command to start your container:

stevedorerun -p80:3000 nest-cloud-run

when you walkdockable imagesTo check the size of our image again, you'll notice that it's now significantly smaller:

stevedorePhotosREPOSITORY TAG ID SIZE OF CREATED IMAGEnest-cloud-run spätestens 004f7f22213931Seconds before 189 MB

Troubleshooting

You may encounter the following errors:

(Video) How To Create Docker Image For NestJS App | Multi-Stage Build

Error: Could not find module 'webpack'

You are probably using the wrong node version in your base image if you get errors like the following:

  • Error: Could not find module 'webpack'

For example, instead of usingDE us: 14-alpine, useDE us: 18-alpineto solve this problem.

Error: nest command not found

when you runnpm-Run-Create, use the Nest CLI to generate the build files.

Nest CLI is a developer dependency. So if you get the errornest command not found, you should:

  • (Recommended Option): Runnpm-Run-Createin a multi-tier Dockerfile setup where you can add production and development dependencies (usingI like you)
  • Update your package.json file to include the Nest CLI package in your production dependencies. The only downside to this approach is that it increases the size of your node_modules, which results in a larger image.

The recommended option is the one implemented in the Dockerfile mentioned earlier in this tutorial if you want an example of how it works.

Dockerfile with pnpm package manager

If you use pnpm as a package manager in your NestJS project, the Dockerfile should look like this:

Dockerfile

################### BUILD FOR LOCAL DEVELOPMENT##################VONus: 18SedevelopingCORREcurl -f https://get.pnpm.io/v6.16.js | no - add --global pnpmWORKED/usr/src/applicationCOPY OF --chown=that thatpnpm-lock.yaml ./CORRElook for pnpm --prodCOPY OF --chown=that that. .CORREinstall pnpmOF THE USERthat################### BUILD FOR PRODUCTION##################VONus: 18Sebuild upCORREcurl -f https://get.pnpm.io/v6.16.js | no - add --global pnpmWORKED/usr/src/applicationCOPY OF --chown=that thatpnpm-lock.yaml ./COPY OF --chown=that that --von=developing/usr/src/app/node_modules ./node_modulesCOPY OF --chown=that that. .CORREpnpm-buildENVProduction NODE_ENVCORREpnpm install --prodOF THE USERthat################### PRODUCTION##################VONus: 18-alpineSeProductionCOPY OF --chown=that that --von=build up/usr/src/app/node_modules ./node_modulesCOPY OF --chown=that that --von=build up/usr/src/app/dist./distCMD["That","dist/principal.js"]

NestJS Dockerfile con Fastify

If you are using Fastify as your server in NestJS instead of the default Express server, you need to change the server to be listed.0.0.0.0.

For example, I would edit theEar()paper inprincipal.tsFile, Archive:

principal.ts

to import {nest factory} Von '@nestjs/núcleo';to import {Fastify Adapter,Nest Fastify app,} Von '@nestjs/platform-fastify';to import {application module} Von './aplicación.módulo';asynchronous occupation Ear() { untilApplication= expectnest factory.cry<Nest Fastify app>(application module, nuevo Fastify Adapter(), ); expectApplication.I'm listening(process.environment.PORTA || 3000, '0.0.0.0');}Ear();

This is noticeable insideFastify-Documentsif you want to read more about it.

Conclution

In summary, here is our production-optimized Docker image for a NestJS project (without explanatory comments):

Dockerfile

################### BUILD FOR LOCAL DEVELOPMENT##################VONus: 18-alpineSedevelopingWORKED/usr/src/applicationCOPY OF --chown=that thatPackage*.json ./CORREI like youCOPY OF --chown=that that. .OF THE USERthat################### BUILD FOR PRODUCTION##################VONus: 18-alpineSebuild upWORKED/usr/src/applicationCOPY OF --chown=that thatPackage*.json ./COPY OF --chown=that that --von=developing/usr/src/app/node_modules ./node_modulesCOPY OF --chown=that that. .CORREnpm-Run-CreateENVProduction NODE_ENVCORREnpm ci --only=producción && npm cache clean --forceOF THE USERthat################### PRODUCTION##################VONus: 18-alpineSeProductionCOPY OF --chown=that that --von=build up/usr/src/app/node_modules ./node_modulesCOPY OF --chown=that that --von=build up/usr/src/app/dist./distCMD["That","dist/principal.js"]

Here are some additional resources related to production deployment that you may find useful:

(Video) NestJS Setup, docker-compose and Database Connection | NestJS & Angular | Task Management App 01

  • Using the NestJS Logger
  • Add a CI pipeline with some automated unit tests
  • Deploy the NestJS app to Cloud Run

Do you have any other tweaks I can make to the docker image above? Write them in the comments below!

FAQs

How do I deploy NestJS app to production? ›

Deploying a NestJS app to Cloud Run with Github Actions
  1. Prerequisites.
  2. Start a NestJS project.
  3. Configure a PORT environment variable.
  4. Prepare the Docker image.
  5. Test the container locally.
  6. Manually deploying to Cloud Run.
  7. Check your gcloud CLI project is set.
  8. Use gcloud run deploy.
May 28, 2022

What is the best practice for Dockerfile? ›

Using a minimal base image:

It is generally recommended to use a minimal base image, such as Alpine Linux, as a starting point for building a Docker image. This can help to reduce the size and complexity of the final image, leading to better performance and faster build times.

Should you use the same Dockerfile for Dev staging and production builds? ›

Multiple Dockerfiles

Staging and production should be using the same image, built from the same Dockerfile to guarantee that they are as-similar-as-possible.

How to deploy Docker image to production? ›

Deploy your app
  1. Build images.
  2. Run your image as a container.
  3. Use containers for development.
  4. Run tests.
  5. Configure CI/CD.
  6. Deploy your app.

How do I Dockerize a NestJS project? ›

How to write a NestJS Dockerfile optimized for production
  1. Writing the Dockerfile.
  2. Test the container locally.
  3. Optimize Dockerfile for production.
  4. Use Alpine node images.
  5. Add a NODE_ENV environment variable.
  6. Use npm ci instead of npm install.
  7. The USER instruction.
  8. Use multistage builds.
Dec 5, 2022

Are companies using NestJS? ›

326 companies reportedly use NestJS in their tech stacks, including kevin., MAK IT, and quero.

How to use Docker in production environment? ›

Adopting Docker in a Production Environment: Enterprise Considerations
  1. Constantly Changing Technology Ecosystem. ...
  2. Enforcing Policy and Controls. ...
  3. Deploying Containers Across Environments. ...
  4. Start Small. ...
  5. Use Docker Hosting Services. ...
  6. Use a Private Image Registry and Scan Images. ...
  7. Docker Monitoring and Logging.

When should you not use Docker? ›

Docker is great for developing web applications, but if your end-product is a desktop application, then we would suggest you not to use Docker. As it doesn't provide the environment for running the software with a graphical interface, you would need to perform additional workarounds.

Do I need to build Docker every time? ›

You only need to build the image once, and use it until the installed dependencies (like Python packages) or OS-level package versions need to be changed. Not every time your code is modified. Just because you're mounting the code directory, does not mean you can't ADD code to the image.

Is Dockerfile deprecated? ›

The post quickly allayed fears with a TL;DR: "Docker as an underlying runtime is being deprecated in favor of runtimes that use the Container Runtime Interface (CRI) created for Kubernetes.

Is it OK to use Docker in production? ›

- Docker integrates perfectly with the concept of DevOps, especially in the area of versioning: development and production are carried out in the same container. Put simply, if the application works on the Dev side, it will also work on the Ops side.

Can you have 2 Dockerfiles? ›

Introduction. Docker is a handy tool for containerization. It's so useful that sometimes, we want to have more than one Dockerfile in the project. Unfortunately, this goes against the straightforward convention of naming all Dockerfiles just “Dockerfile”.

Can you publish a port in a Dockerfile? ›

You can expose a port through your Dockerfile or use --expose and then publish it with the -P flag. This will bind the exposed port to your Docker host on a random port (verified by running docker container ls ). You can expose a port through your Dockerfile or use --expose and then publish it with the -p 80:80 flag.

How do you deploy a project to production? ›

With that in mind, let's talk about some ways to smoothly deploy to production without risking quality.
  1. Automate As Much As Possible. ...
  2. Build and Pack Your Application Only Once. ...
  3. Deploy the Same Way All the Time. ...
  4. Deploy Using Feature Flags In Your Application. ...
  5. Deploy in Small Batches, and Do It Often.
Mar 13, 2018

What is JWT in NestJS? ›

JWT or JSON Web Token is an industry standard RFC 7519 method for representing claims securely between two parties. Passport is the most popular Node authentication library, well-known by the community and successfully used in many production application, NestJS has supported it outside the box with @nestjs/passport.

What ORM does NestJS use? ›

For integrating with SQL and NoSQL databases, Nest provides the @nestjs/typeorm package. Nest uses TypeORM because it's the most mature Object Relational Mapper (ORM) available for TypeScript. Since it's written in TypeScript, it integrates well with the Nest framework.

Should I Dockerize my application? ›

Docker is very useful for web applications running on a server or console-based software. But if your product is a standard desktop application, especially with a rich GUI, Docker may not be the best choice.

Why not to use NestJS? ›

NestJS is heavily inspired by Angular and the syntax and concepts will transfer easily between the two.
...
Do not use NestJS if:
  • You are building micro-services. ...
  • You have complicated API arguments or responses that need good documentation and validation. ...
  • Your project is a one-off.
Feb 3, 2022

Is NestJS faster than Express? ›

Another use case can be enterprise-level web applications and ecommerce applications. NestJS is better suited for these as it is scalable, well-structured, and great for building large web applications. For building fintech and streaming applications, ExpressJS is better suited.

Is NestJS difficult to learn? ›

NestJS provides very clean and well-documented guides for beginners to build simple to complex applications with the NestJS typescript framework. With the documentation, it's straightforward to get started, and almost all your development questions have already been covered in the documentation.

How do I run NestJS in production mode? ›

6 Answers
  1. pull the required repo into a 'hosted' directory.
  2. check the node version.
  3. install node_modules and build native scripts etc.
  4. build the production distribution.
  5. run the production JS scripts.
Feb 17, 2019

How do you deploy an application to production? ›

Deploy to Production: 5 Tips to Make It Smoother
  1. Automate As Much As Possible. ...
  2. Build and Pack Your Application Only Once. ...
  3. Deploy the Same Way All the Time. ...
  4. Deploy Using Feature Flags In Your Application. ...
  5. Deploy in Small Batches, and Do It Often.
Mar 13, 2018

How do I deploy a Nodejs app to production? ›

To deploy a Node Express Application to Production, you need to follow these steps:
  1. Create a simple Node. ...
  2. Write the Dockerfile and build the Docker image.
  3. Push the Docker image to the GitHub container registry.
  4. Deploy the Dockerized Node. ...
  5. Automate deployment with GitHub Actions.
Jun 21, 2021

How do you deploy code into production? ›

  1. Introduction.
  2. Basic tips.
  3. Deployment requirements.
  4. Step 1: get the code in the deployment branch.
  5. Step 2: get the code on the deployment host.
  6. Step 3: configuration and other prep work.
  7. Step 4: synchronize the changes to the cluster.
  8. Test and monitor your live code.

Videos

1. Docker Course 2022 - The Complete Guide #docker
(Bitfumes)
2. Nestjs Full Course 2022 | Beginner Nestjs Tutorial
(Bitfumes)
3. NestJS in 100 Seconds
(Fireship)
4. NestJs Course for Beginners - Create a REST API
(freeCodeCamp.org)
5. Building and deploying Next.js applications with Docker
(Docker)
6. Your DOCKER NextJS IMAGE SUCKS! Optimize it! | HOW TO
(Daniel Laera)
Top Articles
Latest Posts
Article information

Author: Barbera Armstrong

Last Updated: 07/26/2023

Views: 6794

Rating: 4.9 / 5 (79 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Barbera Armstrong

Birthday: 1992-09-12

Address: Suite 993 99852 Daugherty Causeway, Ritchiehaven, VT 49630

Phone: +5026838435397

Job: National Engineer

Hobby: Listening to music, Board games, Photography, Ice skating, LARPing, Kite flying, Rugby

Introduction: My name is Barbera Armstrong, I am a lovely, delightful, cooperative, funny, enchanting, vivacious, tender person who loves writing and wants to share my knowledge and understanding with you.