Home / blog / Docker for Beginners: How to Use Docker and Docker Compose in a NestJS Project
Docker for Beginners: How to Use Docker and Docker Compose in a NestJS Project

Docker for Beginners: How to Use Docker and Docker Compose in a NestJS Project

Featured

Docker for Beginners: How to Use Docker and Docker Compose in a NestJS Project

a

admin

Author

20 min read
55 Views
June 21, 2025

A complete beginner-friendly guide to Docker and Docker Compose with a real NestJS example. Learn how to containerize your application, manage environment variables, and use Docker Compose to orchestrate services like PostgreSQL.

If you've ever struggled with setting up and running your project on different machines, or if deploying your app to a server always feels like reinventing the wheel, then you're in the right place. In this blog post, we'll walk through the basics of Docker, why it's such a powerful tool for developers, and how to use it in a real-world NestJS project. We'll also explore how to handle environment variables and introduce Docker Compose to simplify your development workflow.

What is Docker?

Docker is an open-source platform that allows developers to automate the deployment of applications inside lightweight, portable containers. These containers package your application with all its dependencies, libraries, and configuration files, making it easy to run on any system that supports Docker.

Why Docker?

  • Consistency across environments: Run the same code in development, staging, and production.
  • Simplified setup: No need to install Node.js, databases, or other tools manually.
  • Isolation: Keeps your app's dependencies isolated from the host machine.
  • Portability: Run your app on any machine with Docker installed.


Installing Docker

To get started, install Docker from docker.com.

Once installed, verify it's working:

docker --version


Creating a NestJS App (If you don't have one already)

npm i -g @nestjs/cli
nest new my-nest-app
cd my-nest-app


Dockerizing a NestJS App

1. Create a .dockerignore File

node_modules
dist
Dockerfile
docker-compose.yml
.env

Why?

The .dockerignore file works like .gitignore, telling Docker which files/folders to exclude when building the image. This reduces build time and keeps your final image clean from unnecessary files like local dependencies, compiled output, and sensitive configuration files.


2. Create a Dockerfile

# Stage 1: Build
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

# Stage 2: Run
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY .env .
CMD [ "node", "dist/main.js" ]

What is a Dockerfile?

A Dockerfile is a script of instructions on how to build a Docker image. Think of it as a recipe to prepare your app in a container. It tells Docker which base image to use, how to install dependencies, how to build the app, and how to run it.

Explanation of Key Commands:

  • FROM: Sets the base image. We use node:18-alpine for a small, secure Node.js environment.
  • WORKDIR: Defines the working directory inside the container.
  • COPY: Copies files from your project into the container.
  • RUN: Executes shell commands, like installing dependencies or building the project.
  • CMD: The default command to run when the container starts (our NestJS app).
💡 This Dockerfile uses multi-stage builds to keep the final image small by separating the build and run phases.


3. Handling Environment Variables

Make sure your NestJS app uses @nestjs/config:

npm install @nestjs/config

In main.ts or your module:

import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
  ],
})

Add a .env file:

PORT=3000

Read it in your code:

const port = process.env.PORT || 3000;
🔒 Never commit .env to Git. It should stay private and out of version control.


Docker Compose: Simplify Multi-Container Setups

Docker Compose lets you define and run multi-container Docker applications. It's perfect for combining services like your NestJS app + a database.

Example: docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    env_file:
      - .env
    depends_on:
      - db

  db:
    image: postgres:15
    restart: always
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Why use Docker Compose?

Imagine needing to start your backend server, a PostgreSQL database, and maybe a Redis instance — all configured to talk to each other. Docker Compose lets you define all of these in a single file and start them with one command, making local development and production orchestration much simpler.

Then run:

docker-compose up --build

Your NestJS app will start on port 3000 and be connected to a PostgreSQL database container.


Useful Docker Commands

  • Build image: docker build -t my-nest-app .
  • Run container: docker run -p 3000:3000 my-nest-app
  • List containers: docker ps
  • Stop containers: docker-compose down


Visual Overview

NestJS → Compiled → Docker Container → Port 3000 exposed → Connected to DB (Postgres)


Conclusion

Docker simplifies development, improves consistency, and is essential for modern app deployment. By containerizing your NestJS application and using Docker Compose, you reduce setup time, avoid "it works on my machine" issues, and prepare your app for production scalability.

If you're just getting started with backend development or looking to modernize your workflow, learning Docker is an investment that pays off quickly.


Need help setting up Docker for your project? Feel free to reach out or connect with me on LinkedIn.

share this post

Link Copied