Docker Installation and Configuration

Setting up your Docker environment for development

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.

graph TD A[Docker Installation Process] --> B[Choose Docker Edition] B --> C[Docker Desktop for Windows/Mac] B --> D[Docker Engine for Linux] B --> E[Docker in Cloud Environments] C --> F[Installation] D --> F E --> F F --> G[Post-Installation Configuration] G --> H[Verify Installation] H --> I[Configure Docker Settings] I --> J[Set Up Docker Development Environment]

Docker Editions Overview

Before installing Docker, it's important to understand the different editions available:

Docker Desktop

Docker Engine

Docker in Cloud Environments

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

Installation Steps

  1. Enable required Windows features:
    • WSL 2 (Windows Subsystem for Linux)
    • Virtualization enabled in BIOS settings
  2. Download Docker Desktop Installer:
  3. Run the Installer:
    • Double-click the installer file
    • Follow the installation wizard
    • When prompted, select the option to use WSL 2 backend
  4. Start Docker Desktop:
    • Launch Docker Desktop from the Start menu
    • Allow time for Docker to start and initialize
  5. Verify Installation:
    • Open a command prompt or PowerShell window
    • Run docker --version to verify the installation
    • Run docker run hello-world to test functionality
Windows Docker Architecture Windows Host WSL 2 Linux Kernel Docker Engine Containers

Common Windows Installation Issues

Installing Docker on macOS

System Requirements

Installation Steps

  1. Download Docker Desktop Installer:
    • Go to Docker Desktop
    • Download the macOS installer (.dmg)
    • Choose the correct version for your processor (Intel or Apple Silicon)
  2. Run the Installer:
    • Double-click the .dmg file
    • Drag the Docker icon to the Applications folder
  3. 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
  4. Verify Installation:
    • Open Terminal
    • Run docker --version to verify the installation
    • Run docker run hello-world to test functionality

Special Notes for Apple Silicon (M1/M2) Macs

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

Google Cloud

Microsoft Azure

graph TD A[Cloud Docker Options] --> B[Infrastructure as a Service] A --> C[Container as a Service] B --> D[VM with Docker Installed] C --> E[Managed Container Services] C --> F[Kubernetes Services] C --> G[Container Registry Services]

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:

  1. The Docker client contacts the Docker daemon
  2. The daemon pulls the "hello-world" image from Docker Hub
  3. The daemon creates a container from the image and runs it
  4. 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:

  1. Open Docker Desktop
  2. Click on the gear icon (Settings)
  3. 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
General Resources Docker Engine Kubernetes Network Extensions Advanced Docker Engine Configuration { "debug": false, "experimental": false, "insecure-registries": [], "registry-mirrors": [], "max-concurrent-downloads": 3, "max-concurrent-uploads": 5 } Apply

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

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

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.

pie title "Typical Docker Desktop Resource Allocation" "Docker VM" : 2 "Host OS & Apps" : 6

Recommendations for Developer Machines

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:

  1. Open Docker Desktop settings
  2. Go to "Resources" > "File sharing"
  3. Add directories you want to share with Docker

Performance Considerations

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

  1. Install Docker on your system following the appropriate instructions for your OS
  2. Run the following commands to verify your installation:
    • docker --version
    • docker info
    • docker run hello-world
  3. Take note of the output and confirm Docker is working correctly

Activity 2: Configure Docker Resources

  1. Open Docker Desktop settings (Windows/macOS) or edit daemon.json (Linux)
  2. Adjust CPU, memory, and disk resources based on your system capabilities
  3. Configure file sharing to include your development directories
  4. Apply changes and restart Docker if necessary
  5. Run docker info to verify your changes took effect

Activity 3: Create a Docker Context

  1. Create a new Docker context for your local Docker daemon:
    docker context create local-dev --docker "host=unix:///var/run/docker.sock"
  2. List available contexts: docker context ls
  3. Switch to your new context: docker context use local-dev
  4. Run a command to verify it works: docker ps

Troubleshooting Common Issues

Docker Daemon Not Starting

Permission Denied Errors

Network Connectivity Issues

Docker Desktop Performance Issues

Resources for Further Learning

Summary

In this lecture, we've covered the essential aspects of Docker installation and configuration across different platforms:

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.