dockerfile bash 107 lines · 2 tabs

Docker image optimization and security scanning

Ryan Nakamura Feb 2026
2 tabs
# Optimized production Dockerfile

# Stage 1: Dependencies
FROM node:20-alpine AS deps
WORKDIR /app

# Install only production dependencies
COPY package.json package-lock.json ./
RUN npm ci --only=production &&     npm cache clean --force

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

COPY package.json package-lock.json ./
RUN npm ci

COPY tsconfig.json ./
COPY src/ ./src/

RUN npm run build &&     rm -rf src tsconfig.json

# Stage 3: Production
FROM node:20-alpine AS production

# Security: add non-root user
RUN addgroup -g 1001 -S nodejs &&     adduser -S appuser -u 1001 -G nodejs

# Security: remove unnecessary packages
RUN apk --no-cache add dumb-init &&     rm -rf /var/cache/apk/*

WORKDIR /app

# Copy production dependencies
COPY --from=deps --chown=appuser:nodejs /app/node_modules ./node_modules

# Copy built application
COPY --from=builder --chown=appuser:nodejs /app/dist ./dist
COPY --from=builder --chown=appuser:nodejs /app/package.json ./

# Security: read-only filesystem
RUN mkdir -p /app/tmp && chown appuser:nodejs /app/tmp

USER appuser

ENV NODE_ENV=production
EXPOSE 3000

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

# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]
2 files · dockerfile, bash Explain with highlit

Optimized Docker images reduce build time, storage, and attack surface. Alpine-based images start at 5MB versus 100MB+ for Debian. Multi-stage builds separate build tools from runtime—final image contains only production artifacts. Layer ordering matters: copy dependency files first, then source code, maximizing cache hits. Use COPY --from=builder to extract built artifacts. RUN instructions should be combined with && to reduce layers. .dockerignore excludes node_modules, .git, and test files. Pin exact package versions for reproducibility. Run containers as non-root with USER directive. Use docker scout or trivy for vulnerability scanning. HEALTHCHECK enables container health monitoring. Image size directly impacts deployment speed and cold start time.


Related snips

Share this code

Here's the card — post it anywhere.

Docker image optimization and security scanning — share card
Link copied