Docker Basics
Docker Hub and Registries
Docker Hub (hub.docker.com) hosts pre-built container images. When you run:
docker run python:3.11-slimDocker pulls the image from Docker Hub if not present locally. The format is:
[REGISTRY/]USERNAME/IMAGE[:TAG]
- No registry specified → defaults to Docker Hub
- No username → official images (
python,ubuntu,nginx) - No tag → defaults to
latest
Common registries:
docker.io- Docker Hub (default)ghcr.io- GitHub Container Registry
gcr.io- Google Container Registrylocalhost:5000- Local registry
Building Images
A Dockerfile defines the build process:
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]Build with:
# Basic build
docker build -t myapp .
# With specific tag
docker build -t myapp:v1.0 .
# With build arguments
docker build --build-arg VERSION=1.0 -t myapp .
# From specific Dockerfile
docker build -f Dockerfile.dev -t myapp:dev .The -t flag tags the image. Without it, you get an unnamed image with only an ID.
Running Containers
Basic run patterns:
# Run interactively with terminal
docker run -it ubuntu bash
# Run in background (detached)
docker run -d nginx
# Remove container after exit
docker run --rm python:3.11 python -c "print('Hello')"
# Name the container
docker run --name webserver -d nginxContainer lifecycle:
docker runcreates and starts a new container- Container runs until main process exits
- Container remains in stopped state unless
--rmused
Port Mapping
Expose container ports to host:
# Map port 80 in container to 8080 on host
docker run -p 8080:80 nginx
# Map to specific interface
docker run -p 127.0.0.1:8080:80 nginx
# Map random host port
docker run -P nginx # Maps all exposed ports
# Multiple ports
docker run -p 8080:80 -p 8443:443 nginxFormat: -p [HOST_IP:]HOST_PORT:CONTAINER_PORT
Volume Mounts
Share data between host and container:
# Bind mount (absolute path required)
docker run -v /path/on/host:/path/in/container nginx
# Bind mount with pwd
docker run -v $(pwd)/data:/app/data python:3.11
# Read-only mount
docker run -v $(pwd)/config:/etc/config:ro nginx
# Named volume (Docker-managed)
docker volume create mydata
docker run -v mydata:/data postgres
# Anonymous volume
docker run -v /data postgres # Creates unnamed volumeBind mounts vs Volumes:
- Bind mounts: Direct host filesystem access, use absolute paths
- Named volumes: Docker-managed, portable, better for databases
- Anonymous volumes: Temporary, deleted with container
Environment Variables
Pass configuration to containers:
# Single variable
docker run -e DATABASE_URL=postgres://localhost/db postgres
# Multiple variables
docker run -e USER=admin -e PASSWORD=secret nginx
# From file
docker run --env-file .env python:3.11
# From host environment
docker run -e HOME myapp # Passes $HOME from hostEnvironment file format:
# .env file
DATABASE_URL=postgres://localhost/db
API_KEY=abc123
DEBUG=true
Container Management
Control running containers:
# List running containers
docker ps
# List all containers
docker ps -a
# Stop container (SIGTERM, then SIGKILL after 10s)
docker stop container_name
# Kill immediately (SIGKILL)
docker kill container_name
# Restart container
docker restart container_name
# Remove stopped container
docker rm container_name
# Remove running container
docker rm -f container_nameExecuting Commands
Run commands in existing containers:
# Execute command in running container
docker exec container_name ls -la
# Interactive shell in running container
docker exec -it container_name bash
# As different user
docker exec -u www-data container_name whoami
# With environment variable
docker exec -e DEBUG=true container_name python script.pyexec vs run:
runcreates NEW containerexecruns in EXISTING container
Names vs IDs vs Labels
Three ways to identify containers:
# By name (user-defined)
docker run --name myapp nginx
docker stop myapp
# By ID (auto-generated)
docker ps -q # Show only IDs
docker stop a1b2c3d4
# By label (metadata)
docker run --label env=prod --label team=backend nginx
docker ps --filter label=env=prodNames must be unique. IDs are unique hashes. Labels are key-value metadata for organization.
Command Reference
Quick lookup for common Docker commands:
docker build
Build image from Dockerfile:
docker build [OPTIONS] PATH
Options:
-t, --tag Name and tag (name:tag)
-f, --file Dockerfile path
--build-arg Set build-time variables
--no-cache Build without cache
--target Build specific stage
Examples:
docker build -t myapp:latest .
docker build -f Dockerfile.dev -t myapp:dev .
docker build --build-arg VERSION=1.0 -t myapp:v1 .docker run
Create and start container:
docker run [OPTIONS] IMAGE [COMMAND]
Options:
-d, --detach Run in background
-it Interactive with TTY
--rm Remove after exit
--name Container name
-p, --publish Port mapping (host:container)
-v, --volume Volume mount
-e, --env Environment variable
--network Connect to network
-u, --user Username or UID
Examples:
docker run -d --name web -p 8080:80 nginx
docker run -it --rm ubuntu bash
docker run -v $(pwd):/app -e DEBUG=true myappdocker ps
List containers:
docker ps [OPTIONS]
Options:
-a, --all Show all (including stopped)
-q, --quiet Only display IDs
-f, --filter Filter output
--format Format output
Examples:
docker ps # Running containers
docker ps -a # All containers
docker ps -q # Only IDs
docker ps --filter status=exited # Stopped containers
docker ps --format "table {{.Names}}\t{{.Status}}"docker exec
Execute in running container:
docker exec [OPTIONS] CONTAINER COMMAND
Options:
-i, --interactive Keep STDIN open
-t, --tty Allocate pseudo-TTY
-e, --env Set environment variable
-u, --user Username or UID
-w, --workdir Working directory
Examples:
docker exec myapp ls -la
docker exec -it myapp bash
docker exec -u root myapp apt update
docker exec -e VAR=value myapp envdocker stop/kill
Stop containers:
docker stop [OPTIONS] CONTAINER # Graceful (SIGTERM)
docker kill [OPTIONS] CONTAINER # Force (SIGKILL)
Options:
-t, --time Seconds to wait before killing (stop only)
Examples:
docker stop myapp # 10 second grace period
docker stop -t 30 myapp # 30 second grace period
docker kill myapp # Immediate termination
docker stop $(docker ps -q) # Stop all runningdocker rm/rmi
Remove containers and images:
docker rm [OPTIONS] CONTAINER # Remove container
docker rmi [OPTIONS] IMAGE # Remove image
Options:
-f, --force Force removal
-v, --volumes Remove associated volumes
Examples:
docker rm myapp # Remove stopped container
docker rm -f myapp # Force remove running
docker rm $(docker ps -aq) # Remove all containers
docker rmi myimage:tag # Remove image
docker rmi $(docker images -q) # Remove all imagesdocker logs
View container logs:
docker logs [OPTIONS] CONTAINER
Options:
-f, --follow Follow log output
-t, --timestamps Show timestamps
--tail Number of lines from end
--since Show logs since timestamp
Examples:
docker logs myapp
docker logs -f myapp # Follow live
docker logs --tail 50 myapp # Last 50 lines
docker logs --since 10m myapp # Last 10 minutesdocker cp
Copy files between container and host:
docker cp [OPTIONS] SRC DEST
Examples:
docker cp myapp:/app/config.json ./config.json # Container to host
docker cp ./data.csv myapp:/app/data.csv # Host to container
docker cp myapp:/logs ./backup/ # Copy directorydocker inspect
View detailed container/image info:
docker inspect [OPTIONS] NAME|ID
Examples:
docker inspect myapp # Full JSON output
docker inspect -f '{{.State.Status}}' myapp # Specific field
docker inspect -f '{{.NetworkSettings.IPAddress}}' myapp
docker inspect -f '{{json .Mounts}}' myapp | jq # With jqdocker volume
Manage volumes:
docker volume [COMMAND]
Commands:
create Create a volume
ls List volumes
rm Remove volumes
inspect Display volume details
prune Remove all unused volumes
Examples:
docker volume create mydata
docker volume ls
docker volume rm mydata
docker volume prune -f # Remove unused