Welcome to from-docker-to-kubernetes

Docker Contexts

Learn how to manage multiple Docker environments with Docker contexts for seamless switching between different Docker endpoints

Docker Contexts

Docker contexts allow you to manage connections to multiple Docker engines from a single Docker CLI client. This powerful feature enables seamless switching between different Docker environments, such as local development, remote servers, Kubernetes clusters, and cloud providers. Introduced in Docker 19.03, contexts solve the problem of managing multiple Docker environments without needing to modify environment variables or configuration files each time you switch between them.

Understanding Contexts

What are Contexts?

  • Named configurations for Docker connections that encapsulate all connection parameters
  • Store endpoint information including the Docker API socket location (TCP, SSH, or Unix socket)
  • Include authentication details such as TLS certificates and API credentials
  • Support multiple Docker environments from a single workstation
  • Enable quick environment switching without modifying shell configuration
  • Preserve connection state between CLI sessions

Key Benefits

  • Manage multiple environments from one CLI without changing configuration files
  • Reduce configuration errors by storing validated connection settings
  • Simplify CI/CD pipelines with environment-specific deployment targets
  • Streamline development workflows across local and remote Docker hosts
  • Enhance team collaboration through standardized environment definitions
  • Support hybrid cloud strategies with consistent management interfaces
  • Eliminate the need for SSH sessions to run commands on remote Docker hosts

Managing Contexts

Context Types

# Docker Engine context with TLS security
docker context create my-engine \
  --docker "host=tcp://192.168.1.10:2376,ca=~/certs/ca.pem,cert=~/certs/cert.pem,key=~/certs/key.pem"
# TCP connection to remote Docker host with TLS certificates for authentication
# The three certificate files provide mutual TLS authentication
# Port 2376 is the standard secure Docker daemon port

# Kubernetes context (for Docker+Kubernetes operations)
docker context create my-kubernetes \
  --docker "host=unix:///var/run/docker.sock" \
  --kubernetes "config=/path/to/kubeconfig.yaml,context=my-cluster"
# Combines Docker and Kubernetes endpoints in a single context
# Enables seamless switching between container and orchestration operations
# Uses local Docker daemon but remote Kubernetes cluster
# Leverages existing kubeconfig file for Kubernetes authentication

# ACI (Azure Container Instances) context
docker context create my-aci \
  --aci-subscription-id $AZURE_SUBSCRIPTION_ID
# Connects to Azure Container Instances for serverless container deployments
# Requires Azure CLI authentication before creating context
# Enables managing cloud containers without running your own Kubernetes
# Supports direct deployment using Docker commands to cloud containers

Common Context Scenarios

Development Environments

  • Local Docker Desktop for development and testing on your workstation
  • Development servers for shared team environments or specialized hardware
  • Testing environments for QA, integration, and performance testing
  • Staging servers that mirror production configuration for pre-deployment validation
  • Production environments with restricted access and enhanced security
  • Remote development environments for resource-intensive workloads

Multi-Cloud Management

  • AWS ECS/EKS contexts for Amazon container services management
  • Azure ACI/AKS contexts for Microsoft cloud container orchestration
  • Google Cloud GKE contexts for Google Kubernetes Engine deployments
  • Custom cloud provider setups with specialized APIs or configurations
  • Hybrid deployments spanning on-premises and cloud environments
  • Multi-cloud strategies that leverage best services from different providers
  • Edge deployments for IoT and distributed computing scenarios

Context in Docker Compose

Creating Specialized Contexts

# Create context with TLS
docker context create secure-context \
  --docker "host=tcp://secure-docker-host:2376,ca=./ca.pem,cert=./cert.pem,key=./key.pem"
# Uses TLS mutual authentication for secure remote connections
# Requires certificate authority, client certificate, and client key
# Provides encrypted communication and authentication
# Recommended for production environments and internet-facing Docker hosts

# Create context with SSH
docker context create ssh-context \
  --docker "host=ssh://user@remote-host"
# Uses SSH for secure connection and authentication
# Leverages existing SSH keys and configuration
# No need to expose Docker daemon TCP port
# Works through bastion hosts and jump servers
# Can use non-standard SSH ports: ssh://user@remote-host:2222

# Create context with socket path
docker context create socket-context \
  --docker "host=unix:///custom/path/docker.sock"
# Connects to Docker daemon through a Unix socket
# Useful for non-standard socket locations
# Common in custom installations or rootless Docker
# No network exposure, highest security for local connections
# Maximum performance for local operations

Using Contexts in Scripts

Scripting with Contexts

#!/bin/bash
# Deploy to multiple environments
for ctx in dev staging prod; do
  echo "Deploying to $ctx environment..."
  docker --context $ctx stack deploy -c docker-compose.yml my-app
  
  # Verify deployment status
  docker --context $ctx service ls --filter name=my-app
  
  # Wait for deployment to complete
  docker --context $ctx service ls --filter name=my-app \
    --format "{{.Replicas}}" | grep -q "[0-9]/[0-9]" && \
    echo "Deployment to $ctx complete"
done

# This script demonstrates:
# - Sequential deployment across environments
# - Consistent configuration using the same compose file
# - Verification steps for each deployment
# - Environment-specific targeting without configuration changes

Environment Variables

# Set context with environment variable
export DOCKER_CONTEXT=production
# Sets the default context for the current shell session
# All Docker commands will target the production environment
# Persists until shell session ends or variable changes

# Run command with current context
docker ps
# Uses the context set by the environment variable (production)
# Lists containers running in the production environment
# No need to specify --context flag for each command

# Override with specific context
DOCKER_CONTEXT=staging docker ps
# Temporarily overrides the current context for a single command
# Returns to the previous context for subsequent commands
# Doesn't change the persistent configuration
# Useful for quick operations on a different environment

# Combine with other environment variables
DOCKER_CONTEXT=prod DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect myimage:latest
# Can combine multiple Docker-related environment variables
# Enables flexible configuration for specific commands

CI/CD Integration

# GitHub Actions example
name: Multi-Environment Deployment

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Docker Context
        run: |
          docker context create production \
            --docker "host=ssh://user@prod-server,ssh-key=${{ secrets.SSH_KEY }}"
      
      - name: Deploy to Production
        run: |
          docker --context production stack deploy -c docker-compose.yml my-app

Context Security

Securing Credentials

  • Store sensitive data in credential managers like Docker Credential Helpers
  • Use SSH keys with passphrases for remote host authentication
  • Implement least-privilege access controls for each context
  • Rotate credentials regularly (certificates, API keys, access tokens)
  • Use environment-specific permissions (read-only for dev, full access for admins)
  • Separate context management from credential management
  • Implement credential revocation procedures for compromised environments
  • Audit context usage and credential access patterns
  • Use credential delegation where appropriate (OIDC, IAM roles)
  • Implement MFA for accessing production contexts

Best Practices

# Create context with credential helper
docker context create secure-context \
  --docker "host=tcp://secure-host:2376" \
  --description "Context with secure credentials"
# The credential helper automatically manages and secures authentication information
# The docker credential helper will securely store and retrieve credentials as needed
# Supports various backends: keychain (macOS), wincred (Windows), pass/libsecret (Linux)
# Centralized credential management separate from context definitions

# Export context (without sensitive data)
docker context export secure-context --output secure-context.dockercontext
# Exports context configuration without embedding sensitive credentials
# Safe to share with team members or version control
# Recipients still need appropriate credentials to use the context
# Enables separation of context definition from authentication
# Great for team onboarding and standardization

Advanced Context Management

# Export a context
docker context export my-context --output my-context.dockercontext
# Creates a portable context definition file
# Excludes sensitive information like TLS keys
# Can be version controlled safely
# Useful for team standardization and onboarding

# Import a context
docker context import new-context my-context.dockercontext
# Creates a new context from an exported definition file
# The user must provide their own credentials if required
# Can rename the context during import
# Validates the context configuration during import
# Example of importing with a new name:
# docker context import production-eu my-context.dockercontext

Context Organization Strategies

Naming Conventions

  • <environment>-<region>-<role> hierarchical naming pattern
  • dev-useast-manager for development environment in US East region with manager role
  • prod-euwest-worker for production environment in EU West region with worker role
  • staging-apac-registry for staging environment in Asia-Pacific with registry service
  • Clear, consistent naming that encodes critical information
  • Alphabetical sorting groups related contexts together
  • Easy filtering and pattern matching with standard naming
  • Scales to large environments with many contexts
  • Enables programmatic context selection in scripts

Grouping Strategies

# List contexts with filter
docker context ls --format "{{if .Name | contains \"prod\"}}{{.Name}}: {{.Endpoints.docker.Host}}{{end}}"
# Uses Go templating to filter and format output
# Shows only production contexts with their Docker endpoints
# Powerful for scripting and automation
# Can filter on any context property or metadata

# Create contexts with labels
docker context create prod-us \
  --docker "host=ssh://user@prod-us" \
  --description "Production US" \
  --label env=prod --label region=us
# Labels provide metadata for organization and filtering
# Multiple labels can categorize contexts in different ways
# Can filter contexts by label: --filter label=env=prod
# Labels don't affect context functionality
# Useful for organizing large numbers of contexts

# List contexts by label
docker context ls --format "table {{.Name}}\t{{.Labels.env}}\t{{.Labels.region}}" \
  --filter label=env=prod
# Creates a custom table view of contexts by label
# Great for team documentation and context inventory

Common Use Cases

Context with Docker Buildx

# Create a builder using a specific context
docker buildx create --name remote-builder --use --context remote-server
# Creates a BuildKit builder that uses the remote-server context
# Offloads build processing to the remote Docker host
# Useful for resource-intensive builds on powerful servers
# --use flag makes this the default builder for future commands

# Build using remote builder
docker buildx build --builder remote-builder -t myimage:latest .
# Builds the image on the remote server specified in the context
# Local files are automatically transferred to the remote build server
# The resulting image is stored on the remote Docker host
# Add --load to also import the image to your local Docker

# Multi-context, multi-platform build
docker buildx create --name builder1 --context context1
docker buildx create --name builder2 --context context2
docker buildx create --name multibuilder --driver docker-container \
  --use --bootstrap --append builder1 --append builder2
docker buildx build --platform linux/amd64,linux/arm64 -t myimage:latest .
# Creates a distributed build farm across multiple contexts
# Each builder can handle different platform builds
# Allows parallel building of multi-architecture images
# Distributes the workload across multiple Docker hosts
# Reduces overall build time for complex multi-platform images

Troubleshooting

Common Issues

  • Connection timeouts when network latency is high or firewalls block traffic
  • Authentication failures due to expired certificates or incorrect credentials
  • Permission problems from insufficient user rights on remote Docker hosts
  • Network connectivity issues caused by firewall rules or proxy configurations
  • Certificate validation errors from expired or mismatched TLS certificates
  • Resource constraints when remote hosts lack memory or CPU for operations
  • SSH connection issues including key permission problems or agent connectivity
  • API version mismatches between Docker client and remote daemon versions
  • Context configuration errors from typos or incorrect endpoint specifications

Diagnostic Commands

# Test connection
docker --context my-context info
# Verifies basic connectivity to the Docker daemon
# Shows system-wide information including configuration
# Quickly identifies if the context is working properly
# First command to run when troubleshooting a context

# Check endpoint information
docker context inspect --format '{{json .Endpoints}}' my-context | jq
# Outputs the raw endpoint configuration in JSON format
# Useful for verifying connection parameters
# The 'jq' tool formats the output for better readability
# Helps identify misconfiguration in the context definition

# Verify Docker daemon version
docker --context my-context version
# Shows both client and server versions
# Identifies API version mismatches
# Verifies the remote Docker engine is responsive
# Provides TLS and authentication information

# Test network connectivity
docker --context my-context run --rm alpine ping -c 1 google.com
# Verifies that containers can access the internet
# Tests DNS resolution on the remote Docker host
# Checks if container networking is functional
# Useful for diagnosing network isolation issues

# Test resource availability
docker --context my-context system df
# Shows disk usage information on the remote system
# Helps identify resource constraints
# Verifies storage is available for images and containers

Context Migration

# Create context for new environment
docker context create new-prod --docker "host=ssh://user@new-prod-server"

# Test new environment
docker --context new-prod stack deploy -c docker-compose.yml my-app-test

# Switch production after validation
docker context use new-prod

Best Practices

Context Management

  • Document all contexts with detailed information about purpose and configuration
  • Use consistent naming conventions that encode environment, region, and role
  • Limit access to production contexts through RBAC and credential management
  • Implement context rotation procedures for security and infrastructure updates
  • Audit context usage regularly to identify unauthorized access or misuse
  • Share development contexts with team members using exported configurations
  • Create onboarding documentation for new team members
  • Establish procedures for context lifecycle management (creation to retirement)
  • Implement automated validation of context configurations
  • Create emergency procedures for context access during incidents

Workflow Integration

  • Integrate with shell aliases for quick context switching
    • Example: alias dprod="docker --context production"
    • Example: alias dswitch="docker context use"
  • Use with Docker Compose environments for consistent multi-service deployments
  • Include in deployment scripts with proper error handling and logging
  • Document in project README files with examples and prerequisites
  • Automate context switching based on git branches or project directories
  • Create environment-specific settings files that map to specific contexts
  • Build context-aware shell prompts that display the active context
  • Implement CI/CD hooks that select appropriate contexts
  • Create context groups for common operations across multiple environments
  • Develop context-specific monitoring and alerting configurations

Real-World Examples