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
docker --version # Display the Docker version. docker info # Display system-wide information. docker login # Log in to a Docker registry (e.g., Docker Hub). docker logout # Log out from a Docker registry.
Image Management
docker build -t <image_name> . # Build a Docker image from a Dockerfile in the current directory. docker build -t <image_name>:<tag> . # Build an image with a specific tag. docker images # List all local Docker images. docker pull <image_name>:<tag> # Pull an image from a registry. docker push <username>/<image_name>:<tag> # Push an image to a registry. docker rmi <image_name> # Remove a Docker image. docker image prune # Remove all dangling (unused) images. docker history <image_name> # Show the history of an image.
Container Management
docker run -d -p <host_port>:<container_port> --name <container_name> <image_name> # Create and run a container in detached mode, mapping ports. docker run -it <image_name> /bin/bash # Run a container interactively and open a bash shell. docker ps # List running containers. docker ps -a # List all containers (running and stopped). docker start <container_name_or_id> # Start a stopped container. docker stop <container_name_or_id> # Stop a running container. docker restart <container_name_or_id> # Restart a container. docker rm <container_name_or_id> # Remove a stopped container. docker exec -it <container_name_or_id> <command> # Execute a command inside a running container. docker logs <container_name_or_id> # Fetch and follow the logs of a container. docker inspect <container_name_or_id> # Display detailed information about a container. docker attach <container_name_or_id> # Attach to a running container's standard input, output, and error streams.
Volume Management
docker volume create <volume_name> # Create a new volume. docker volume ls # List all volumes. docker volume inspect <volume_name> # Display detailed information about a volume. docker volume rm <volume_name> # Remove one or more volumes. docker volume prune # Remove all unused volumes.
Network Management
docker network ls # List all Docker networks. docker network create <network_name> # Create a new custom network. docker network connect <network_name> <container_name_or_id> # Connect a running container to a network. docker network disconnect <network_name> <container_name_or_id> # Disconnect a container from a network. docker network rm <network_name> # Remove a network.
Cleaning Up
docker system prune # Remove all stopped containers, dangling images, unused networks, and dangling build cache. docker system prune -a # Remove all unused Docker data (stopped containers, all unused images, all networks not used by at least one container, and all build cache).
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.