Skip to content

Production-ready Next.js Docker template with multi-stage builds, security hardening, and performance optimizations.

License

Notifications You must be signed in to change notification settings

nooblk-98/nextjs-docker-template

Repository files navigation

Next.js-docker logo

Next.js Docker Template

Production-ready Next.js Docker template with multi-stage builds, security hardening, and performance optimizations.

CI/CD Docker Security Next.js License Last Commit Contributions Welcome

Features

Security First

  • Non-root user (UID 1001) - Prevents privilege escalation
  • Read-only filesystem - Blocks malware installation
  • Dropped Linux capabilities - Minimal permissions
  • Security headers - HSTS, CSP, X-Frame-Options, X-XSS-Protection
  • SSL/TLS ready - Nginx reverse proxy with HTTPS
  • Rate limiting - DDoS protection (10 req/s)
  • No new privileges - Prevents container breakout

Performance Optimized

  • Multi-stage Docker build - smaller images
  • Standalone Next.js output - Minimal runtime dependencies
  • Layer caching - Faster rebuilds
  • Alpine Linux - Lightweight base
  • SWC minification - Faster builds
  • Gzip compression - Reduced bandwidth usage
  • Static asset caching - 1-year cache for immutable files

Developer Friendly

  • Hot reload - Development mode with volume mounts
  • TypeScript - Full type safety
  • Tailwind CSS - Utility-first styling
  • ESLint - Code quality
  • CI/CD ready - GitHub Actions workflow included

pre Requirements !?

Standalone Next.js Build

The template uses Next.js standalone output mode which is already activated in next.config.js:

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Enable standalone output for Docker optimization
  output: 'standalone', 

Quick Start

Use with your own code

# Download Dockerfile (prod)
wget https://raw.githubusercontent.com/nooblk-98/nextjs-docker-template/refs/heads/main/Dockerfile
# Download Docker Compose  (prod)
wget https://raw.githubusercontent.com/nooblk-98/nextjs-docker-template/refs/heads/main/docker-compose.yml

workflow

wget https://raw.githubusercontent.com/nooblk-98/nextjs-docker-template/refs/heads/main/.github/workflows/docker-build.yml

Build & Push Workflow

The template includes a GitHub Actions workflow for automated building and pushing to Docker Hub:

Build Workflow

health check API

# place this under /src/app/api/health/route.ts

wget https://raw.githubusercontent.com/nooblk-98/nextjs-docker-template/refs/heads/main/src/app/api/health/route.ts

Use with your own code

# Download Dockerfile (dev)
wget https://raw.githubusercontent.com/nooblk-98/nextjs-docker-template/refs/heads/main/Dockerfile.dev
# Download Docker Compose  (dev)
wget https://raw.githubusercontent.com/nooblk-98/nextjs-docker-template/refs/heads/main/docker-compose.dev.yml

Docker Development (Hot Reload)

docker-compose -f docker-compose.dev.yml up

Production Build

docker-compose up -d

🐳 Docker Commands

Production

# Build production image
docker build -t nextjs-app:latest .
# Run production container
docker run -p 3000:3000 nextjs-app:latest
# Using Docker Compose
docker-compose up -d                  # Start in background
docker-compose down                   # Stop and remove
docker-compose logs -f                # Follow logs
docker-compose ps                     # Show status
docker-compose restart                # Restart services

Development

# Build development image
docker build -f Dockerfile.dev -t nextjs-app:dev .
# Run development container with hot reload
docker-compose -f docker-compose.dev.yml up
# Stop development containers
docker-compose -f docker-compose.dev.yml down

Useful Commands

# View container logs
docker logs -f nextjs-production

# Execute command in container
docker exec -it nextjs-production sh

# Check container health
docker inspect --format='{{.State.Health.Status}}' nextjs-production

# View resource usage
docker stats nextjs-production

# Remove all stopped containers
docker container prune

# Remove unused images
docker image prune -a

βš™οΈ Configuration

Environment Variables

  1. Copy the example file:
cp .env.example .env.local
  1. Edit .env.local with your values:
NODE_ENV=production
PORT=3000
NEXT_TELEMETRY_DISABLED=1

# Add your custom variables
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
API_KEY=your-api-key-here
NEXT_PUBLIC_API_URL=https://api.example.com
  1. Update next.config.js if needed:
env: {
  DATABASE_URL: process.env.DATABASE_URL,
  API_KEY: process.env.API_KEY,
}

Node.js Version

The Node.js version is configurable via build arguments:

Method 1: Docker Compose (Recommended)

Edit docker-compose.yml or docker-compose.dev.yml:

build:
  args:
    NODE_VERSION: 20  # Change to 18, 20, 21, etc.

Method 2: Docker Build Command

# Build with specific Node.js version
docker build --build-arg NODE_VERSION=18 -t nextjs-app:latest .

# Or use Node.js 21
docker build --build-arg NODE_VERSION=21 -t nextjs-app:latest .

Method 3: Environment Variable

# Set environment variable
export NODE_VERSION=18

# Build
docker-compose build

SSL/TLS Configuration

For development, generate self-signed certificates:

# Linux/Mac
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout nginx/ssl/key.pem \
  -out nginx/ssl/cert.pem \
  -subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

# Windows (PowerShell)
# Use start.bat option 4 to auto-generate

For production, use Let's Encrypt or your certificate authority.

πŸ” Security Features

Container Security

Non-Root User

RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 nextjs
USER nextjs

Read-Only Filesystem

read_only: true
tmpfs:
  - /tmp:noexec,nosuid,size=100m
  - /app/.next/cache:noexec,nosuid,size=500m

Dropped Capabilities

cap_drop:
  - ALL
cap_add:
  - NET_BIND_SERVICE

Application Security

Security headers configured in next.config.js:

  • Strict-Transport-Security: Forces HTTPS
  • X-Frame-Options: Prevents clickjacking
  • X-Content-Type-Options: Prevents MIME sniffing
  • X-XSS-Protection: Browser XSS protection
  • Referrer-Policy: Controls referrer information
  • Permissions-Policy: Restricts browser features

Network Security

Nginx provides:

  • SSL/TLS termination
  • Rate limiting (10 req/s)
  • Gzip compression
  • Static asset caching
  • Security headers

🌐 Deployment

Request Flow

Client Request
  ↓
Nginx (Port 443)
  β”œβ”€β†’ SSL Termination
  β”œβ”€β†’ Rate Limit Check
  β”œβ”€β†’ Security Headers
  └─→ Gzip Compression
  ↓
Next.js (Port 3000)
  β”œβ”€β†’ Static Files β†’ Serve from .next/static
  β”œβ”€β†’ API Route β†’ Execute handler
  β”œβ”€β†’ SSR Page β†’ Render on server
  └─→ SSG Page β†’ Serve pre-rendered HTML
  ↓
Response to Client

πŸ› Troubleshooting

Container Won't Start

# Check logs
docker logs nextjs-production

# Inspect container
docker inspect nextjs-production

# Check health status
docker inspect --format='{{.State.Health.Status}}' nextjs-production

Permission Issues

# Ensure files are accessible to UID 1001
chown -R 1001:1001 /path/to/files

Build Failures

# Clear Docker cache
docker builder prune -a

# Rebuild without cache
docker build --no-cache -t nextjs-app:latest .

Hot Reload Not Working

# Ensure volume mounts are correct in docker-compose.dev.yml
volumes:
  - .:/app
  - /app/node_modules
  - /app/.next

# Set polling environment variables
environment:
  - WATCHPACK_POLLING=true
  - CHOKIDAR_USEPOLLING=true

🀝 Contributing

Contributions are welcome!

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

⭐ Show Your Support

If this template helped you, please give it a star! ⭐


Made with ❀️ by NoobLK

⬆ Back to top

About

Production-ready Next.js Docker template with multi-stage builds, security hardening, and performance optimizations.

Topics

Resources

License

Stars

Watchers

Forks