Docker for Developers: From Development to Production
A practical guide to containerizing your applications with Docker, setting up CI/CD pipelines, and deploying to production.
Why Docker
Docker eliminates the "works on my machine" problem. Every developer on your team runs the same environment. Your CI/CD pipeline builds once and deploys everywhere. Production matches development.
Essential Docker Concepts
Images
Read-only templates containing your application code, runtime, libraries, and dependencies. Think of them as snapshots of your application.
Containers
Running instances of images. Containers are lightweight, isolated, and disposable. Start one in seconds, stop it without affecting others.
Dockerfile
A text file containing instructions to build your image. Each instruction creates a layer in the image. Understanding layer caching is key to building efficient Dockerfiles.
Writing Better Dockerfiles
Use Multi-Stage Builds
Separate your build environment from your runtime. This reduces image size dramatically:
# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
# Runtime stage
FROM node:20-slim
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]Leverage Layer Caching
Order your Dockerfile instructions from least to most frequently changing. Dependencies rarely change — copy and install them before copying your source code.
Use .dockerignore
Exclude unnecessary files from your build context. Node modules, git directories, and documentation shouldn't be in your image.
Docker Compose for Development
Docker Compose lets you define multi-service environments in a single file:
services:
app:
build: .
ports:
- "3000:3000"
depends_on:
- database
- redis
database:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7One command starts your entire development environment — application, database, cache, and any other services.
Production Deployment
Health Checks
Always define health checks in your Dockerfile or Compose file. This allows orchestrators to restart unhealthy containers automatically.
Resource Limits
Set memory and CPU limits. Prevent one container from consuming all resources and affecting others.
Logging
Write logs to stdout/stderr. Let Docker handle log collection and rotation. This works with any container orchestration platform.
CI/CD Integration
Build images in your CI pipeline, tag them with the commit SHA, and push to a container registry. Deploy by pulling the new image and restarting the container. Rollbacks become as simple as deploying the previous tag.
