Docker for Production: Complete Guide to Containerizing Web Applications
Jenkins
Source: Dev.to | Jan 04, 2026 (UTC)
Docker has revolutionized how we deploy applications. This comprehensive guide covers everything from basic containerization to production-ready deployments with security best practices and orchestration strategies.
Understanding Docker Architecture
Before diving into production configurations, understand Docker’s core components:
Docker Engine – The runtime that builds and runs containers
Images – Read-only templates containing application code and dependencies
Containers – Running instances of images
Volumes – Persistent data storage
Networks – Communication between containers
Containers share the host OS kernel, making them lightweight compared to virtual machines while providing process isolation.
Multi-Stage Builds for Production
Multi-stage builds create smaller, more secure production images:
Node.js Application
# Stage 1: Dependencies FROM node:20-alpine AS deps WORKDIR /app COPY package*.json ./ RUN npm ci --only=production # Stage 2: Build FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Stage 3: Production FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production # Create non-root user RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs # Copy only necessary files COPY --from=deps /app/node_modules ./node_modules COPY --from=builder /app/dist ./dist COPY --from=builder /app/package.json ./ USER nextjs EXPOSE 3000 CMD ["node", "dist/main.js"]
Enter fullscreen mode
Exit fullscreen mode
PHP/Laravel Application
# Stage 1: Composer dependencies FROM composer:2 AS vendor WORKDIR /app COPY composer.json composer.lock ./ RUN composer install \ --no-dev \ --no-scripts \ --no-autoloader \ --prefer-dist COPY . . RUN composer dump-autoload --optimize # Stage 2: Frontend assets FROM node:20-alpine AS frontend WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # Stage 3: Production image FROM php:8.3-fpm-alpine AS production # Install PHP extensions RUN apk add --no-cache \ libpng-dev \ libzip-dev \ && docker-php-ext-install \ pdo_mysql \ gd \ zip \ opcache # Configure OPcache for production RUN echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini \ && echo "opcache.memory_consumption=256" >> /usr/local/etc/php/conf.d/opcache.ini \ && echo "opcache.max_accelerated_files=20000" >> /usr/local/etc/php/conf.d/opcache.ini \ && echo "opcache.validate_timestamps=0" >> /usr/local/etc/php/conf.d/opcache.ini WORKDIR /var/www/html # Copy application COPY --from=vendor /app/vendor ./vendor COPY --from=frontend /app/public/build ./public/build COPY . . # Set permissions RUN chown -R www-data:www-data storage bootstrap/cache USER www-data EXPOSE 9000 CMD ["php-fpm"]
Enter fullscreen mode
Exit fullscreen mode
Always run containers as non-root users in production. This limits the potential damage from container escapes.
# Using Docker Scout docker scout cves myapp:latest # Using Trivy trivy image myapp:latest # Using Snyk snyk container test myapp:latest
Enter fullscreen mode
Exit fullscreen mode
Secure Dockerfile Practices
# Use specific version tags, not 'latest' FROM node:20.10.0-alpine3.18 # Don't store secrets in images # Use build arguments for build-time secrets ARG NPM_TOKEN RUN echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc \ && npm ci \ && rm .npmrc # Use COPY instead of ADD (ADD can fetch remote URLs) COPY package*.json ./ # Set proper file permissions RUN chmod -R 755 /app # Use read-only root filesystem where possible # (configure in docker-compose or runtime) # Don't run as root USER node # Use HEALTHCHECK HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:3000/health || exit 1
# Order layers from least to most frequently changed FROM node:20-alpine WORKDIR /app # System dependencies (rarely change) RUN apk add --no-cache dumb-init # Package files (change occasionally) COPY package*.json ./ RUN npm ci --only=production # Application code (changes frequently) COPY . . ENTRYPOINT ["dumb-init", "--"] CMD ["node", "dist/main.js"]
Docker enables consistent, reproducible deployments across environments. By following these production best practices—multi-stage builds, security hardening, proper networking, and CI/CD integration—you can build robust containerized applications ready for scale.
Key takeaways:
Use multi-stage builds for smaller, secure images
Never run containers as root in production
Implement health checks and resource limits
Scan images for vulnerabilities regularly
Use proper logging and monitoring
For further actions, you may consider blocking this person and/or reporting abuse
Залишити відповідь