Skip to content
← Back to blog
DockerNestJSAngularDevOps

Docker Compose for NestJS + Angular Development

Firas Sayah·May 10, 2026·5 min read

One Command to Rule Them All

New developer joins the team. They clone the repo, run docker compose up, and everything works. No installing PostgreSQL, no configuring Redis, no version mismatches. That is the promise of Docker Compose, and it is essential for any serious SaaS development workflow.

The Complete docker-compose.yml

version: '3.8'

services:
  api:
    build:
      context: .
      dockerfile: apps/api/Dockerfile
      target: development
    volumes:
      - ./apps/api/src:/app/apps/api/src
      - ./libs:/app/libs
    ports:
      - '3000:3000'
      - '9229:9229' # Debug port
    environment:
      - DATABASE_URL=postgres://postgres:postgres@db:5432/saas
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    command: npx nx serve api

  web:
    build:
      context: .
      dockerfile: apps/web/Dockerfile
      target: development
    volumes:
      - ./apps/web/src:/app/apps/web/src
    ports:
      - '4200:4200'
    command: npx nx serve web

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: saas
    ports:
      - '5432:5432'
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U postgres']
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - '6379:6379'
    volumes:
      - redisdata:/data

volumes:
  pgdata:
  redisdata:

Cloudrix SaaS Starter ships with this pre-configured and tested.

Skip weeks of boilerplate — auth, payments, multi-tenancy, and deployment included out of the box.

Try the live demo →

Multi-Stage Dockerfiles

Use multi-stage builds to keep images small in production while supporting hot reload in development:

# Base stage
FROM node:20-alpine AS base
WORKDIR /app
COPY package.json pnpm-lock.yaml ./
RUN corepack enable && pnpm install --frozen-lockfile

# Development stage
FROM base AS development
COPY . .
EXPOSE 3000 9229

# Production stage
FROM base AS production
COPY . .
RUN pnpm nx build api --configuration=production
CMD ["node", "dist/apps/api/main.js"]

The target: development in docker-compose.yml tells Docker to stop at the development stage, giving you hot reload via volume mounts.

Hot Reload with Volume Mounts

The key to a good developer experience is fast feedback. Mount your source directories as volumes so changes are reflected instantly:

volumes:
  - ./apps/api/src:/app/apps/api/src

NestJS's file watcher detects the changes and rebuilds. Angular's dev server does the same. No container restart needed.

Environment Variables

Never hard-code configuration. Use a .env file for local development:

DATABASE_URL=postgres://postgres:postgres@db:5432/saas
REDIS_URL=redis://redis:6379
JWT_SECRET=local-dev-secret
STRIPE_SECRET_KEY=sk_test_...

Reference it in docker-compose.yml:

env_file:
  - .env

Health Checks and Startup Order

PostgreSQL takes a few seconds to accept connections. Without a health check, your API container will crash on startup. The healthcheck and depends_on with condition: service_healthy in the compose file solves this cleanly.

Adding More Services

As your SaaS grows, add services to the same compose file:

  maildev:
    image: maildev/maildev
    ports:
      - '1080:1080' # Web UI
      - '1025:1025' # SMTP

  minio:
    image: minio/minio
    command: server /data --console-address ":9001"
    ports:
      - '9000:9000'
      - '9001:9001'

MailDev catches all outgoing emails locally. MinIO provides S3-compatible storage. Both eliminate the need for external service accounts during development.

Production vs Development

Create a separate docker-compose.prod.yml that overrides development settings:

services:
  api:
    build:
      target: production
    volumes: [] # No source mounts
    restart: unless-stopped

Deploy with docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d.

SaaS Starter includes a production-ready Docker setup. See the deployment feature for details.

Get Started Today

All of these patterns are fully implemented in SaaS Starter. Skip 2-6 weeks of setup.

F

Firas Sayah

Senior Software Engineer

Full-stack developer with 5+ years building production SaaS applications with NestJS and Angular.