Streamlining Development with Docker: A Complete Workflow
Docker has revolutionized how we develop, test, and deploy applications. This guide shows you how to create an efficient development workflow using Docker containers.
Why Docker for Development?
Docker solves the "it works on my machine" problem by ensuring consistent environments across development, testing, and production.
Benefits:
- Consistency: Same environment everywhere
- Isolation: No dependency conflicts
- Portability: Works on any Docker-enabled system
- Scalability: Easy to scale services
Setting Up Your Development Environment
Basic Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Docker Compose for Multi-Service Apps
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
depends_on:
- database
database:
image: postgres:15
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
Development Best Practices
Multi-Stage Builds
Optimize your images with multi-stage builds:
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine AS production
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
CMD ["npm", "start"]
Development vs Production Configs
Use different Docker Compose files:
# docker-compose.dev.yml
version: '3.8'
services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
Docker Commands Cheat Sheet
Essential commands for daily development:
# Build and run
docker-compose up --build
# Run in background
docker-compose up -d
# View logs
docker-compose logs -f app
# Execute commands in container
docker-compose exec app npm install
# Stop all services
docker-compose down
# Clean up everything
docker system prune -a
Debugging in Docker
Debugging Node.js Applications
# Add debugging support
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000 9229
CMD ["node", "--inspect=0.0.0.0:9229", "index.js"]
Production Deployment
Health Checks
Add health checks to your containers:
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
Security Best Practices
- Use non-root users
- Scan images for vulnerabilities
- Keep base images updated
- Use secrets management
Conclusion
Docker transforms development workflows by providing consistency, isolation, and portability. Start with simple containers and gradually adopt more advanced patterns as your needs grow.
The investment in learning Docker pays dividends in reduced debugging time, easier onboarding, and reliable deployments.