@nesvel/docker-config
v1.0.3
Published
Shared Dockerfile templates and Docker configurations for Node.js applications
Maintainers
Readme
@nesvel/docker-config
Production-ready Dockerfile templates and Docker configurations for Node.js applications.
Features
- 🐳 4 Optimized Templates: Node.js, NestJS, Next.js, and Vite
- 🚀 Multi-stage Builds: Minimal production images
- 🔒 Security First: Non-root users, minimal attack surface
- 📦 Smart Auto-detection: Automatically detects your project type
- ⚡ Performance Optimized: Layer caching, fast builds
- 🛠️ Helper Functions: Generate .dockerignore and docker-compose.yml
Installation
pnpm add -D @nesvel/docker-configQuick Start
Automatic Installation (Recommended)
The smart installer automatically detects your project type and installs the appropriate Dockerfile:
# Auto-detect and install
pnpm docker-install
# Install with docker-compose.yml
pnpm docker-install --compose
# Manual template selection
pnpm docker-install --template=vite
# Install to specific directory
pnpm docker-install --dir=./apps/webAlternatively, use the full path:
npx @nesvel/docker-config installManual Installation
1. Copy Template
Copy the appropriate Dockerfile template for your project:
# Node.js / Express
cp node_modules/@nesvel/docker-config/templates/node.dockerfile Dockerfile
# NestJS
cp node_modules/@nesvel/docker-config/templates/nestjs.dockerfile Dockerfile
# Next.js
cp node_modules/@nesvel/docker-config/templates/nextjs.dockerfile Dockerfile
# Vite / React / Vue
cp node_modules/@nesvel/docker-config/templates/vite.dockerfile Dockerfile2. Create .dockerignore
cat > .dockerignore << 'EOF'
node_modules
dist
build
.next
.git
.env*
!.env.example
EOFTemplates
Node.js
Generic Node.js application template with pnpm.
Best for: Express, Fastify, Koa, custom Node.js servers
Features:
- Multi-stage build (dependencies → builder → runner)
- Alpine Linux (minimal size)
- Non-root user
- Health checks
- Signal handling with dumb-init
- Production dependency pruning
Build & Run:
docker build -f node.dockerfile -t myapp:latest .
docker run -p 3000:3000 myapp:latestNestJS
Optimized for NestJS applications with TypeScript compilation.
Best for: NestJS APIs and microservices
Features:
- TypeScript compilation
- Production dependencies only
- Built-in health check endpoint support
- Proper signal handling
- Minimal image size
Build & Run:
docker build -f nestjs.dockerfile -t nest-api:latest .
docker run -p 3000:3000 nest-api:latestNext.js
Next.js with standalone output mode for minimal bundle size.
Best for: Next.js applications (SSR, SSG, or hybrid)
Features:
- Three-stage build (deps → builder → runner)
- Standalone output (~40MB production image)
- Static asset optimization
- Telemetry disabled
- Fast startup time
Build & Run:
docker build -f nextjs.dockerfile -t next-app:latest .
docker run -p 3000:3000 next-app:latestRequirements:
output: 'standalone'in next.config.js
Vite
Vite SPA served with Nginx.
Best for: React, Vue, Svelte, or vanilla JS SPAs built with Vite
Features:
- Static file serving with Nginx
- SPA routing support (fallback to index.html)
- Gzip compression enabled
- API proxy configuration example
- Minimal image size (~25MB)
- Fast cold starts (<1s)
Build & Run:
docker build -f vite.dockerfile -t vite-app:latest .
docker run -p 80:80 vite-app:latestProgrammatic Usage
TypeScript/JavaScript API
import {
templates,
generateDockerignore,
generateComposeService
} from '@nesvel/docker-config';
// List available templates
console.log(templates);
// {
// node: { name: 'node', path: 'templates/node.dockerfile', ... },
// nestjs: { ... },
// nextjs: { ... },
// vite: { ... }
// }
// Generate .dockerignore content
const dockerignore = generateDockerignore([
'*.log',
'tmp/',
]);
// Generate docker-compose service configuration
const service = generateComposeService('nestjs', {
name: 'api',
port: 3001,
environment: {
DATABASE_URL: 'postgres://localhost:5432/db',
},
volumes: ['./uploads:/app/uploads'],
dependsOn: ['postgres', 'redis'],
});Custom Build Scripts
// build-docker.ts
import { templates } from '@nesvel/docker-config';
import { execSync } from 'child_process';
const template = templates.nextjs;
const imageName = 'my-nextjs-app:latest';
console.log(`Building with ${template.name} template...`);
execSync(
`docker build -f ${template.path} -t ${imageName} .`,
{ stdio: 'inherit' }
);Docker Compose Integration
Generate Configuration Programmatically
import { generateComposeService } from '@nesvel/docker-config';
import { writeFileSync } from 'fs';
import YAML from 'yaml';
const services = {
web: generateComposeService('nextjs', {
name: 'web',
port: 3000,
dependsOn: ['api'],
}),
api: generateComposeService('nestjs', {
name: 'api',
port: 3001,
environment: {
DATABASE_URL: 'postgres://db:5432/mydb',
},
dependsOn: ['db'],
}),
db: {
image: 'postgres:16-alpine',
environment: {
POSTGRES_DB: 'mydb',
POSTGRES_PASSWORD: 'password',
},
volumes: ['postgres-data:/var/lib/postgresql/data'],
},
};
const compose = {
version: '3.8',
services,
volumes: { 'postgres-data': null },
};
writeFileSync('docker-compose.yml', YAML.stringify(compose));Manual docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NODE_ENV: production
DATABASE_URL: postgres://db:5432/mydb
depends_on:
- db
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_DB: mydb
POSTGRES_PASSWORD: password
volumes:
- postgres-data:/var/lib/postgresql/data
volumes:
postgres-data:Advanced Usage
Monorepo Setup
For monorepo projects, build from the root and specify the app context:
# Build from monorepo root
docker build \
-f packages/api/Dockerfile \
-t api:latest \
--build-context workspace=. \
.
# Or use docker-compose with build context
services:
api:
build:
context: .
dockerfile: apps/api/DockerfileBuild Arguments
Add custom build arguments to your Dockerfile:
# Add after ARG NODE_VERSION in template
ARG API_URL
ENV NEXT_PUBLIC_API_URL=$API_URLThen build with:
docker build --build-arg API_URL=https://api.example.com -t app:latest .Multi-platform Builds
Build for multiple architectures:
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myapp:latest \
--push \
.Development vs Production
Create separate Dockerfiles:
# Dockerfile.dev
FROM node:22-alpine
WORKDIR /app
RUN corepack enable pnpm
COPY package.json pnpm-lock.yaml ./
RUN pnpm install
COPY . .
CMD ["pnpm", "dev"]# Development
docker-compose -f docker-compose.dev.yml up
# Production
docker-compose -f docker-compose.yml upTypeScript Types
All templates and utilities are fully typed:
import type {
DockerTemplate,
DockerComposeService,
ComposeServiceOptions,
} from '@nesvel/docker-config';
const template: DockerTemplate = {
name: 'custom',
path: 'custom.dockerfile',
description: 'Custom template',
features: ['feature1', 'feature2'],
};
const options: ComposeServiceOptions = {
name: 'api',
port: 3000,
environment: { NODE_ENV: 'production' },
};Best Practices
1. Use .dockerignore
Always create a .dockerignore to reduce build context size:
npx @nesvel/docker-config install # Generates .dockerignore automatically2. Layer Caching
Order Dockerfile commands from least to most frequently changing:
# ✅ Good - Dependencies cached unless package.json changes
COPY package.json pnpm-lock.yaml ./
RUN pnpm install
COPY . .
# ❌ Bad - Cache invalidated on any file change
COPY . .
RUN pnpm install3. Multi-stage Builds
All templates use multi-stage builds to minimize production image size:
- Build stage: Compile TypeScript, bundle assets
- Production stage: Only runtime files, no dev dependencies
4. Security
- Run as non-root user (all templates do this)
- Keep base images updated
- Use specific version tags (not
latest) - Scan images:
docker scan myapp:latest
5. Health Checks
Add health checks for container orchestration:
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"Troubleshooting
Build Fails with "Cannot find module"
Ensure your package.json has a build script:
{
"scripts": {
"build": "tsc" // or "vite build", "next build", etc.
}
}Image Size Too Large
Check for:
- Unused dependencies (use
pnpm install --prod) - Missing
.dockerignore - Not using multi-stage builds
Permission Errors
The templates use non-root users. If you need to write files, ensure directories are writable:
RUN chown -R nodejs:nodejs /app/uploadsPort Already in Use
Map to a different host port:
docker run -p 8080:3000 myapp:latest # Host:ContainerMigration Guide
From Docker Hub Official Images
Replace:
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "start"]With:
npx @nesvel/docker-config install --template=nodeBenefits:
- Production-optimized multi-stage build
- pnpm for faster installs
- Non-root user
- Health checks
- Proper signal handling
Contributing
Contributions welcome! Please read our Contributing Guide.
License
MIT © Nesvel
Related Packages
- @nesvel/typescript-config - Shared TypeScript configurations
- @nesvel/eslint-config - Shared ESLint configurations
- @nesvel/prettier-config - Shared Prettier configurations
