Quick Answer:
docker run -d --name myapp -p 8080:80 nginxstarts an nginx container in the background on port 8080.docker pslists running containers.docker logs myappshows logs.docker exec -it myapp bashopens a shell inside the container.docker stop myappstops it.
Container Lifecycle
Run a Container
# Basic run (foreground)
docker run nginx
# Detached (background) with name and port mapping
docker run -d --name web -p 8080:80 nginx
# Run and auto-remove when stopped
docker run --rm -it ubuntu bash
# Run with environment variables
docker run -d --name db -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 mysql:8
# Run with volume mount
docker run -d --name web -v /host/path:/container/path nginx
# Run with resource limits
docker run -d --name app --memory=512m --cpus=1.5 myapp
Manage Containers
# List running containers
docker ps
# List ALL containers (including stopped)
docker ps -a
# Stop a container
docker stop web
# Start a stopped container
docker start web
# Restart
docker restart web
# Kill (force stop)
docker kill web
# Remove a stopped container
docker rm web
# Remove a running container (force)
docker rm -f web
# Stop and remove ALL containers
docker stop $(docker ps -q) && docker rm $(docker ps -aq)
Inspect and Debug
# View logs
docker logs web
docker logs -f web # Follow (tail)
docker logs --tail 100 web # Last 100 lines
docker logs --since 1h web # Last hour
# Execute command inside running container
docker exec -it web bash # Interactive shell
docker exec web cat /etc/hosts # Run single command
# Container details
docker inspect web
docker inspect --format='{{.NetworkSettings.IPAddress}}' web
# Resource usage (live)
docker stats
docker stats web
# See running processes inside container
docker top web
# Copy files to/from container
docker cp localfile.txt web:/path/in/container/
docker cp web:/path/in/container/file.txt ./local/
Images
# List images
docker images
# Pull an image
docker pull nginx:latest
docker pull nginx:1.25-alpine # Specific version
# Build from Dockerfile
docker build -t myapp .
docker build -t myapp:v2 -f Dockerfile.prod .
# Tag an image
docker tag myapp myregistry.com/myapp:v2
# Push to registry
docker push myregistry.com/myapp:v2
# Remove an image
docker rmi nginx
# Remove all unused images
docker image prune -a
# Image history (see layers)
docker history myapp
# Save/load images (for transfer without registry)
docker save myapp > myapp.tar
docker load < myapp.tar
Volumes
# Create a named volume
docker volume create mydata
# List volumes
docker volume ls
# Inspect a volume
docker volume inspect mydata
# Use a volume in a container
docker run -d -v mydata:/var/lib/mysql mysql:8
# Bind mount (host directory)
docker run -d -v $(pwd)/data:/app/data myapp
# Remove a volume
docker volume rm mydata
# Remove ALL unused volumes
docker volume prune
Networks
# List networks
docker network ls
# Create a network
docker network create mynet
# Run container on a network
docker run -d --name web --network mynet nginx
# Connect running container to network
docker network connect mynet web
# Disconnect
docker network disconnect mynet web
# Inspect network (see connected containers)
docker network inspect mynet
# Containers on the same network can reach each other by name:
# From 'web' container: curl http://api:3000 (if 'api' is on same network)
Docker Compose
Basic compose.yml
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
depends_on:
- api
api:
build: ./api
environment:
- DATABASE_URL=postgres://db:5432/myapp
depends_on:
- db
db:
image: postgres:16-alpine
environment:
- POSTGRES_PASSWORD=secret
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Compose Commands
# Start all services (detached)
docker compose up -d
# Stop all services
docker compose down
# Stop and remove volumes too
docker compose down -v
# Rebuild and start
docker compose up -d --build
# View logs
docker compose logs -f
docker compose logs api # Single service
# Scale a service
docker compose up -d --scale api=3
# Execute command in a service
docker compose exec api bash
# List services
docker compose ps
Dockerfile Reference
# Start from a base image
FROM node:20-alpine
# Set working directory
WORKDIR /app
# Copy dependency files first (cache layer)
COPY package*.json ./
# Install dependencies
RUN npm ci --omit=dev
# Copy app source
COPY . .
# Expose port (documentation)
EXPOSE 3000
# Set environment variable
ENV NODE_ENV=production
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost:3000/health || exit 1
# Run the app
CMD ["node", "server.js"]
Multi-stage Build (smaller images)
# Build stage
FROM node:20 AS builder
WORKDIR /app
COPY . .
RUN npm ci && npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
CMD ["node", "dist/server.js"]
Cleanup
# Remove all stopped containers
docker container prune
# Remove all unused images
docker image prune -a
# Remove all unused volumes
docker volume prune
# Remove all unused networks
docker network prune
# Nuclear option: remove EVERYTHING unused
docker system prune -a --volumes
# Check disk usage
docker system df
Common Patterns
Run a one-off command
# Run a script and remove container after
docker run --rm -v $(pwd):/work -w /work python:3.12 python script.py
Quick database for development
# PostgreSQL
docker run -d --name pg -e POSTGRES_PASSWORD=dev -p 5432:5432 postgres:16-alpine
# MySQL
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=dev -p 3306:3306 mysql:8
# Redis
docker run -d --name redis -p 6379:6379 redis:alpine
# MongoDB
docker run -d --name mongo -p 27017:27017 mongo:7
Troubleshooting
# Container won't start? Check logs:
docker logs mycontainer
# Container exits immediately? Run interactively:
docker run -it myimage bash
# Can't connect to container port?
docker port mycontainer # Check port mapping
docker inspect mycontainer | grep IPAddress
# Out of disk space?
docker system df # Check usage
docker system prune -a # Clean up