Skip to main content

Docker Commands Guide

A comprehensive reference guide for Docker commands with practical examples, configurations, and real-world use cases for Linux environments.

Table of Contents


Docker Installation and Setup

Installation on Different Linux Distributions

Ubuntu/Debian

# Update package index
sudo apt update

# Install prerequisites
sudo apt 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

# Add Docker repository
echo "deb [arch=amd64 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
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker

CentOS/RHEL/Rocky Linux

# Install yum-utils
sudo yum install -y yum-utils

# Add Docker repository
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# Install Docker
sudo yum install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Start and enable Docker
sudo systemctl start docker
sudo systemctl enable docker

Post-Installation Setup

# Add user to docker group (avoid using sudo)
sudo usermod -aG docker $USER

# Logout and login again or run:
newgrp docker

# Test Docker installation
docker run hello-world

# Check Docker version
docker --version
docker version
docker info

Container Management

Basic Container Operations

Running Containers

# Run a simple container
docker run ubuntu:20.04

# Run container interactively
docker run -it ubuntu:20.04 /bin/bash

# Run container in background (detached)
docker run -d nginx:latest

# Run with custom name
docker run -d --name my-nginx nginx:latest

# Run with port mapping
docker run -d -p 8080:80 --name web-server nginx:latest

# Run with environment variables
docker run -d -e MYSQL_ROOT_PASSWORD=secret mysql:8.0

# Run with volume mount
docker run -d -v /host/path:/container/path nginx:latest

# Run with resource limits
docker run -d --memory=512m --cpus=1.0 nginx:latest

Container Lifecycle Management

# List running containers
docker ps

# List all containers (including stopped)
docker ps -a

# Start a stopped container
docker start container_name

# Stop a running container
docker stop container_name

# Restart a container
docker restart container_name

# Pause a container
docker pause container_name

# Unpause a container
docker unpause container_name

# Remove a container
docker rm container_name

# Force remove a running container
docker rm -f container_name

# Remove all stopped containers
docker container prune

Container Inspection and Monitoring

# View container logs
docker logs container_name

# Follow logs in real-time
docker logs -f container_name

# Show last 100 lines of logs
docker logs --tail 100 container_name

# Show logs with timestamps
docker logs -t container_name

# Inspect container details
docker inspect container_name

# Show container resource usage
docker stats

# Show resource usage for specific container
docker stats container_name

# Execute command in running container
docker exec -it container_name /bin/bash

# Execute command as specific user
docker exec -it -u root container_name /bin/bash

Image Management

Image Operations

# List local images
docker images

# Search images on Docker Hub
docker search nginx

# Pull image from registry
docker pull nginx:latest

# Pull specific tag
docker pull ubuntu:20.04

# Build image from Dockerfile
docker build -t my-app:latest .

# Build with custom Dockerfile
docker build -t my-app:latest -f Dockerfile.prod .

# Build with build arguments
docker build --build-arg VERSION=1.0 -t my-app:latest .

# Tag an image
docker tag my-app:latest my-registry.com/my-app:v1.0

# Remove image
docker rmi image_name

# Remove unused images
docker image prune

# Remove all unused images
docker image prune -a

# Show image history
docker history image_name

Dockerfile Examples

Basic Web Application

# Dockerfile for Node.js application
FROM node:16-alpine

# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install dependencies
RUN npm ci --only=production

# Copy application code
COPY . .

# Create non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

# Change ownership
RUN chown -R nextjs:nodejs /app
USER nextjs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1

# Start application
CMD ["npm", "start"]

Multi-stage Build

# Multi-stage build for Go application
FROM golang:1.19-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Final stage
FROM alpine:latest

RUN apk --no-cache add ca-certificates
WORKDIR /root/

COPY --from=builder /app/main .

EXPOSE 8080
CMD ["./main"]

Network Management

Network Operations

# List networks
docker network ls

# Create custom network
docker network create my-network

# Create network with specific driver
docker network create --driver bridge my-bridge-network

# Create network with custom subnet
docker network create --subnet=172.20.0.0/16 my-custom-network

# Inspect network
docker network inspect my-network

# Connect container to network
docker network connect my-network container_name

# Disconnect container from network
docker network disconnect my-network container_name

# Remove network
docker network rm my-network

# Remove unused networks
docker network prune

Network Types and Use Cases

Bridge Network (Default)

# Create custom bridge network
docker network create --driver bridge \
--subnet=172.18.0.0/16 \
--ip-range=172.18.240.0/20 \
my-bridge

# Run containers on custom bridge
docker run -d --network my-bridge --name web nginx
docker run -d --network my-bridge --name db mysql:8.0

Host Network

# Use host networking (container uses host's network stack)
docker run -d --network host nginx

# Useful for high-performance applications
docker run -d --network host --name monitoring-app my-monitoring:latest

None Network

# No networking (completely isolated)
docker run -d --network none my-isolated-app

Volume Management

Volume Operations

# List volumes
docker volume ls

# Create named volume
docker volume create my-data

# Create volume with specific driver
docker volume create --driver local my-local-data

# Inspect volume
docker volume inspect my-data

# Remove volume
docker volume rm my-data

# Remove unused volumes
docker volume prune

# Remove all unused volumes
docker volume prune -a

Mount Types

Named Volumes

# Create and use named volume
docker volume create app-data
docker run -d -v app-data:/var/lib/mysql mysql:8.0

# Share volume between containers
docker run -d --name db -v shared-data:/data mysql:8.0
docker run -d --name backup -v shared-data:/backup ubuntu:20.04

Bind Mounts

# Mount host directory to container
docker run -d -v /host/path:/container/path nginx

# Mount with read-only access
docker run -d -v /host/config:/etc/nginx/conf.d:ro nginx

# Mount current directory
docker run -d -v $(pwd):/app node:16 npm start

tmpfs Mounts

# Mount tmpfs (temporary filesystem in memory)
docker run -d --tmpfs /tmp nginx

# Mount with specific options
docker run -d --tmpfs /tmp:rw,noexec,nosuid,size=100m nginx

Docker Compose

Basic docker-compose.yml

version: '3.8'

services:
web:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- db
networks:
- app-network

db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: myapp
volumes:
- db-data:/var/lib/mysql
networks:
- app-network

volumes:
db-data:

networks:
app-network:
driver: bridge

Docker Compose Commands

# Start services
docker-compose up

# Start in background
docker-compose up -d

# Start specific service
docker-compose up web

# Stop services
docker-compose down

# Stop and remove volumes
docker-compose down -v

# View logs
docker-compose logs

# Follow logs
docker-compose logs -f

# Scale services
docker-compose up --scale web=3

# Execute command in service
docker-compose exec web /bin/bash

# Build services
docker-compose build

# Pull latest images
docker-compose pull

Advanced Compose Example

version: '3.8'

services:
nginx:
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./ssl:/etc/ssl/certs
depends_on:
- app
restart: unless-stopped
networks:
- frontend

app:
build:
context: ./app
args:
- NODE_ENV=production
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
- REDIS_URL=redis://redis:6379
volumes:
- ./app:/usr/src/app
- /usr/src/app/node_modules
depends_on:
- db
- redis
restart: unless-stopped
networks:
- frontend
- backend

db:
image: postgres:13
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
networks:
- backend

redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- redis-data:/data
restart: unless-stopped
networks:
- backend

volumes:
postgres-data:
redis-data:

networks:
frontend:
driver: bridge
backend:
driver: bridge

Registry Operations

Docker Hub Operations

# Login to Docker Hub
docker login

# Login with username
docker login -u username

# Push image to Docker Hub
docker push username/image-name:latest

# Pull private image
docker pull username/private-repo:latest

# Logout
docker logout

Private Registry

# Run local registry
docker run -d -p 5000:5000 --name registry registry:2

# Tag image for private registry
docker tag my-app localhost:5000/my-app:latest

# Push to private registry
docker push localhost:5000/my-app:latest

# Pull from private registry
docker pull localhost:5000/my-app:latest

# List repositories in registry
curl -X GET http://localhost:5000/v2/_catalog

# List tags for repository
curl -X GET http://localhost:5000/v2/my-app/tags/list

Secure Registry with TLS

# Generate SSL certificate
openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt

# Run registry with TLS
docker run -d \
--restart=always \
--name registry \
-v $(pwd)/certs:/certs \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-p 443:443 \
registry:2

System Management

Docker System Commands

# Show Docker system information
docker system df

# Show detailed space usage
docker system df -v

# Clean up unused resources
docker system prune

# Clean up everything (including volumes)
docker system prune --volumes

# Clean up all unused images
docker system prune -a

# Show system events
docker system events

# Show real-time events
docker system events --since 30m

Resource Management

# Set memory limit
docker run -d --memory=512m nginx

# Set CPU limit
docker run -d --cpus=1.5 nginx

# Set CPU shares (relative weight)
docker run -d --cpu-shares=512 nginx

# Set swap limit
docker run -d --memory=512m --memory-swap=1g nginx

# Limit block IO
docker run -d --device-read-bps /dev/sda:1mb nginx

# Set restart policy
docker run -d --restart=unless-stopped nginx

Docker Daemon Configuration

# Edit daemon configuration
sudo vim /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"data-root": "/var/lib/docker",
"default-ulimits": {
"nofile": {
"Name": "nofile",
"Hard": 64000,
"Soft": 64000
}
}
}
# Restart Docker daemon
sudo systemctl restart docker

Security and Best Practices

Security Commands

# Run container as non-root user
docker run -d --user 1001:1001 nginx

# Drop capabilities
docker run -d --cap-drop ALL --cap-add NET_BIND_SERVICE nginx

# Run with read-only root filesystem
docker run -d --read-only nginx

# Set security options
docker run -d --security-opt no-new-privileges nginx

# Use AppArmor profile
docker run -d --security-opt apparmor:docker-default nginx

# Scan image for vulnerabilities (if Docker Scout is available)
docker scout cves image-name

Best Practices Dockerfile

# Use specific base image versions
FROM node:16.17.0-alpine3.16

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001

# Set working directory
WORKDIR /app

# Copy only necessary files
COPY package*.json ./

# Install dependencies as root, then switch user
RUN npm ci --only=production && \
npm cache clean --force

# Copy application files
COPY --chown=nextjs:nodejs . .

# Switch to non-root user
USER nextjs

# Use COPY instead of ADD
COPY src/ ./src/

# Set proper permissions
RUN chmod +x entrypoint.sh

# Use multi-stage builds to reduce image size
FROM node:16-alpine AS dependencies
# ... dependency installation

FROM node:16-alpine AS runner
COPY --from=dependencies /app/node_modules ./node_modules
# ... final image setup

# Health check
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost:3000/ || exit 1

# Use exec form for CMD
CMD ["node", "server.js"]

Troubleshooting

Common Issues and Solutions

Container Won't Start

# Check container logs
docker logs container_name

# Check container configuration
docker inspect container_name

# Run container interactively to debug
docker run -it image_name /bin/bash

# Check available resources
docker system df

Port Already in Use

# Find process using port
sudo netstat -tulpn | grep :8080
sudo lsof -i :8080

# Kill process using port
sudo kill -9 PID

# Use different port mapping
docker run -d -p 8081:80 nginx

Out of Disk Space

# Clean up Docker resources
docker system prune -a --volumes

# Remove unused images
docker image prune -a

# Remove stopped containers
docker container prune

# Check Docker space usage
docker system df -v

Permission Denied

# Add user to docker group
sudo usermod -aG docker $USER

# Fix Docker socket permissions
sudo chmod 666 /var/run/docker.sock

# Restart Docker service
sudo systemctl restart docker

Debugging Commands

# Enter running container
docker exec -it container_name /bin/bash

# Run debugging tools in container
docker exec -it container_name ps aux
docker exec -it container_name netstat -tulpn

# Copy files from container
docker cp container_name:/path/to/file /host/path/

# Copy files to container
docker cp /host/path/file container_name:/path/to/

# Check container processes
docker top container_name

# Monitor container resource usage
docker stats container_name

Real-World Examples

1. NGINX Web Server with SSL

#!/bin/bash
# nginx-ssl-setup.sh

# Create directories
mkdir -p nginx/conf.d ssl

# Generate SSL certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ssl/nginx.key \
-out ssl/nginx.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=localhost"

# Create NGINX configuration
cat > nginx/conf.d/default.conf << 'EOF'
server {
listen 80;
server_name localhost;
return 301 https://$server_name$request_uri;
}

server {
listen 443 ssl;
server_name localhost;

ssl_certificate /etc/ssl/certs/nginx.crt;
ssl_certificate_key /etc/ssl/private/nginx.key;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
EOF

# Run NGINX container
docker run -d \
--name nginx-ssl \
-p 80:80 \
-p 443:443 \
-v $(pwd)/nginx/conf.d:/etc/nginx/conf.d \
-v $(pwd)/ssl/nginx.crt:/etc/ssl/certs/nginx.crt \
-v $(pwd)/ssl/nginx.key:/etc/ssl/private/nginx.key \
nginx:latest

2. WordPress with MySQL

# wordpress-docker-compose.yml
version: '3.8'

services:
wordpress:
image: wordpress:latest
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: wordpress_password
WORDPRESS_DB_NAME: wordpress
volumes:
- wordpress_data:/var/www/html
depends_on:
- db
restart: unless-stopped

db:
image: mysql:8.0
environment:
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress_password
MYSQL_ROOT_PASSWORD: root_password
volumes:
- db_data:/var/lib/mysql
restart: unless-stopped

volumes:
wordpress_data:
db_data:

3. Monitoring Stack (Prometheus + Grafana)

# monitoring-stack.yml
version: '3.8'

services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
restart: unless-stopped

grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
depends_on:
- prometheus
restart: unless-stopped

node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
restart: unless-stopped

volumes:
prometheus_data:
grafana_data:

4. ELK Stack for Log Management

# elk-stack.yml
version: '3.8'

services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0
environment:
- discovery.type=single-node
- xpack.security.enabled=false
ports:
- "9200:9200"
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
restart: unless-stopped

logstash:
image: docker.elastic.co/logstash/logstash:8.5.0
ports:
- "5044:5044"
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
environment:
- "LS_JAVA_OPTS=-Xmx256m -Xms256m"
depends_on:
- elasticsearch
restart: unless-stopped

kibana:
image: docker.elastic.co/kibana/kibana:8.5.0
ports:
- "5601:5601"
environment:
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
depends_on:
- elasticsearch
restart: unless-stopped

volumes:
elasticsearch_data:

5. Development Environment

#!/bin/bash
# dev-environment-setup.sh

# Create development network
docker network create dev-network

# Start database
docker run -d \
--name dev-postgres \
--network dev-network \
-e POSTGRES_DB=devdb \
-e POSTGRES_USER=dev \
-e POSTGRES_PASSWORD=devpass \
-p 5432:5432 \
-v dev_postgres_data:/var/lib/postgresql/data \
postgres:13

# Start Redis cache
docker run -d \
--name dev-redis \
--network dev-network \
-p 6379:6379 \
redis:6-alpine

# Start application
docker run -d \
--name dev-app \
--network dev-network \
-e DATABASE_URL=postgresql://dev:devpass@dev-postgres:5432/devdb \
-e REDIS_URL=redis://dev-redis:6379 \
-p 3000:3000 \
-v $(pwd):/app \
-w /app \
node:16 npm run dev

echo "Development environment started!"
echo "Application: http://localhost:3000"
echo "Database: localhost:5432"
echo "Redis: localhost:6379"

Performance Optimization

Container Optimization

# Use multi-stage builds
FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:16-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY . .
CMD ["npm", "start"]

# Optimize image layers
RUN apt-get update && apt-get install -y \
curl \
vim \
&& rm -rf /var/lib/apt/lists/*

# Use .dockerignore
echo "node_modules" >> .dockerignore
echo ".git" >> .dockerignore
echo "*.log" >> .dockerignore

Resource Monitoring

#!/bin/bash
# container-monitoring.sh

echo "=== Container Resource Usage ==="
docker stats --no-stream

echo -e "\n=== Container Processes ==="
for container in $(docker ps --format "{{.Names}}"); do
echo "Container: $container"
docker exec $container ps aux 2>/dev/null || echo " Cannot access process list"
echo ""
done

echo "=== Disk Usage ==="
docker system df

echo -e "\n=== Network Usage ==="
docker network ls

Quick Reference

Essential Commands

# Container lifecycle
docker run -d --name myapp -p 8080:80 nginx
docker ps
docker stop myapp
docker start myapp
docker rm myapp

# Image management
docker images
docker pull nginx:latest
docker build -t myapp .
docker rmi myapp

# Logs and debugging
docker logs -f myapp
docker exec -it myapp /bin/bash
docker inspect myapp

# Cleanup
docker system prune
docker container prune
docker image prune
docker volume prune

# Compose operations
docker-compose up -d
docker-compose down
docker-compose logs -f
docker-compose exec service bash

Common Flags

FlagDescriptionExample
-dDetached modedocker run -d nginx
-itInteractive terminaldocker run -it ubuntu bash
-pPort mappingdocker run -p 8080:80 nginx
-vVolume mountdocker run -v /host:/container nginx
-eEnvironment variabledocker run -e KEY=value nginx
--nameContainer namedocker run --name myapp nginx
--rmAuto-remove on exitdocker run --rm nginx
-fFollow logsdocker logs -f container