Skip to content

feat(generator): generate Docker artifacts for NestJS #16

Description

@dev-queiroz

Summary

Generate production-ready Dockerfile and docker-compose.yml for containerized NestJS deployment.

Motivation

To be truly "generated and runnable", applications must work in containers. This feature generates all Docker artifacts so developers can deploy with docker-compose up.

Scope

In Scope

  • Multi-stage Dockerfile (build + runtime stages)
  • docker-compose.yml with NestJS + PostgreSQL
  • Environment variable configuration
  • Health check in docker-compose
  • Volume mounts for development (live reload)
  • .dockerignore file
  • Production-ready image (minimal, non-root user)
  • Can run with docker-compose up immediately

Out of Scope

  • Kubernetes manifests (future)
  • CI/CD pipeline generation
  • Docker registry configuration
  • Secrets management

Acceptance Criteria

  • Dockerfile generated with multi-stage build
  • Base image: node:20-alpine (production), node:20 (dev)
  • Non-root user created in Dockerfile
  • docker-compose.yml generated with services: app + postgres
  • PostgreSQL image: postgres:15-alpine
  • Health check defined in docker-compose
  • Environment variables passed to app container
  • Volume mounts for development (src/ mounted)
  • .dockerignore excludes node_modules, dist, .env
  • Build succeeds: docker-compose build
  • App starts: docker-compose up
  • Database accessible from app container
  • Health endpoint returns 200 from container

Files to Create/Modify

  • packages/generators/src/nest/templates/Dockerfile.template (NEW)
  • packages/generators/src/nest/templates/docker-compose.template.yml (NEW)
  • packages/generators/src/nest/templates/.dockerignore (NEW)
  • packages/generators/src/nest/generator.ts (MODIFY)
  • tests/docker-generation.test.mjs (NEW)

Example Output

Dockerfile

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY .env.example .env
USER nodejs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\
  CMD node -e \"require('http').get('http://localhost:3000/health', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})\"
CMD [\"node\", \"dist/main.js\"]

docker-compose.yml

version: '3.8'
services:
  app:
    build: .
    ports:
      - \"3000:3000\"
    environment:
      NODE_ENV: development
      DATABASE_URL: postgresql://postgres:postgres@postgres:5432/forge
    depends_on:
      - postgres
    volumes:
      - ./src:/app/src
      - /app/node_modules
    healthcheck:
      test: [\"CMD\", \"curl\", \"-f\", \"http://localhost:3000/health\"]
      interval: 30s
      timeout: 10s
      retries: 3

  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: forge
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Test Strategy

  • Generate Docker artifacts from contract
  • Build Docker image: docker build -t forge-app .
  • Verify image builds successfully
  • Start with docker-compose: docker-compose up
  • Verify app accessible on port 3000
  • Verify database connectivity from app
  • Test health endpoint returns 200
  • Verify volume mounts work (live reload ready)
  • Verify clean shutdown on SIGTERM

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions