Docker Security Best Practices
Secure your containers from development to production. Common mistakes and how to fix them.
Security Best Practices
Use Minimal Base Images
Start with minimal images like Alpine or distroless. Less software = smaller attack surface.
Don't Run as Root
Containers running as root can escape to host. Always use a non-root user.
Scan Images for Vulnerabilities
Base images and dependencies may have known CVEs. Scan before deploying.
Never Store Secrets in Images
Secrets in Dockerfiles or images persist in layers and can be extracted.
Use Multi-Stage Builds
Keep build tools out of production images. Reduces size and attack surface.
Common Dockerfile Mistakes
ENV API_KEY=sk-xxxFix: Pass secrets at runtime: docker run -e API_KEY=$API_KEY
FROM node:latestFix: Pin specific versions: FROM node:20.11-alpine
No USER directiveFix: Add: RUN adduser -D appuser && USER appuser
EXPOSE 22 (SSH in container)Fix: Only expose ports your app needs. Never SSH into containers.
COPY . .Fix: Use .dockerignore. Copy only what's needed.
Secure Dockerfile Template
# Use specific version, minimal base FROM node:20.11-alpine AS builder WORKDIR /app # Copy package files first (cache dependencies) COPY package*.json ./ RUN npm ci --only=production # Copy source code COPY src/ ./src/ # Build RUN npm run build # Production stage - minimal image FROM node:20.11-alpine # Create non-root user RUN addgroup -S appgroup && adduser -S appuser -G appgroup WORKDIR /app # Copy only production artifacts COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules # Set ownership and switch to non-root RUN chown -R appuser:appgroup /app USER appuser # Don't run as PID 1 CMD ["node", "dist/index.js"]
This template demonstrates: minimal base images, multi-stage builds, non-root user, and proper layer ordering.
Secure Your Containerized Apps
VAS scans your deployed applications for security issues— including exposed secrets that might have leaked from Docker images.
Get Starter ScanFrequently Asked Questions
Is Docker secure by default?
No. Docker provides isolation but defaults aren't hardened. Containers run as root by default, images may have vulnerabilities, and secrets can leak into layers. You need to actively implement security practices—use non-root users, scan images, and properly manage secrets.
Can containers escape to the host?
Yes, especially if running as root or with privileged mode. Container escapes are real vulnerabilities. Mitigate by: never using --privileged, running as non-root, keeping Docker updated, and using security tools like AppArmor or seccomp profiles.
How do I handle secrets in Docker?
Never put secrets in Dockerfiles or images. Options: Docker secrets (Swarm), Kubernetes secrets, environment variables at runtime (not build time), or secret managers like Vault, AWS Secrets Manager. For development, use .env files that aren't copied into images.
Should I use Alpine or Distroless?
Alpine is good for most use cases—small but has a shell for debugging. Distroless is more secure (no shell, minimal binaries) but harder to debug. Start with Alpine, consider distroless for high-security production workloads where you don't need shell access.
How often should I rebuild images?
At minimum, weekly to pick up security patches in base images. Better: trigger rebuilds when base images update. Use tools like Dependabot or Renovate to track base image updates. Critical CVEs should trigger immediate rebuilds.
Related Resources
Last updated: January 16, 2026