Introduction
In our previous lectures, we explored containerization concepts and Docker's architecture. Now it's time to get Docker up and running on your system. This lecture will guide you through installing Docker on different operating systems, configuring it for development, and ensuring it's set up securely and efficiently.
Docker installation varies across different operating systems, but the core functionality remains consistent. Think of it like installing a kitchen in different homes—the layout might change, but the essential appliances and their functions remain the same.
Docker Editions Overview
Before installing Docker, it's important to understand the different editions available:
Docker Desktop
- Comprehensive package for Windows and macOS
- Includes Docker Engine, Docker CLI client, Docker Compose, and more
- Provides a graphical user interface for managing Docker
- Uses a virtual machine behind the scenes on non-Linux systems
Docker Engine
- Core Docker runtime for Linux systems
- Command-line focused experience
- Runs natively (no VM required)
- Available via package managers (apt, yum, etc.)
Docker in Cloud Environments
- Pre-configured Docker instances in cloud platforms
- Options include AWS EC2 with Docker, Google Cloud Compute Engine, and Azure VMs
- Managed container services like AWS ECS, Google Cloud Run, and Azure Container Instances
Choosing the right Docker edition is like selecting the right vehicle for your journey—each has its own advantages depending on your specific needs and destination.
Installing Docker on Windows
System Requirements
- Windows 10 64-bit: Pro, Enterprise, or Education (Build 16299 or later)
- Windows 11 64-bit: Home or Pro (version 21H2 or later)
- Virtualization enabled in BIOS/UEFI
- At least 4GB of RAM
Installation Steps
-
Enable required Windows features:
- WSL 2 (Windows Subsystem for Linux)
- Virtualization enabled in BIOS settings
-
Download Docker Desktop Installer:
- Go to Docker Desktop
- Download the Windows installer (.exe)
-
Run the Installer:
- Double-click the installer file
- Follow the installation wizard
- When prompted, select the option to use WSL 2 backend
-
Start Docker Desktop:
- Launch Docker Desktop from the Start menu
- Allow time for Docker to start and initialize
-
Verify Installation:
- Open a command prompt or PowerShell window
- Run
docker --versionto verify the installation - Run
docker run hello-worldto test functionality
Common Windows Installation Issues
-
Virtualization not enabled:
Solution: Enable virtualization in BIOS/UEFI settings
-
WSL 2 not installed:
Solution: Run
wsl --installin PowerShell as administrator -
Hyper-V conflicts:
Solution: Ensure no other virtualization software (like VirtualBox) is running
Installing Docker on macOS
System Requirements
- macOS 11 Big Sur or newer for Intel Macs
- macOS 12 Monterey or newer for Apple Silicon (M1/M2) Macs
- At least 4GB of RAM
- VirtualBox is not required, as Docker Desktop uses macOS's native hypervisor framework
Installation Steps
-
Download Docker Desktop Installer:
- Go to Docker Desktop
- Download the macOS installer (.dmg)
- Choose the correct version for your processor (Intel or Apple Silicon)
-
Run the Installer:
- Double-click the .dmg file
- Drag the Docker icon to the Applications folder
-
Start Docker Desktop:
- Open Docker Desktop from Applications folder
- Authenticate with your macOS user password if prompted
- Allow time for Docker to start and initialize
-
Verify Installation:
- Open Terminal
- Run
docker --versionto verify the installation - Run
docker run hello-worldto test functionality
Special Notes for Apple Silicon (M1/M2) Macs
- Docker Desktop for Apple Silicon can run both ARM64 and x86 container images
- Running x86 images requires emulation (Rosetta 2), which impacts performance
- Many popular images now have ARM64 variants available
- Specify platform when pulling images:
docker pull --platform linux/amd64 image-name
Installing Docker on Linux
Docker runs natively on Linux without the need for a virtual machine, making it more efficient than on Windows or macOS. Installation procedures vary slightly between Linux distributions.
Ubuntu Installation
# Uninstall old versions (if any)
sudo apt-get remove docker docker-engine docker.io containerd runc
# Set up the repository
sudo apt-get update
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# Add Docker's official GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Set up the stable repository
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Install Docker Engine
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# Verify installation
sudo docker run hello-world
CentOS/RHEL Installation
# Remove old versions
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
# Set up the repository
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# Install Docker Engine
sudo yum install docker-ce docker-ce-cli containerd.io
# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker
# Verify installation
sudo docker run hello-world
Post-Installation Steps for Linux
By default, Docker commands require sudo privileges. To run Docker as a non-root user:
# Create the docker group if it doesn't exist
sudo groupadd docker
# Add your user to the docker group
sudo usermod -aG docker $USER
# Apply the new group membership (or log out and back in)
newgrp docker
# Verify you can run docker without sudo
docker run hello-world
Docker in Cloud Environments
If you're working in cloud environments, you might not need to install Docker locally. Many cloud providers offer containerization services that handle the underlying Docker infrastructure for you.
AWS
- EC2 with Docker: Launch an Amazon EC2 instance with Docker pre-installed
- Amazon ECS (Elastic Container Service): Run and manage Docker containers on a cluster
- AWS Fargate: Run containers without managing the underlying infrastructure
- Amazon ECR (Elastic Container Registry): Store, manage, and deploy Docker container images
Google Cloud
- Compute Engine with Docker: Launch a VM with Docker pre-installed
- Google Kubernetes Engine (GKE): Managed Kubernetes service for Docker containers
- Cloud Run: Run stateless containers without managing infrastructure
- Container Registry: Store and manage Docker container images
Microsoft Azure
- Azure VMs with Docker: Deploy VMs with Docker pre-installed
- Azure Kubernetes Service (AKS): Managed Kubernetes service
- Azure Container Instances: Run containers without managing servers
- Azure Container Registry: Store and manage Docker images
Verifying Installation
After installing Docker, you should verify that it's working correctly. These commands work on all operating systems:
# Check Docker version
docker --version
# View more detailed information
docker info
# Run a test container
docker run hello-world
# List Docker components version information
docker version
The hello-world container is a simple test that confirms Docker is installed correctly. It performs the following steps:
- The Docker client contacts the Docker daemon
- The daemon pulls the "hello-world" image from Docker Hub
- The daemon creates a container from the image and runs it
- The container outputs a test message and exits
If you see a message like "Hello from Docker!" then your installation is working correctly.
Docker Configuration
After installing Docker, you might want to adjust its configuration to better suit your development needs. Configuration methods vary by platform but generally involve similar settings.
Docker Desktop Configuration (Windows/macOS)
Docker Desktop provides a graphical interface for configuration:
- Open Docker Desktop
- Click on the gear icon (Settings)
- Configure options such as:
- Resources: CPU, memory, disk, and data location
- File sharing: Directories that can be mounted in containers
- Network: Proxy settings, DNS configuration
- Docker Engine: JSON configuration file for the daemon
Linux Docker Configuration
On Linux, Docker daemon configuration is managed through a JSON configuration file:
# Location of daemon configuration file
/etc/docker/daemon.json
# Example configuration file
{
"data-root": "/path/to/docker-data",
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"default-address-pools": [
{"base": "172.30.0.0/16", "size": 24}
],
"registry-mirrors": ["https://mirror.example.com"],
"insecure-registries": ["registry.local:5000"]
}
# Restart Docker to apply changes
sudo systemctl restart docker
Key Configuration Options
- data-root: Directory where Docker stores all its data
- storage-driver: Driver used for container and image storage (overlay2 is recommended)
- log-driver: How container logs are stored
- registry-mirrors: Alternative registries to speed up image pulls
- insecure-registries: Registries that don't use HTTPS
- default-address-pools: IP address ranges for container networks
Environment Variables
Docker client behavior can be modified with environment variables:
# Connect to a different Docker daemon
export DOCKER_HOST=tcp://192.168.1.100:2375
# Use TLS encryption for Docker daemon communication
export DOCKER_TLS=1
export DOCKER_CERT_PATH=/path/to/certs
# Set Docker CLI context
export DOCKER_CONTEXT=production
# Use a specific configuration file
export DOCKER_CONFIG=/path/to/config/directory
Environment variables offer a flexible way to change Docker client behavior without modifying configuration files. They're particularly useful in CI/CD pipelines or when switching between different Docker environments.
Registry Configuration
Docker uses Docker Hub as its default registry, but you can configure it to use private or alternative registries:
Logging into Registries
# Login to Docker Hub
docker login
# Login to a private registry
docker login registry.example.com:5000
# Login with username provided on command line
docker login -u username registry.example.com:5000
Configuring Insecure Registries
For registries without proper HTTPS certificates:
# In daemon.json
{
"insecure-registries": ["registry.local:5000"]
}
# Restart Docker daemon after changes
sudo systemctl restart docker
Using Registry Mirrors
Registry mirrors can speed up image pulls by caching images closer to your location:
# In daemon.json
{
"registry-mirrors": ["https://mirror.example.com"]
}
# Restart Docker daemon after changes
sudo systemctl restart docker
Resource Allocation
Docker's resource usage can significantly impact system performance. Properly configuring resources is important, especially on development machines:
Docker Desktop Resource Configuration
- CPU: Number of CPU cores Docker can use
- Memory: Amount of RAM allocated to Docker
- Disk: Maximum size of Docker data (images, containers, volumes)
- Swap: Additional virtual memory space
Setting appropriate resource limits is crucial for balancing Docker performance with host system usability. Too few resources can make containers slow, while too many can make your host system unresponsive.
Recommendations for Developer Machines
- Allocate 2-4 CPU cores to Docker (50% of available cores)
- Allocate 4-8GB RAM for Docker (depends on your applications)
- Set disk space to 60-100GB (or more for large projects)
- Enable swap for memory-intensive applications
File Sharing Configuration
For bind mounts to work, Docker needs access to the host directories you want to mount in containers. This requires configuring file sharing:
Docker Desktop File Sharing
On Windows and macOS, you need to explicitly allow Docker to access specific directories:
- Open Docker Desktop settings
- Go to "Resources" > "File sharing"
- Add directories you want to share with Docker
Performance Considerations
- Mounting large directory trees can impact performance
- On Windows/macOS, file sharing happens through the VM boundary, causing overhead
- Consider using Docker volumes instead of bind mounts for better performance
- Use dedicated bind mounts for specific files rather than mounting entire project directories
File sharing is like lending books from your library to a friend—you need to decide which books (directories) you're willing to share, and there's always a small risk and overhead involved in the process.
Docker Contexts
Docker contexts allow you to easily switch between different Docker endpoints (local, remote, or cloud). This is especially useful for developers working with multiple environments:
# List available contexts
docker context ls
# Create a new context for a remote Docker host
docker context create remote-server --docker "host=ssh://user@remote-server"
# Create a context for AWS ECS
docker context create ecs --from-env
# Switch to a different context
docker context use remote-server
# Run a command using a specific context without switching
docker --context=remote-server ps
# Inspect a context
docker context inspect remote-server
# Remove a context
docker context rm remote-server
Contexts are like profile settings in a web browser—they store connection details and preferences for different environments, allowing you to quickly switch between them without reconfiguring everything.
Docker Compose Installation
Docker Compose is a crucial tool for multi-container applications. While it comes bundled with Docker Desktop, on Linux you might need to install it separately:
Linux Installation
# Download the current stable release
sudo curl -L "https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# Apply executable permissions
sudo chmod +x /usr/local/bin/docker-compose
# Create a symbolic link, if necessary
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# Verify installation
docker-compose --version
Using Docker Compose V2 Plugin
Docker now provides Compose V2 as a plugin to the Docker CLI:
# Install Docker Compose CLI plugin on Linux
mkdir -p ~/.docker/cli-plugins/
curl -SL https://github.com/docker/compose/releases/download/v2.17.2/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
chmod +x ~/.docker/cli-plugins/docker-compose
# Use Docker Compose V2
docker compose version # Note: no hyphen between docker and compose
Docker Compose is like a recipe book that goes along with your kitchen (Docker). While the kitchen can function without it, the recipe book makes it much easier to prepare complex meals (multi-container applications) consistently.
Security Best Practices
Securing your Docker installation is crucial, especially in production environments but also important for development:
User Namespace Remapping
Run the Docker daemon with user namespace remapping to limit container process privileges:
# In daemon.json
{
"userns-remap": "default"
}
# Restart Docker daemon after changes
sudo systemctl restart docker
Content Trust
Enable Docker Content Trust to verify image authenticity:
# Enable content trust for image pulls/pushes
export DOCKER_CONTENT_TRUST=1
Limit Container Capabilities
Reduce container privileges by dropping capabilities:
# Run container with minimal capabilities
docker run --cap-drop=all --cap-add=NET_BIND_SERVICE nginx
Use Non-Root Users in Containers
# In your Dockerfile
USER non-root-user
# Or when running containers
docker run --user 1000:1000 nginx
Limit Resource Usage
# Set memory and CPU limits
docker run --memory=512m --cpu-shares=512 nginx
Securing Docker is like securing your home—you need multiple layers of protection, from good locks (user namespaces) to controlled access (limited capabilities) and resource management (usage limits).
Practice Activities
Activity 1: Install and Verify Docker
- Install Docker on your system following the appropriate instructions for your OS
- Run the following commands to verify your installation:
docker --versiondocker infodocker run hello-world
- Take note of the output and confirm Docker is working correctly
Activity 2: Configure Docker Resources
- Open Docker Desktop settings (Windows/macOS) or edit daemon.json (Linux)
- Adjust CPU, memory, and disk resources based on your system capabilities
- Configure file sharing to include your development directories
- Apply changes and restart Docker if necessary
- Run
docker infoto verify your changes took effect
Activity 3: Create a Docker Context
- Create a new Docker context for your local Docker daemon:
docker context create local-dev --docker "host=unix:///var/run/docker.sock" - List available contexts:
docker context ls - Switch to your new context:
docker context use local-dev - Run a command to verify it works:
docker ps
Troubleshooting Common Issues
Docker Daemon Not Starting
- Check status:
sudo systemctl status docker - Check logs:
journalctl -u docker.service - Common solutions:
- Ensure daemon.json has valid JSON syntax
- Check for conflicting network configurations
- Verify disk space is available
Permission Denied Errors
- Issue:
permission denied while trying to connect to the Docker daemon socket - Solution: Add user to docker group or run with sudo
- Commands:
sudo usermod -aG docker $USER newgrp docker
Network Connectivity Issues
- Issue: Containers can't communicate or access the internet
- Solutions:
- Check Docker network settings:
docker network ls - Verify host firewall rules aren't blocking Docker
- Reset Docker networking:
docker network prune
- Check Docker network settings:
Docker Desktop Performance Issues
- Issue: Docker Desktop consuming excessive resources
- Solutions:
- Adjust resource limits in Docker Desktop settings
- Prune unused objects:
docker system prune -a - Restart Docker Desktop
Resources for Further Learning
Summary
In this lecture, we've covered the essential aspects of Docker installation and configuration across different platforms:
- Installing Docker on Windows, macOS, and Linux
- Setting up Docker in cloud environments
- Verifying your Docker installation
- Configuring Docker daemon settings
- Managing Docker resources and file sharing
- Setting up Docker contexts for multiple environments
- Installing Docker Compose
- Implementing Docker security best practices
- Troubleshooting common installation issues
With Docker properly installed and configured, you now have a powerful containerization platform ready for development. In the next lecture, we'll dive into creating Docker containers for different programming languages.