Expert ReviewedUpdated 2025developer
developer
14 min readJuly 7, 2024Updated Nov 5, 2025

Docker Commands Guide: Essential Commands for Container Management

Master Docker containerization with essential commands for building, running, and managing containers. Includes Dockerfile best practices and Docker Compose workflows.

Docker revolutionized software deployment by packaging applications with their dependencies into portable containers. Whether you are developing locally, deploying to production, or managing microservices, mastering Docker commands is essential for modern development workflows.

Key Takeaways

  • 1
    docker run -d -p 8080:80 runs containers in background with port mapping
  • 2
    Use docker exec -it container sh for interactive debugging
  • 3
    Multi-stage Dockerfile builds create smaller production images
  • 4
    Named volumes persist data beyond container lifecycle
  • 5
    docker compose up -d manages multi-container applications

1Basic Docker Commands

Start with these fundamental commands for pulling images and running containers.
# Check Docker version and info
docker --version
docker info

# Pull an image from Docker Hub
docker pull nginx
docker pull node:20-alpine
docker pull postgres:16

# List downloaded images
docker images
docker image ls

# Run a container
docker run nginx                           # Run in foreground
docker run -d nginx                        # Run detached (background)
docker run -it ubuntu bash                 # Interactive with terminal
docker run --name my-nginx nginx           # Assign name
docker run --rm nginx                      # Auto-remove when stopped

# Port mapping
docker run -p 8080:80 nginx                # Host:Container
docker run -p 3000:3000 node-app

# Environment variables
docker run -e NODE_ENV=production node-app
docker run --env-file .env node-app
Common docker run flags
FlagPurpose
-dRun container in detached mode (background)
-itInteractive mode with terminal
-pMap port (host:container)
-eSet environment variable
-vMount volume
--nameAssign container name
--rmAuto-remove container on exit

2Container Management

Learn to list, start, stop, and remove containers effectively.
# List containers
docker ps                                  # Running containers
docker ps -a                               # All containers (including stopped)
docker ps -q                               # Only container IDs

# Start/Stop containers
docker start my-container
docker stop my-container
docker restart my-container

# Graceful stop with timeout
docker stop -t 30 my-container             # Wait 30 seconds before kill

# Force stop (SIGKILL)
docker kill my-container

# Remove containers
docker rm my-container                     # Remove stopped container
docker rm -f my-container                  # Force remove (even if running)
docker container prune                     # Remove all stopped containers

# View container logs
docker logs my-container
docker logs -f my-container                # Follow (tail)
docker logs --tail 100 my-container        # Last 100 lines
docker logs --since 1h my-container        # Last hour

# Execute commands in running container
docker exec my-container ls /app
docker exec -it my-container bash          # Interactive shell
docker exec -it my-container sh            # For Alpine images

# Copy files to/from container
docker cp local-file.txt my-container:/app/
docker cp my-container:/app/logs ./logs
Use docker exec -it container-name sh for Alpine-based images (they do not have bash). For debugging, docker logs -f is invaluable for real-time log streaming.

Image Management

Docker images are the blueprints for containers. Learn to build, tag, and manage them.
# List images
docker images
docker image ls
docker images -a                           # Include intermediate layers

# Build image from Dockerfile
docker build -t my-app .
docker build -t my-app:v1.0 .              # With tag
docker build -f Dockerfile.prod -t my-app .  # Custom Dockerfile
docker build --no-cache -t my-app .        # Without cache

# Tag images
docker tag my-app:latest my-app:v1.0
docker tag my-app user/my-app:latest       # For Docker Hub

# Push to registry
docker push user/my-app:latest
docker push user/my-app:v1.0

# Remove images
docker rmi nginx
docker rmi nginx:latest
docker rmi -f nginx                        # Force remove
docker image prune                         # Remove dangling images
docker image prune -a                      # Remove all unused images

# Save/Load images (for transfer)
docker save my-app > my-app.tar
docker load < my-app.tar

# Inspect image
docker inspect nginx
docker history nginx                       # View layer history
docker image prune -a removes ALL images not used by at least one container. Be careful in production environments where you might need to rollback.

4Dockerfile Best Practices

A well-structured Dockerfile creates smaller, faster, and more secure images.
# Basic Node.js Dockerfile
FROM node:20-alpine

WORKDIR /app

# Copy package files first (layer caching)
COPY package*.json ./
RUN npm ci --only=production

# Copy source code
COPY . .

# Set user (security best practice)
USER node

EXPOSE 3000
CMD ["node", "server.js"]
# Multi-stage build for smaller images
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
**Dockerfile Best Practices:**
  • Use specific base image tags (node:20-alpine, not node:latest)
  • Copy package files before source code for better layer caching
  • Use multi-stage builds to reduce final image size
  • Run as non-root user (USER directive)
  • Use .dockerignore to exclude unnecessary files
  • Combine RUN commands to reduce layers
  • Clean up package manager caches in the same RUN command
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
.env
.env.local
Dockerfile
docker-compose*.yml
README.md
.vscode
coverage
.next

5Volumes and Data Persistence

Containers are ephemeral—data is lost when they are removed. Volumes persist data independently of container lifecycle.
# Create named volume
docker volume create my-data

# List volumes
docker volume ls

# Inspect volume
docker volume inspect my-data

# Mount volume to container
docker run -v my-data:/app/data postgres

# Bind mount (host directory)
docker run -v $(pwd)/data:/app/data nginx
docker run -v /absolute/path:/app/data nginx

# Read-only mount
docker run -v my-data:/app/data:ro nginx

# Anonymous volume
docker run -v /app/node_modules node-app

# Remove volumes
docker volume rm my-data
docker volume prune                        # Remove unused volumes

# Backup volume data
docker run --rm -v my-data:/data -v $(pwd):/backup \
  alpine tar cvf /backup/backup.tar /data

# Restore volume data
docker run --rm -v my-data:/data -v $(pwd):/backup \
  alpine tar xvf /backup/backup.tar -C /
Named volumes are managed by Docker and stored in /var/lib/docker/volumes/. Bind mounts map directly to host paths and are better for development when you need to edit files on your host machine.

6Docker Networking

Docker networks enable containers to communicate with each other and the outside world.
# List networks
docker network ls

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

# Run container on network
docker run --network my-network --name web nginx
docker run --network my-network --name api node-app

# Connect existing container to network
docker network connect my-network my-container
docker network disconnect my-network my-container

# Inspect network
docker network inspect my-network

# Remove network
docker network rm my-network
docker network prune                       # Remove unused networks

# Container DNS
# Containers on same network can reach each other by name
# In api container: curl http://web:80

# Host networking (Linux only)
docker run --network host nginx            # Uses host network stack
Docker network drivers
Network TypeUse Case
bridgeDefault. Isolated network for containers on same host
hostContainer uses host network directly (no isolation)
noneNo networking (completely isolated)
overlayMulti-host networking (Docker Swarm)

7Docker Compose

Docker Compose defines and runs multi-container applications with a single YAML file.
# docker-compose.yml
version: '3.8'

services:
  web:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgres://db:5432/myapp
    depends_on:
      - db
      - redis
    volumes:
      - ./web:/app
      - /app/node_modules

  api:
    build:
      context: ./api
      dockerfile: Dockerfile.prod
    ports:
      - "8080:8080"
    env_file:
      - .env
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: secret
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    volumes:
      - redis-data:/data

volumes:
  postgres-data:
  redis-data:
# Start services
docker compose up
docker compose up -d                       # Detached mode
docker compose up --build                  # Rebuild images

# Stop services
docker compose down
docker compose down -v                     # Also remove volumes
docker compose down --rmi all              # Also remove images

# View logs
docker compose logs
docker compose logs -f web                 # Follow specific service
docker compose logs --tail 100             # Last 100 lines

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

# Execute command in service
docker compose exec web bash
docker compose exec db psql -U user myapp

# View running services
docker compose ps

# Rebuild specific service
docker compose build web
docker compose up -d --no-deps --build web

8Cleanup and Optimization

Docker can consume significant disk space. Regular cleanup keeps your system healthy.
# View disk usage
docker system df
docker system df -v                        # Verbose

# Remove unused data
docker system prune                        # Stopped containers, dangling images, unused networks
docker system prune -a                     # Also remove unused images
docker system prune -a --volumes           # Also remove volumes

# Selective cleanup
docker container prune                     # Stopped containers only
docker image prune                         # Dangling images only
docker image prune -a                      # All unused images
docker volume prune                        # Unused volumes
docker network prune                       # Unused networks

# Remove all containers
docker rm $(docker ps -aq)
docker rm -f $(docker ps -aq)              # Force remove running ones

# Remove all images
docker rmi $(docker images -q)

# Remove containers older than 24 hours
docker container prune --filter "until=24h"
Run docker system prune regularly in development. In CI/CD pipelines, always clean up after builds to avoid disk space issues.

9Debugging Containers

When containers misbehave, these commands help diagnose and fix issues.
# View container details
docker inspect my-container
docker inspect --format '{{.State.Status}}' my-container
docker inspect --format '{{.NetworkSettings.IPAddress}}' my-container

# View resource usage
docker stats                               # All containers
docker stats my-container                  # Specific container

# View running processes
docker top my-container

# View port mappings
docker port my-container

# View file changes in container
docker diff my-container

# Debug crashed container
docker logs my-container --tail 50
docker inspect my-container | grep -A 10 State

# Run shell in stopped container
docker commit crashed-container debug-image
docker run -it debug-image sh

# Health check status
docker inspect --format '{{.State.Health.Status}}' my-container

# Events log
docker events
docker events --since 1h
docker events --filter container=my-container
For crashed containers, docker logs is your first stop. If the container exited immediately, use docker inspect to check the State.ExitCode and State.Error fields.

Boost Your Developer Workflow

Free online tools for encoding, formatting, hashing, and more.

Explore Dev Tools

Frequently Asked Questions

What is the difference between docker run and docker start?
docker run creates a NEW container from an image and starts it. docker start starts an EXISTING stopped container. Use run for first-time container creation, start to resume stopped containers.
How do I access a running container terminal?
Use docker exec -it container-name bash (or sh for Alpine images). The -it flags allocate a pseudo-TTY and keep STDIN open, allowing interactive shell access.
What is the difference between COPY and ADD in Dockerfile?
COPY simply copies files from host to image. ADD has extra features: it can extract tar archives and download URLs. Best practice: use COPY unless you specifically need ADD features, as COPY is more predictable.
How do I persist data when a container is removed?
Use Docker volumes. Named volumes (docker volume create) are managed by Docker. Bind mounts map host directories. Both persist data independently of container lifecycle.
Why is my Docker image so large?
Common causes: using full OS base images (use alpine variants), not using multi-stage builds, copying unnecessary files (use .dockerignore), not cleaning package manager caches, and too many layers.