Now that I've covered Docker basics and architecture, it's time to get hands-on with containers. This post covers the essential commands for running and managing containers - the skills you'll use daily when working with Docker.
Basic Container Management
Running Containers with docker run
The docker run command is probably the most important Docker command - it's how you start containers:
# Simple container run
docker run nginx
# Run in detached mode (background)
docker run -d nginx
# Run with a specific name
docker run --name my-webserver nginx
# Run and remove when stopped (temporary container)
docker run --rm nginx
When using the -d flag (detached mode):
- Container runs in the background
- Terminal isn't attached to the container output
- You get your command prompt back immediately
- Container continues running in the background
Container Lifecycle Management
Containers have a lifecycle you can control with these commands:
# Stop a running container
docker stop container-id
# Start a stopped container
docker start container-id
# Restart a container
docker restart container-id
# Kill a container (force stop)
docker kill container-id
# Remove a container
docker rm container-id
# Remove a running container (force)
docker rm -f container-id
Inspecting Containers
To see what's happening with your containers:
# List running containers
docker ps
# List all containers (including stopped)
docker ps -a
# Show container details
docker inspect container-id
# Show container stats (CPU, memory usage)
docker stats container-id
# Show processes running in a container
docker top container-id
The docker inspect command is particularly powerful - it shows all configuration details, network settings, mounts, and state information in JSON format.
Executing Commands in Containers
Sometimes you need to run a command inside a running container:
# Run an interactive shell
docker exec -it container-id bash
# Run a specific command
docker exec container-id ls -la
# Run as a specific user
docker exec -u root container-id whoami
The -it flags are important for interactive sessions
Container Interaction
Port Mapping
Containers are isolated by default. To access a container's service from your host:
# Map container port 80 to host port 8080
docker run -p 8080:80 nginx
# Map to all host interfaces
docker run -p 8080:80 nginx
# Map to specific host IP
docker run -p 127.0.0.1:8080:80 nginx
# Map to random host port
docker run -p 80 nginx
This is crucial for web applications or any service that needs to be accessible.
Environment Variables
Pass configuration to containers using environment variables:
# Set a single environment variable
docker run -e VARIABLE_NAME=value nginx
# Set multiple environment variables
docker run -e DB_HOST=localhost -e DB_PORT=5432 postgres
# Pass environment variables from a file
docker run --env-file ./env.list nginx
Many Docker images use environment variables for configuration (database connections, API keys, feature flags, etc.).
Working with Container Logs
Containers typically send their output to STDOUT and STDERR, which Docker captures:
# View container logs
docker logs container-id
Container Resource Constraints
Prevent containers from consuming too many resources:
# Memory limits
docker run --memory=512m nginx
docker run --memory=1g --memory-swap=2g nginx
# CPU limits
docker run --cpus=0.5 nginx # Limit to 50% of one CPU
docker run --cpu-shares=512 nginx # Relative CPU priority
Without these limits, a single container could potentially use all available system resources!
Docker System Prune
The docker system prune -f command is a maintenance command that cleans up unused Docker resources in one go:
docker system prune -f
What it removes:
- All stopped containers
- All networks not used by at least one container
- All dangling images (images with no tags and not referenced by any container)
- All build caches
Adding the -a flag will also remove all unused images (not just dangling ones):
docker system prune -a
I run this regularly to free up disk space, especially on development machines that tend to accumulate unused Docker resources over time.
Practical Examples
Here are some real-world examples I use regularly:
Running a Web Server
docker run -d --name webserver -p 8080:80 nginx
Then visit http://localhost:8080 in your browser.
Running a Database with Environment Variables
docker run -d --name db \
-e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_USER=myuser \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
postgres:13
Interactive Debugging Session
# Start an interactive Ubuntu container
docker run -it --rm ubuntu bash
# Or connect to a running container
docker exec -it container-id bash
Running a Container with Resource Limits
docker run -d --name limited-app \
--cpus=0.5 \
--memory=256m \
-p 3000:3000 \
my-nodejs-app
Useful Docker Commands Cheat Sheet
Here's a summary of essential commands:
# Container Management
docker run image-name # Create and start container
docker start container-id # Start container
docker stop container-id # Stop container
docker restart container-id # Restart container
docker rm container-id # Remove container
# Container Information
docker ps # List running containers
docker ps -a # List all containers
docker inspect container-id # Show container details
docker logs container-id # Show container logs
docker stats # Show container resource usage
# Container Interaction
docker exec -it container-id bash # Interactive shell
docker cp file.txt container-id:/path # Copy to container
docker cp container-id:/path/file.txt . # Copy from container
Conclusion
Working with Docker containers comes down to mastering these basic commands. I use most of these daily when developing with Docker. The pattern is usually: run containers with the right configuration, check if they're working as expected, troubleshoot with logs and exec if needed, and clean up when finished.
Next up, I'll cover working with Docker images - how to use existing images efficiently and build your own custom images using Dockerfiles.
Next up: "Working with Docker Images"
Top comments (0)