Docker Workflows¶
Common Docker operations for development.
Container Debugging¶
Shell Access¶
# Running container
docker exec -it container_name bash
docker exec -it container_name sh # If no bash
# Run new container with shell
docker run -it --rm image_name bash
# As root (when container runs as non-root)
docker exec -it -u root container_name bash
Inspecting Containers¶
# Container details
docker inspect container_name
# Specific fields
docker inspect -f '{{.State.Status}}' container_name
docker inspect -f '{{.NetworkSettings.IPAddress}}' container_name
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name
# Environment variables
docker exec container_name env
# Running processes
docker exec container_name ps aux
docker top container_name
Logs¶
# View logs
docker logs container_name
# Follow logs
docker logs -f container_name
# Tail last N lines
docker logs --tail 100 container_name
# With timestamps
docker logs -t container_name
# Since specific time
docker logs --since 2024-01-15T10:00:00 container_name
docker logs --since 1h container_name
# Compose logs
docker compose logs
docker compose logs -f api db
docker compose logs --tail 50 api
File Operations¶
# Copy from container
docker cp container_name:/app/data.json ./data.json
# Copy to container
docker cp ./config.yaml container_name:/app/config.yaml
# View file in container
docker exec container_name cat /app/config.yaml
Resource Usage¶
# Live stats
docker stats
docker stats container_name
# One-time stats
docker stats --no-stream
# Disk usage
docker system df
docker system df -v # Verbose
Docker Compose¶
Basic Operations¶
# Start all services
docker compose up
# Start in background
docker compose up -d
# Start specific services
docker compose up -d api db
# Rebuild and start
docker compose up -d --build
# Force recreate
docker compose up -d --force-recreate
# Stop services
docker compose stop
# Stop and remove
docker compose down
docker compose down -v # Include volumes
docker compose down --rmi local # Include local images
Service Management¶
# Restart service
docker compose restart api
# Scale service
docker compose up -d --scale worker=3
# Rebuild single service
docker compose build api
docker compose up -d api
# Pull latest images
docker compose pull
docker compose up -d
Executing Commands¶
# Run command in running container
docker compose exec api python manage.py shell
docker compose exec db psql -U postgres
# Run one-off command (new container)
docker compose run --rm api python manage.py migrate
docker compose run --rm api pytest
# Run with environment override
docker compose run -e DEBUG=1 --rm api python script.py
Profiles¶
# docker-compose.yml
services:
api:
build: .
profiles: ["app"]
db:
image: postgres:15
worker:
build: .
profiles: ["app", "worker"]
debug:
image: busybox
profiles: ["debug"]
# Start specific profiles
docker compose --profile app up -d
docker compose --profile debug up -d debug
# Start all
docker compose --profile app --profile worker up -d
Networking¶
Network Inspection¶
# List networks
docker network ls
# Inspect network
docker network inspect bridge
docker network inspect compose_default
# Find container IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container
# Container connectivity
docker exec container_name ping other_container
docker exec container_name curl http://api:8000/health
Custom Networks¶
# Create network
docker network create mynetwork
# Run container on network
docker run -d --network mynetwork --name api myimage
# Connect existing container
docker network connect mynetwork container_name
# Disconnect
docker network disconnect mynetwork container_name
Port Mapping¶
# View port mappings
docker port container_name
# Map specific port
docker run -p 8080:80 nginx
docker run -p 127.0.0.1:8080:80 nginx # Bind to localhost only
# Expose all ports
docker run -P nginx # Random host ports
Volume Management¶
Volume Operations¶
# List volumes
docker volume ls
# Create volume
docker volume create mydata
# Inspect volume
docker volume inspect mydata
# Remove volume
docker volume rm mydata
# Remove unused volumes
docker volume prune
Bind Mounts¶
# Mount directory
docker run -v $(pwd):/app image_name
docker run -v /host/path:/container/path image_name
# Read-only mount
docker run -v $(pwd):/app:ro image_name
# Named volume
docker run -v mydata:/app/data image_name
Volume Backup¶
# Backup volume to tarball
docker run --rm -v mydata:/data -v $(pwd):/backup alpine \
tar czf /backup/mydata.tar.gz -C /data .
# Restore volume from tarball
docker run --rm -v mydata:/data -v $(pwd):/backup alpine \
tar xzf /backup/mydata.tar.gz -C /data
Building Images¶
Build Commands¶
# Basic build
docker build -t myapp .
# With tag
docker build -t myapp:v1.0 .
docker build -t registry.example.com/myapp:latest .
# No cache
docker build --no-cache -t myapp .
# Build arg
docker build --build-arg VERSION=1.0 -t myapp .
# Target stage
docker build --target builder -t myapp:builder .
# From different file
docker build -f Dockerfile.prod -t myapp:prod .
Multi-Stage Build Example¶
# Dockerfile
FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
FROM python:3.12-slim AS runtime
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "main.py"]
# Build final stage
docker build -t myapp .
# Build builder stage only
docker build --target builder -t myapp:builder .
Build Cache¶
# Use BuildKit (better caching)
DOCKER_BUILDKIT=1 docker build -t myapp .
# Cache from previous build
docker build --cache-from myapp:latest -t myapp:new .
# Export cache
docker build --build-arg BUILDKIT_INLINE_CACHE=1 -t myapp .
Debugging Techniques¶
Container Won't Start¶
# Check logs
docker logs container_name
# Check exit code
docker inspect -f '{{.State.ExitCode}}' container_name
# Run with entrypoint override
docker run -it --entrypoint bash image_name
# Run with command override
docker run -it image_name bash
Networking Issues¶
# Check DNS resolution
docker exec container_name nslookup api
# Check connectivity
docker exec container_name curl -v http://api:8000
# Check iptables (host)
sudo iptables -L -n
# Check docker networks
docker network inspect bridge
Permission Issues¶
# Run as root
docker exec -u root container_name ls -la /app
# Check file ownership
docker exec container_name ls -la /app
# Fix permissions
docker exec -u root container_name chown -R app:app /app
Resource Issues¶
# Check memory usage
docker stats container_name
# Check disk usage in container
docker exec container_name df -h
# Check available disk
docker system df
Cleanup¶
Selective Cleanup¶
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune # Dangling only
docker image prune -a # All unused
# Remove unused volumes
docker volume prune
# Remove unused networks
docker network prune
Full Cleanup¶
# Remove everything unused
docker system prune
# Include volumes
docker system prune --volumes
# Include all images
docker system prune -a --volumes
# Force (no confirmation)
docker system prune -af --volumes
Compose Cleanup¶
# Stop and remove containers, networks
docker compose down
# Include volumes
docker compose down -v
# Include images
docker compose down --rmi all
docker compose down --rmi local # Only locally built
Development Patterns¶
Hot Reload with Volumes¶
# docker-compose.yml
services:
api:
build: .
volumes:
- .:/app
- /app/node_modules # Exclude node_modules
command: bun run dev
Database Persistence¶
services:
db:
image: postgres:15
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: postgres
volumes:
pgdata:
Override for Development¶
# docker-compose.override.yml (auto-loaded)
services:
api:
build:
context: .
target: development
volumes:
- .:/app
environment:
DEBUG: 1