Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Docker Command Guide

A comprehensive guide to installing, managing, and using Docker containers.

What is Docker?

Docker is a tool that lets you package applications into containers — lightweight, portable environments that run consistently across machines.

With Docker, you can:

  • Package code, dependencies, and system tools into one unit
  • Run the same app on your laptop, server, or cloud
  • Avoid "it works on my machine" problems
  • Test, scale, and deploy software faster

Docker helps developers isolate applications and ship them with confidence.

Think of a container as a box with everything your app needs to run — regardless of where it's deployed.

Familiarity with Linux CLI

If you’ve used the Linux command line before, many Docker commands will feel familiar. Docker's CLI follows similar patterns for file navigation, process control, and permission handling. This makes learning Docker more intuitive for users with a Linux or Unix-like background.

Installation

Ubuntu/Debian

sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
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
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

CentOS/RHEL/Fedora

sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io

Arch Linux

sudo pacman -Syu docker

Void Linux

sudo xbps-install -S docker
sudo ln -s /etc/sv/docker /var/service/docker

Alpine Linux

sudo apk update
sudo apk add docker
sudo rc-update add docker boot

Gentoo

sudo emerge --ask app-containers/docker
sudo rc-update add docker default
sudo /etc/init.d/docker start

NixOS

Enable Docker in your configuration file (/etc/nixos/configuration.nix):

virtualisation.docker.enable = true;

Then apply the changes:

sudo nixos-rebuild switch

OpenSUSE (Tumbleweed / Leap)

sudo zypper refresh
sudo zypper install docker

Generic Linux (via Docker convenience script)

For unsupported or minimal distros:

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

macOS

Install Docker Desktop from https://docker.com/products/docker-desktop

Windows

Install Docker Desktop from https://docker.com/products/docker-desktop

Post-Installation Setup

Add your user to docker group (Linux):

sudo usermod -aG docker $USER
newgrp docker

Start Docker service:

sudo systemctl start docker
sudo systemctl enable docker

Verify installation:

docker --version # shows currently installed version
docker run hello-world

Basic Container Operations

Run a container

docker run ubuntu

Run container interactively

docker run -it ubuntu bash

Run container in background (detached)

docker run -d nginx

Run with custom name

docker run --name my-nginx nginx

Run with port mapping

docker run -p 8080:80 nginx

This means the container's internal port 80 (where the Nginx server is listening) is mapped to port 8080 on your local machine. When this container is running, users can access the web server by visiting http://localhost:8080 on the host system. Without this mapping, the service inside the container would not be reachable from outside the container. Port mapping is essential for exposing containerised services to the host or public network.

Run with volume mounting

docker run -v /host/path:/container/path ubuntu

Run with environment variables

docker run -e MYSQL_ROOT_PASSWORD=mypassword mysql

Run and remove when stopped

docker run --rm ubuntu echo "Hello World"

Container Management

List running containers

docker ps

ps stands for process status

List all containers (including stopped)

docker ps -a

Stop a container

docker stop container_name

Start a stopped container

docker start container_name

Restart a container

docker restart container_name

Remove a container

docker rm container_name

Remove all stopped containers

docker container prune

Force remove a running container

docker rm -f container_name

Execute command in running container

docker exec -it container_name bash

The command docker exec -it container_name bash lets you run an interactive shell inside a running container. exec executes a command without restarting the container, -i keeps input open, and -t allocates a terminal. Running bash starts a shell session, useful for debugging, managing files, or exploring the container like SSH.

Copy files to/from container

docker cp file.txt container_name:/path/to/destination
docker cp container_name:/path/to/file.txt ./local/path

View container logs

docker logs container_name

Follow logs in real-time

docker logs -f container_name

View container resource usage

docker stats

Inspect container details

docker inspect container_name

Image Management

List local images

docker images

Pull an image from registry

docker pull ubuntu:20.04

Remove an image

docker rmi image_name

Remove unused images

docker image prune

Remove all unused images

docker image prune -a

Build image from Dockerfile

docker build -t my-app .

Build with custom Dockerfile name

docker build -t my-app -f custom.dockerfile .

Tag an image

docker tag source_image:tag target_image:tag

Push image to registry

docker push username/image_name:tag

Search for images

docker search nginx

View image history

docker history image_name

Docker Compose

docker compose vs docker-compose

There are two ways to use Docker Compose:

  • docker-compose (hyphenated): This is the older Python-based standalone command.
  • docker compose (space-separated): This is the newer plugin-based command integrated into the Docker CLI.

Key Differences

Featuredocker-composedocker compose
CLI styleHyphenated: docker-compose upSubcommand: docker compose up
InstallationSeparate binaryBundled with Docker (v20.10+)
Written inPythonGo (as a Docker CLI plugin)
LifecycleBeing deprecatedActively maintained
PerformanceSlightly slowerFaster and better Docker integration
CompatibilityWidely supportedPreferred for modern setups

Which Should You Use?

Use docker compose (with a space) if you're using Docker v20.10+, as it is the officially supported method moving forward. The old docker-compose is being phased out and may not receive future updates.

Tip: If you're still using docker-compose, consider upgrading your Docker CLI and migrating to docker compose.

Migration Note

Both commands support the same docker-compose.yml file format, so switching typically requires no changes to your YAML files—just the command syntax changes.

Start services defined in docker-compose.yml

Note: docker-compose command will be depricated. Use docker compose instead.

docker compose up

Start services in background

docker compose up -d

Stop services

docker compose down

View running services

docker compose ps

View logs

docker compose logs

Follow logs

docker compose logs -f

Rebuild and start services

docker compose up --build

Scale a service

docker compose up --scale web=3

Execute command in service

docker compose exec service_name bash

Networking

List networks

docker network ls

Create a network

docker network create my-network

Connect container to network

docker network connect my-network container_name

Disconnect container from network

docker network disconnect my-network container_name

Run container on specific network

docker run --network my-network nginx

Remove network

docker network rm my-network

Inspect network

docker network inspect my-network

Volumes

List volumes

docker volume ls

Create a volume

docker volume create my-volume

Remove a volume

docker volume rm my-volume

Remove unused volumes

docker volume prune

Inspect volume

docker volume inspect my-volume

Run container with named volume

docker run -v my-volume:/data ubuntu

Run container with bind mount

docker run -v /host/path:/container/path ubuntu

Common Docker Setups

Web Server (Nginx)

docker run -d --name web-server -p 80:80 -v /path/to/html:/usr/share/nginx/html nginx

Database (MySQL)

docker run -d --name mysql-db -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=mydb -p 3306:3306 mysql:8.0

Database (PostgreSQL)

docker run -d --name postgres-db -e POSTGRES_PASSWORD=password -e POSTGRES_DB=mydb -p 5432:5432 postgres:13

Redis Cache

docker run -d --name redis-cache -p 6379:6379 redis:alpine

WordPress with MySQL

docker run -d --name wordpress-db -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=wordpress mysql:8.0
docker run -d --name wordpress-site --link wordpress-db:mysql -p 8080:80 -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_DB_PASSWORD=password wordpress

Node.js Application

docker run -d --name node-app -p 3000:3000 -v /path/to/app:/usr/src/app -w /usr/src/app node:16 npm start

Dockerfile Examples

Basic Node.js Dockerfile

Create a file named Dockerfile:

FROM node:16-alpine
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

Build and run:

docker build -t my-node-app .
docker run -p 3000:3000 my-node-app

Basic Python Dockerfile

FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

Multi-stage Build Example

FROM node:16 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Docker Compose Examples

Basic docker-compose.yml

version: '3.8'
services:
  web:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
  
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: myapp
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

WordPress with Docker Compose

version: '3.8'
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "8080:80"
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wordpress
      WORDPRESS_DB_PASSWORD: password
      WORDPRESS_DB_NAME: wordpress
    depends_on:
      - db
  
  db:
    image: mysql:8.0
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: password
      MYSQL_ROOT_PASSWORD: rootpassword
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Note: adding secrets such as passwords in docker compose file is not secure. It is advised to use a secrets manager (eg. docker secrets) to store secrets or store secrets in the .env directory.

System Maintenance

View Docker system info

docker system info

View disk usage

docker system df

Clean up everything

docker system prune -a

Clean up with volumes

docker system prune -a --volumes

Remove all containers

docker rm -f $(docker ps -aq)

Remove all images

docker rmi -f $(docker images -q)

Update all images

docker images --format "table {{.Repository}}:{{.Tag}}" | tail -n +2 | xargs -L1 docker pull

Registry Operations

Login to Docker Registry

docker login

Login to private registry

docker login registry.example.com

Tag for registry

docker tag my-app username/my-app:v1.0

Push to registry

docker push username/my-app:v1.0

Pull from private registry

docker pull registry.example.com/my-app:v1.0

Troubleshooting

Container won't start

Check logs:

docker logs container_name

Permission denied errors

Fix ownership (Linux):

sudo chown -R $USER:$USER /path/to/files

Port already in use

Find process using port:

sudo lsof -i :8080

Kill process:

sudo kill -9 PID

Out of disk space

Clean up Docker:

docker system prune -a --volumes

Container runs but app doesn't work

Check if container is listening on correct port:

docker exec container_name netstat -tlnp

Can't connect to Docker daemon

Start Docker service:

sudo systemctl start docker

Add user to docker group:

sudo usermod -aG docker $USER

Security Best Practices

Run containers as non-root user

docker run --user 1000:1000 ubuntu

Limit container resources

docker run --memory="256m" --cpus="1.0" ubuntu

Use read-only filesystem

docker run --read-only ubuntu

Drop capabilities

docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

Scan images for vulnerabilities

docker scout quickview image_name

Use official images when possible

docker pull nginx:alpine

Performance Tips

Use specific image tags

Instead of:

docker pull nginx:latest

Use:

docker pull nginx:1.21-alpine

Use multi-stage builds

Reduces final image size by excluding build dependencies.

Use .dockerignore

Create .dockerignore file to exclude unnecessary files:

node_modules
.git
*.log
.env

Optimise layer caching

Place frequently changing instructions at the bottom of Dockerfile.

Use Alpine images

docker pull node:16-alpine

Smaller size than full distributions.

Common Workflows

Development Workflow

# 1. Create Dockerfile
nano Dockerfile

# 2. Build image
docker build -t my-app .

# 3. Run container
docker run -d -p 8080:80 --name my-app-container my-app

# 4. Check logs
docker logs my-app-container

# 5. Update and rebuild
docker stop my-app-container
docker rm my-app-container
docker build -t my-app .
docker run -d -p 8080:80 --name my-app-container my-app

Production Deployment

# 1. Pull latest code
git pull origin main

# 2. Build production image
docker build -t my-app:prod .

# 3. Stop old container
docker stop my-app-prod

# 4. Remove old container
docker rm my-app-prod

# 5. Start new container
docker run -d --name my-app-prod -p 80:8080 my-app:prod

Further Reading

Quick Reference

CommandDescription
docker run -itRun interactively
docker run -dRun in background
docker psList running containers
docker ps -aList all containers
docker stopStop container
docker rmRemove container
docker imagesList images
docker rmiRemove image
docker exec -itExecute command in container
docker logsView container logs
docker buildBuild image from Dockerfile
docker compose upStart services
docker compose downStop services
docker system pruneClean up unused resources