webdev

Docker 101: From Development to Production – A Quick Guide

Docker has fundamentally transformed the way developers build, test, and deploy applications by introducing a consistent, lightweight, and portable runtime environment. With its ability to package applications and their dependencies into isolated containers, Docker has eliminated the age-old challenge of “it works on my machine” while enabling seamless deployment across various environments. The part of “It’s working for me” used to be funny or sad depends on the day and the hour…

Whether you’re developing locally, testing in a CI/CD pipeline, or deploying to production, Docker provides the flexibility and scalability to streamline these processes. In this guide, we’ll explore the foundational concepts of Docker, dive into its practical uses, and demonstrate how you can harness its power to simplify workflows and achieve greater efficiency in your development and operations pipelines. Whether you’re a beginner or looking to refine your Docker skills, this walkthrough will equip you with the knowledge you need to use Docker effectively.

What is Docker?

Docker is a platform that packages applications and their dependencies into lightweight, portable containers. These containers can run consistently across any environment that has Docker installed.

Basic Docker Concepts

Images and Containers

  • Image: A blueprint that contains everything needed to run an application
  • Container: A running instance of an image
  • Dockerfile: A script containing instructions to build an image

Key Commands

# Pull an image
docker pull nginx

# Run a container
docker run nginx

# List running containers
docker ps

# Stop a container
docker stop container_id

### How to get 'clean' quickly
# Remove all containers first (force stop and remove)
docker container stop $(docker container ls -aq)
docker container prune -f

# Remove all images (including those in use)
docker rmi -f $(docker images -q)

Development Environment Setup

Let’s create a simple Node.js application and containerize it.

  1. Create a Dockerfile:
FROM node:22-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000
CMD ["npm", "start"]
  1. Create a .dockerignore:
node_modules
npm-debug.log
  1. Use Docker Compose for local development. Create docker-compose.yml:
version: '3'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    volumes:
      - .:/app
      - /app/node_modules
    environment:
      - NODE_ENV=development

Development Best Practices

  • Use volumes to mount source code for hot reloading
  • Keep development dependencies separate
  • Use environment variables for configuration

Testing Environment

Create a separate Docker configuration for testing:

# Dockerfile.test
FROM node:22-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

CMD ["npm", "test"]

Run tests in a containerized environment:

docker build -f Dockerfile.test -t myapp-test .
docker run myapp-test

Testing Best Practices

  • Use multi-stage builds to keep test dependencies separate
  • Run tests in isolation
  • Set up CI/CD pipelines with Docker

Production Environment

Create an optimized production build:

# Dockerfile.prod
FROM node:22-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm install

COPY . .
RUN npm run build

FROM node:22-alpine

WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY package*.json ./
RUN npm install --only=production

EXPOSE 3000
CMD ["npm", "start"]

Production Best Practices

  1. Security:
  • Use specific image versions
  • Run containers as non-root
  • Scan images for vulnerabilities
   docker scan myapp:latest
  1. Performance:
  • Use multi-stage builds
  • Minimize image layers
  • Only install production dependencies
  1. Monitoring:
   # Check container resource usage
   docker stats

   # View container logs
   docker logs container_id

Deployment Example

Deploy to production using Docker Compose:

version: '3'
services:
  app:
    image: myapp:latest
    restart: always
    ports:
      - "80:3000"
    environment:
      - NODE_ENV=production
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

Deployment Best Practices

  • Use container orchestration (Kubernetes/Swarm)
  • Implement health checks
  • Set up proper logging
  • Use secrets management
  • Configure automatic restarts

Common Docker Commands Reference

# Build an image
docker build -t my-fe-app .

# Run container in detached mode
docker run -d my-fe-app

# View logs
docker logs -f container_id

# Execute command in running container
docker exec -it container_id sh

# Remove unused resources
docker system prune

Cheat Sheet

Docker Commands Cheat Sheet – Most Useful Commands 🌻

Container Management

  1. Run a container
docker run [OPTIONS] IMAGE [COMMAND]
# Example: Run nginx in detached mode with port mapping
docker run -d -p 80:80 nginx
  1. List containers
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
  1. Stop container
docker stop [CONTAINER_ID/NAME]
  1. Remove container
# Remove a stopped container
docker rm [CONTAINER_ID/NAME]
# Force remove a running container
docker rm -f [CONTAINER_ID/NAME]
  1. Execute command in container
docker exec -it [CONTAINER_ID/NAME] [COMMAND]
# Example: Open shell in container
docker exec -it my-container bash

Image Management

  1. Build image
docker build -t [NAME:TAG] .
# Example: Build with specific Dockerfile
docker build -f Dockerfile.prod -t myapp:prod .
  1. List images
docker images
  1. Remove image
docker rmi [IMAGE_ID/NAME]
  1. Pull image
docker pull [IMAGE_NAME]:[TAG]
  1. Push image
docker push [IMAGE_NAME]:[TAG]

Container Information

  1. View container logs
docker logs [CONTAINER_ID/NAME]
# Follow log output
docker logs -f [CONTAINER_ID/NAME]
  1. Container resource usage
docker stats [CONTAINER_ID/NAME]
  1. Inspect container
docker inspect [CONTAINER_ID/NAME]

Network Management

  1. List networks
docker network ls
  1. Create network
docker network create [NETWORK_NAME]
  1. Connect container to network
docker network connect [NETWORK_NAME] [CONTAINER_ID/NAME]

Volume Management

  1. Create volume
docker volume create [VOLUME_NAME]
  1. List volumes
docker volume ls
  1. Remove volume
docker volume rm [VOLUME_NAME]

Docker Compose

  1. Start services
docker-compose up
# Detached mode
docker-compose up -d
  1. Stop services
docker-compose down
  1. View service logs
docker-compose logs [SERVICE_NAME]

System Management

  1. System information
docker info
  1. Clean up system
# Remove unused resources
docker system prune
# Remove all unused images
docker system prune -a
  1. View disk usage
docker system df

Advanced Commands

  1. Export container
docker export [CONTAINER_ID] > container.tar
  1. Import container
docker import container.tar [IMAGE_NAME]
  1. Save image
docker save [IMAGE_NAME] > image.tar
  1. Load image
docker load < image.tar
  1. View container changes
docker diff [CONTAINER_ID/NAME]

Useful Options for docker run

Common options you can add to docker run:

-d              # Run in detached mode
-p HOST:CONTAINER  # Port mapping
-v HOST:CONTAINER  # Volume mounting
--name          # Assign container name
--rm            # Remove container when stopped
-e KEY=VALUE    # Set environment variables
--network       # Connect to network
--restart       # Restart policy

Example with multiple options:

docker run -d \
  --name my-app \
  -p 3000:3000 \
  -v $(pwd):/app \
  -e NODE_ENV=production \
  --restart always \
  my-app:latest

Conclusion

Docker provides a consistent environment across development, testing, and production. By following these best practices and examples, you can create a robust containerization strategy for your applications.

Remember to:

  • Keep development and production configurations separate
  • Optimize for security and performance in production
  • Use Docker Compose for managing multi-container applications
  • Implement proper monitoring and logging
  • Regular security scanning and updates
  • Have fun

Start small with a single container and gradually expand your Docker usage… Or walk before you run.

Be strong.


Discover more from Ido Green

Subscribe to get the latest posts sent to your email.

Standard