docker-node

Docker (Node.js Containerization)

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "docker-node" with this command: npx skills add petbrains/mvp-builder/petbrains-mvp-builder-docker-node

Docker (Node.js Containerization)

Overview

Docker enables consistent environments for Node.js applications across development, testing, and production. Multi-stage builds reduce image size, docker-compose simplifies local development.

Base Image: node:20-alpine (recommended for small size)

Use case: Deploy TypeScript APIs, ensure consistent environments

Key Benefit: "Works on my machine" → "Works everywhere"

When to Use This Skill

✅ Use Docker when:

  • Deploying to cloud (AWS, GCP, Azure)

  • Need consistent dev environment across team

  • Running CI/CD pipelines

  • Deploying with Kubernetes

  • Need isolated PostgreSQL/Redis for development

❌ Skip Docker when:

  • Simple scripts or CLI tools

  • Serverless deployments (use platform's build)

  • Early prototyping (adds complexity)

Multi-Stage Dockerfile (Production)

Dockerfile

Stage 1: Dependencies

FROM node:20-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci --only=production && npm cache clean --force

Stage 2: Build

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

Stage 3: Production

FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production

Security: non-root user

RUN addgroup -g 1001 -S nodejs &&
adduser -S nodejs -u 1001 -G nodejs

Copy production artifacts

COPY --from=deps --chown=nodejs:nodejs /app/node_modules ./node_modules COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist COPY --from=builder --chown=nodejs:nodejs /app/prisma ./prisma COPY --from=builder --chown=nodejs:nodejs /app/node_modules/.prisma ./node_modules/.prisma

USER nodejs EXPOSE 3000

Run migrations then start

CMD ["sh", "-c", "npx prisma migrate deploy && node dist/index.js"]

Docker Compose (Development)

docker-compose.yml

version: '3.8'

services: app: build: context: . target: builder # Use builder stage for dev ports: - "3000:3000" environment: NODE_ENV: development DATABASE_URL: postgresql://postgres:postgres@postgres:5432/myapp volumes: - ./src:/app/src:delegated # Hot reload - ./prisma:/app/prisma:delegated depends_on: postgres: condition: service_healthy command: npm run dev

postgres: image: postgres:15-alpine environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: myapp ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d myapp"] interval: 5s timeout: 5s retries: 10

redis: image: redis:7-alpine ports: - "6379:6379" volumes: - redis_data:/data

volumes: postgres_data: redis_data:

.dockerignore

Dependencies

node_modules

Build outputs

dist .next

Git

.git .gitignore

Environment

.env .env.* !.env.example

IDE

.vscode .idea

Docker

docker-compose* Dockerfile*

Tests & docs

coverage .md **/.test.ts **/*.spec.ts

OS

.DS_Store Thumbs.db

Commands

Development

Start all services

docker-compose up

Start with rebuild

docker-compose up --build

Start in background

docker-compose up -d

View logs

docker-compose logs -f app

Stop all

docker-compose down

Stop and remove volumes (reset DB)

docker-compose down -v

Production Build

Build production image

docker build -t myapp:latest .

Run container

docker run -p 3000:3000
-e DATABASE_URL="postgresql://..."
-e JWT_SECRET="..."
myapp:latest

Run with env file

docker run -p 3000:3000 --env-file .env.production myapp:latest

Debug

Shell into running container

docker-compose exec app sh

Shell into new container

docker run -it myapp:latest sh

View container processes

docker-compose top

Check image size

docker images myapp

Database Migrations in Docker

Development (Auto-migrate)

docker-compose.yml

app: command: sh -c "npx prisma migrate dev && npm run dev"

Production (Deploy migrations)

In Dockerfile CMD

CMD ["sh", "-c", "npx prisma migrate deploy && node dist/index.js"]

CI/CD Pipeline

Run migrations in separate step

docker run --rm
-e DATABASE_URL="$PROD_DATABASE_URL"
myapp:latest
npx prisma migrate deploy

Health Checks

Application Health

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

Health Endpoint

// src/routes/health.ts app.get('/health', async (req, res) => { try { await prisma.$queryRawSELECT 1; res.json({ status: 'healthy', db: 'connected' }); } catch { res.status(503).json({ status: 'unhealthy', db: 'disconnected' }); } });

Environment Variables

Development

docker-compose.yml

services: app: environment: NODE_ENV: development DATABASE_URL: postgresql://postgres:postgres@postgres:5432/myapp JWT_SECRET: dev-secret-not-for-production

Production

Pass at runtime

docker run -e DATABASE_URL="..." -e JWT_SECRET="..." myapp

Or use env file

docker run --env-file .env.production myapp

Optimization Tips

Reduce Image Size

Use alpine base

FROM node:20-alpine

Clean npm cache

RUN npm ci && npm cache clean --force

Don't install devDependencies in production

RUN npm ci --only=production

Layer Caching

Copy package files first (changes less often)

COPY package*.json ./ RUN npm ci

Then copy source (changes more often)

COPY . . RUN npm run build

Security

Run as non-root

RUN adduser -S nodejs USER nodejs

Don't expose unnecessary ports

EXPOSE 3000

Use specific versions

FROM node:20.10-alpine

Rules

Do ✅

  • Use multi-stage builds for production

  • Run containers as non-root user

  • Use .dockerignore to exclude unnecessary files

  • Add health checks

  • Pin base image versions

  • Use docker-compose for local development

Avoid ❌

  • Running as root in production

  • Storing secrets in Dockerfile

  • Using latest tag in production

  • Including node_modules in image

  • Skipping .dockerignore

Troubleshooting

"Prisma client not generated": → Add RUN npx prisma generate in builder stage → Copy node_modules/.prisma to runner stage

"Permission denied": → Check file ownership with --chown → Ensure USER matches file owner

"Container exits immediately": → Check logs: docker-compose logs app → Verify CMD is blocking (not backgrounded)

"Can't connect to database": → Use service name as host (postgres, not localhost) → Check depends_on with healthcheck → Verify DATABASE_URL uses container network

"Image too large": → Use alpine base image → Add .dockerignore → Use multi-stage builds → Clean npm cache

File Structure

project/ ├── Dockerfile ├── docker-compose.yml ├── .dockerignore ├── .env.example ├── package.json ├── tsconfig.json ├── prisma/ │ └── schema.prisma └── src/ └── index.ts

References

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

frontend-magic-ui

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-google-fonts

No summary provided by upstream source.

Repository SourceNeeds Review
General

figma-design-extraction

No summary provided by upstream source.

Repository SourceNeeds Review