Introduction to Docker
In the world of software development, the phrase “it works on my machine” used to be a common, frustrating refrain. This is precisely the problem Docker set out to solve. Introduced in 2013, Docker has revolutionized how applications are built, shipped, and run by leveraging containerization.
Imagine a lightweight, self-contained package that includes everything an application needs to run: its code, runtime, libraries, environment variables, and configuration files. That’s a Docker container. Unlike traditional virtual machines, which include an entire operating system, Docker containers share the host operating system’s kernel. This makes them significantly more efficient in terms of resource consumption and startup time, allowing you to run multiple containers on the same machine without them interfering with each other.
Docker provides a consistent and isolated environment, ensuring that an application runs the same way everywhere – from your development machine to testing environments and production servers. This consistency speeds up development, simplifies deployment, and enhances collaboration across teams.
Docker Cheatsheet
Here’s a quick reference guide for commonly used Docker commands:
General Commands
# Display the Docker version. docker --version # Display system-wide information. docker info # Log in to a Docker registry (e.g., Docker Hub). docker login # Log out from a Docker registry. docker logout
Image Management
# Build a Docker image from a Dockerfile in the current directory. docker build -t <image_name> . # Build an image with a specific tag. docker build -t <image_name>:<tag> . # List all local Docker images. docker images # Pull an image from a registry. docker pull <image_name>:<tag> # Push an image to a registry. docker push <username>/<image_name>:<tag> # Remove a Docker image. docker rmi <image_name> # Remove all dangling (unused) images. docker image prune # Show the history of an image. docker history <image_name>
Container Management
# Create and run a container in detached mode, mapping ports. docker run -d -p <host_port>:<container_port> --name <container_name> <image_name> # Run a container interactively and open a bash shell. docker run -it <image_name> /bin/bash # List running containers. docker ps # List all containers (running and stopped). docker ps -a # Start a stopped container. docker start <container_name_or_id> # Stop a running container. docker stop <container_name_or_id> # Restart a container. docker restart <container_name_or_id> # Remove a stopped container. docker rm <container_name_or_id> # Execute a command inside a running container. docker exec -it <container_name_or_id> <command> # Fetch and follow the logs of a container. docker logs <container_name_or_id> # Display detailed information about a container. docker inspect <container_name_or_id> # Attach to a running container's standard input, output, and error streams. docker attach <container_name_or_id>
Volume Management
# Create a new volume. docker volume create <volume_name> # List all volumes. docker volume ls # Display detailed information about a volume. docker volume inspect <volume_name> # Remove one or more volumes. docker volume rm <volume_name> # Remove all unused volumes. docker volume prune
Network Management
# List all Docker networks. docker network ls # Create a new custom network. docker network create <network_name> # Connect a running container to a network. docker network connect <network_name> <container_name_or_id> # Disconnect a container from a network. docker network disconnect <network_name> <container_name_or_id> # Remove a network. docker network rm <network_name>
Cleaning Up
# Remove all stopped containers, dangling images, unused networks, and dangling build cache. docker system prune # Remove all unused Docker data (stopped containers, all unused images, all networks not used by at least one container, and all build cache). docker system prune -a
Docker RUN Cheatsheet
Basic Syntax
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Essential Options
Container Management
# Run container in background (detached) docker run -d nginx # Run container interactively with terminal docker run -it ubuntu bash # Run container and remove it when it exits docker run --rm hello-world # Name your container docker run --name my-container nginx # Restart policies docker run --restart=always nginx docker run --restart=on-failure nginx docker run --restart=unless-stopped nginx
Port Mapping
# Map container port to host port docker run -p 8080:80 nginx # Map to specific host interface docker run -p 127.0.0.1:8080:80 nginx # Map multiple ports docker run -p 8080:80 -p 8443:443 nginx # Publish all exposed ports to random host ports docker run -P nginx
Volume and Data Management
# Bind mount host directory to container docker run -v /host/path:/container/path nginx # Create named volume docker run -v my-volume:/container/path nginx # Mount current directory docker run -v $(pwd):/app node # Read-only mount docker run -v /host/path:/container/path:ro nginx # Anonymous volume docker run -v /container/path nginx
Environment Variables
# Set single environment variable docker run -e NODE_ENV=production node # Set multiple environment variables docker run -e NODE_ENV=production -e PORT=3000 node # Load environment variables from file docker run --env-file .env node # Pass environment variable from host docker run -e USER=$USER ubuntu
Resource Limits
# Limit memory usage docker run -m 512m nginx # Limit CPU usage (percentage) docker run --cpus="1.5" nginx # Limit CPU cores docker run --cpuset-cpus="0,1" nginx # Set memory and swap limit docker run -m 512m --memory-swap 1g nginx
Networking
# Use specific network docker run --network my-network nginx # Use host network docker run --network host nginx # Disable networking docker run --network none nginx # Add hostname docker run --hostname my-host nginx # Add DNS server docker run --dns 8.8.8.8 nginx # Add host entry docker run --add-host myhost:127.0.0.1 nginx
Security Options
# Run as specific user docker run -u 1000:1000 nginx # Run with specific user name docker run -u myuser nginx # Add capabilities docker run --cap-add SYS_ADMIN nginx # Drop capabilities docker run --cap-drop ALL nginx # Run in privileged mode docker run --privileged nginx # Set security options docker run --security-opt seccomp:unconfined nginx
Working Directory and Entry Point
# Set working directory docker run -w /app node # Override entry point docker run --entrypoint /bin/bash nginx # Override entry point with interactive shell docker run --entrypoint /bin/bash -it nginx
Common Use Cases
Web Applications
# Run Nginx web server docker run -d -p 80:80 --name web-server nginx # Run Node.js app with volume mount docker run -d -p 3000:3000 -v $(pwd):/app node:18 node app.js # Run with environment file docker run -d -p 3000:3000 --env-file .env node:18
Databases
# Run MySQL with persistent data docker run -d \ --name mysql-db \ -e MYSQL_ROOT_PASSWORD=secret \ -e MYSQL_DATABASE=myapp \ -v mysql-data:/var/lib/mysql \ -p 3306:3306 \ mysql:8.0 # Run PostgreSQL docker run -d \ --name postgres-db \ -e POSTGRES_PASSWORD=secret \ -e POSTGRES_DB=myapp \ -v postgres-data:/var/lib/postgresql/data \ -p 5432:5432 \ postgres:15 # Run Redis docker run -d --name redis-cache -p 6379:6379 redis:7
Useful Combinations
Complete Web Application Stack
# Full-featured web application docker run -d \ --name my-web-app \ --restart unless-stopped \ -p 8080:80 \ -v $(pwd)/html:/usr/share/nginx/html:ro \ -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \ -e NGINX_HOST=localhost \ -e NGINX_PORT=80 \ --health-cmd="curl -f http://localhost" \ --health-interval=30s \ nginx:alpine
Development Environment
# Development container with volume mounts docker run -it \ --name dev-env \ --rm \ -v $(pwd):/workspace \ -w /workspace \ -p 3000:3000 \ -e NODE_ENV=development \ node:18-alpine \ sh
Docker Compose Cheatsheet
Docker Compose is a tool for defining and running multi-container Docker applications. You define your application’s services in a docker-compose.yml
file, and then with a single command, you can spin up everything.
General Commands
docker-compose --version # Display the Docker Compose version. docker-compose config # Validate and view the Compose file configuration.
Project Management (from the directory containing docker-compose.yml
)
docker-compose up # Build, (re)create, start, and attach to containers for a service. docker-compose up -d # Run containers in detached mode (in the background). docker-compose up --build -d # Build images before starting containers and detached mode. docker-compose down # Stop and remove containers, networks, images, and volumes. docker-compose down --volumes # Also remove named volumes declared in the volumes section of the Compose file. docker-compose start [service_name...] # Start existing containers for a service. docker-compose stop [service_name...] # Stop running containers for a service without removing them. docker-compose restart [service_name...] # Restart containers for a service. docker-compose ps # List containers for a service. docker-compose logs [service_name...] # View output from containers. docker-compose logs -f # Follow log output. docker-compose build [service_name...] # Build or rebuild services. docker-compose pull [service_name...] # Pull service images. docker-compose exec <service_name> <command> # Execute a command in a running container. docker-compose run <service_name> <command> # Run a one-off command on a service (starts a new container).
Example docker-compose.yml
Structure
version: '3.8' # Specify the Compose file format version services: web: # Service name build: . # Build the image from the current directory (where Dockerfile is) ports: - "80:80" # Map host port 80 to container port 80 volumes: - ./app:/app # Mount the local 'app' directory into the container's '/app' depends_on: # Define dependencies between services - db environment: # Set environment variables DATABASE_URL: "mysql://user:password@db:3306/mydb" db: # Another service image: mysql:8.0 # Use a pre-built MySQL image from Docker Hub environment: MYSQL_ROOT_PASSWORD: mysecretpassword MYSQL_DATABASE: mydb volumes: - db_data:/var/lib/mysql # Persist database data to a named volume volumes: db_data: # Define the named volume
Final Thoughts
Docker has fundamentally changed how we approach application development and deployment. Here are the key takeaways from this blog post:
- Consistency and Portability: Docker solves the “works on my machine” problem by providing consistent, isolated environments for applications, ensuring they run uniformly across different stages of the development lifecycle.
- Efficiency and Speed: Containers are lightweight and start quickly, leading to more efficient resource utilization and faster development/deployment cycles compared to traditional virtual machines.
- Simplified Management: Docker streamlines the packaging, distribution, and running of applications.
- Orchestration with Docker Compose: For multi-container applications, Docker Compose simplifies the definition and management of all services, allowing you to spin up complex environments with a single command.
- Continuous Improvement: The Docker ecosystem is constantly evolving. Staying updated with the latest versions, tools, and best practices is essential for maximizing its benefits.
By understanding these core concepts and leveraging both Docker and Docker Compose, you can build, ship, and run your applications with greater efficiency, consistency, and confidence.