Cloud & DevOps14 min read660 words

Docker Container Best Practices 2026: Production-Ready Containers

Master Docker for production deployments. Learn Dockerfile optimization, security hardening, multi-stage builds, and container orchestration best practices.

DK

David Kumar

Containers are the foundation of modern deployment. Building production-ready Docker images requires attention to security, performance, and maintainability. This guide covers essential practices for container excellence.

Optimized Multi-Stage Builds

dockerfile
# Production-ready Node.js Dockerfile
# Stage 1: Dependencies
FROM node:20-alpine AS deps
WORKDIR /app

# Install dependencies only when needed
COPY package.json pnpm-lock.yaml ./
RUN corepack enable pnpm && pnpm install --frozen-lockfile

# Stage 2: Build
FROM node:20-alpine AS builder
WORKDIR /app

COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Build application
RUN corepack enable pnpm && pnpm build

# Prune dev dependencies
RUN pnpm prune --prod

# Stage 3: Production
FROM node:20-alpine AS runner
WORKDIR /app

# Security: Create non-root user
RUN addgroup --system --gid 1001 nodejs && \
    adduser --system --uid 1001 appuser

# Set environment
ENV NODE_ENV=production
ENV PORT=3000

# Copy only production files
COPY --from=builder --chown=appuser:nodejs /app/dist ./dist
COPY --from=builder --chown=appuser:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:nodejs /app/package.json ./

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD node -e "require('http').get('http://localhost:3000/health', (r) => process.exit(r.statusCode === 200 ? 0 : 1))"

# Start application
CMD ["node", "dist/index.js"]

Security Hardening

dockerfile
# Security-focused Dockerfile
FROM node:20-alpine AS base

# Update packages and install security updates
RUN apk update && apk upgrade && \
    # Remove unnecessary packages
    apk del --purge apk-tools && \
    # Remove caches
    rm -rf /var/cache/apk/* /tmp/*

# Don't run as root
RUN addgroup -g 1001 -S appgroup && \
    adduser -u 1001 -S appuser -G appgroup

# Set restrictive permissions
RUN chmod 755 /app

USER appuser

# Prevent privilege escalation
# In docker-compose.yml or k8s manifest:
# security_context:
#   run_as_non_root: true
#   run_as_user: 1001
#   read_only_root_filesystem: true
#   allow_privilege_escalation: false
#   capabilities:
#     drop:
#       - ALL
yaml
# docker-compose.yml with security options
version: '3.8'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    read_only: true
    tmpfs:
      - /tmp
    user: "1001:1001"
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 128M
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Image Optimization

dockerfile
# Optimized Python Dockerfile
FROM python:3.12-slim AS base

# Prevent Python from writing pyc files and buffering stdout/stderr
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1

FROM base AS builder

# Install build dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Create virtual environment
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Install dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

FROM base AS production

# Copy virtual environment from builder
COPY --from=builder /opt/venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Create non-root user
RUN useradd --create-home --shell /bin/bash appuser
WORKDIR /home/appuser/app

# Copy application code
COPY --chown=appuser:appuser . .

USER appuser

EXPOSE 8000

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:app"]

Scanning and Testing

bash
# Scan images for vulnerabilities

# Using Trivy (recommended)
trivy image --severity HIGH,CRITICAL myapp:latest

# Using Snyk
snyk container test myapp:latest

# Using Docker Scout
docker scout cves myapp:latest

# Lint Dockerfiles
hadolint Dockerfile

# Scan for secrets in image
trufflehog docker --image myapp:latest

# Check image size and layers
docker history myapp:latest
dive myapp:latest  # Interactive layer explorer

Best Practices Summary

Docker Best Practices Checklist

Build:

- Use multi-stage builds to minimize image size

- Pin specific base image versions

- Order layers from least to most frequently changed

- Use .dockerignore to exclude unnecessary files

Security:

- Never run as root in production

- Scan images for vulnerabilities regularly

- Use read-only root filesystem where possible

- Drop all capabilities and add only what's needed

Performance:

- Use slim/alpine base images when possible

- Combine RUN commands to reduce layers

- Leverage BuildKit cache mounts

- Use HEALTHCHECK for proper orchestration

Conclusion

Production-ready containers require attention to security, size optimization, and proper configuration. These practices ensure your containers are secure, efficient, and maintainable in production environments.

Need help with container strategy? Contact Jishu Labs for expert DevOps consulting and container optimization.

DK

About David Kumar

David Kumar is the DevOps Lead at Jishu Labs with extensive experience in containerization and cloud infrastructure.

Related Articles

Ready to Build Your Next Project?

Let's discuss how our expert team can help bring your vision to life.

Top-Rated
Software Development
Company

Ready to Get Started?

Get consistent results. Collaborate in real-time.
Build Intelligent Apps. Work with Jishu Labs.

SCHEDULE MY CALL