Docker Run
Introduction
docker run
is one of the most fundamental commands in Docker. It serves as your gateway to creating and starting containers from Docker images. When you execute docker run
, Docker performs several operations behind the scenes: it finds the specified image, creates a new container based on that image, and then starts the container with the options you've provided.
Think of Docker images as blueprints and containers as the actual instances created from these blueprints. The docker run
command is what brings these blueprints to life!
Basic Syntax
The basic syntax for the docker run
command is:
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Let's break down each component:
[OPTIONS]
: Optional flags that modify how the container runsIMAGE
: The Docker image you want to use (e.g., ubuntu, nginx)[COMMAND]
: Optional command to execute when the container starts[ARG...]
: Optional arguments to pass to the command
Basic Examples
Running a Simple Container
Let's start with running a basic Ubuntu container:
docker run ubuntu
Output:
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7b1a6ab2e44d: Pull complete
Digest: sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Status: Downloaded newer image for ubuntu:latest
What happened? Docker:
- Looked for the Ubuntu image locally
- Did not find it, so it pulled it from Docker Hub
- Created a container
- Started the container
- The container immediately exited because we didn't specify any command to keep it running
Running a Container in Interactive Mode
To interact with a container, we use the -i
(interactive) and -t
(terminal) flags:
docker run -it ubuntu bash
Output:
root@7a8f8c3d2b1a:/#
Now you're inside the container with a bash shell! You can run commands just like you would on an Ubuntu system.
Essential Options
Let's explore some of the most commonly used options with docker run
:
Container Identification
docker run --name my-ubuntu-container ubuntu
This assigns a name to your container, making it easier to reference later.
Detached Mode
docker run -d nginx
Output:
7a8f8c3d2b1a8e9f0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3
The -d
flag runs the container in the background (detached mode) and returns the container ID.
Port Mapping
docker run -d -p 8080:80 nginx
This maps port 8080 on your host to port 80 in the container, allowing you to access the nginx web server by visiting http://localhost:8080
in your browser.
Volume Mounting
docker run -v /host/path:/container/path ubuntu
This mounts a directory from your host system into the container, enabling data persistence and sharing.
Environment Variables
docker run -e DB_HOST=localhost -e DB_PORT=5432 my-app
Sets environment variables inside the container.
Practical Examples
Let's look at some real-world examples of using docker run
:
Running a Web Server
docker run -d --name my-website -p 8080:80 -v $(pwd)/website:/usr/share/nginx/html nginx
This command:
- Runs an Nginx web server in detached mode
- Names it "my-website"
- Maps port 8080 on your host to port 80 in the container
- Mounts your local "website" directory to Nginx's HTML directory
Now you can edit files in your local "website" directory, and they'll be served by Nginx.
Running a Database
docker run -d \
--name my-postgres \
-e POSTGRES_PASSWORD=mysecretpassword \
-e POSTGRES_USER=myuser \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
-v postgres-data:/var/lib/postgresql/data \
postgres
This creates a PostgreSQL database container with:
- Custom username, password, and database name
- Port mapping to access the database from your host
- A named volume for data persistence
Running a Multi-container Application
For a web application with a separate database, you might run:
# Database container
docker run -d --name app-db \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=app_data \
-e MYSQL_USER=app_user \
-e MYSQL_PASSWORD=app_pass \
--network app-network \
mysql:5.7
# Web application container
docker run -d --name app-web \
-p 3000:3000 \
--network app-network \
-e DB_HOST=app-db \
-e DB_USER=app_user \
-e DB_PASSWORD=app_pass \
-e DB_NAME=app_data \
my-web-app
Note: For this to work, you'd first need to create a network with docker network create app-network
.
Docker Run Workflow
Here's a visual representation of what happens when you run docker run
:
Common Flags Reference Table
Flag | Description | Example |
---|---|---|
-d, --detach | Run container in background | docker run -d nginx |
-p, --publish | Map container port to host | docker run -p 8080:80 nginx |
-v, --volume | Mount a volume | docker run -v /host/path:/container/path ubuntu |
-e, --env | Set environment variables | docker run -e VAR=value image |
--name | Assign a name to the container | docker run --name web nginx |
-i, --interactive | Keep STDIN open | Used with -t for interactive shells |
-t, --tty | Allocate a pseudo-TTY | Used with -i for interactive shells |
--rm | Remove container when it exits | docker run --rm alpine echo "Hello" |
--network | Connect to a network | docker run --network my-net image |
--restart | Restart policy for container | docker run --restart always nginx |
Resource Constraints
Docker allows you to limit resources used by containers:
# Limit memory to 512MB
docker run --memory="512m" nginx
# Limit CPU to 0.5 cores
docker run --cpus="0.5" nginx
# Set CPU priority (higher = more priority)
docker run --cpu-shares="512" nginx
Best Practices
-
Always use specific image tags rather than
latest
to ensure reproducibility:bashdocker run nginx:1.21.3
-
Use
--rm
flag for temporary containers to avoid cluttering your system:bashdocker run --rm alpine echo "This container will be removed after exit"
-
Name your containers for easier management:
bashdocker run --name web-app nginx
-
Use volume mounts for persistent data:
bashdocker run -v data-volume:/app/data my-app
-
Set resource limits to prevent one container from consuming all system resources:
bashdocker run --memory="1g" --cpus="1.0" my-app
-
Use environment variables for configuration rather than hardcoding values:
bashdocker run -e LOG_LEVEL=info -e API_KEY=12345 my-app
Common Errors and Troubleshooting
Image Not Found
Unable to find image 'non-existent-image:latest' locally
docker: Error response from daemon: pull access denied for non-existent-image, repository does not exist or may require 'docker login'.
Solution: Double-check the image name and ensure it exists on Docker Hub or your private registry.
Port Already Allocated
docker: Error response from daemon: driver failed programming external connectivity on endpoint my-container: Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use.
Solution: Choose a different host port that isn't already in use.
Insufficient Permissions
docker: Got permission denied while trying to connect to the Docker daemon socket.
Solution: Run the command with sudo
or add your user to the docker group.
Container Exits Immediately
If your container stops right after starting, it might be because:
- The main process completed its task
- There was an error in the application
- The container lacks a foreground process
Solution: Check logs with docker logs <container-id>
and ensure your application runs in the foreground.
Summary
The docker run
command is your entry point to working with Docker containers. In this guide, we've covered:
- Basic usage and syntax
- Common options and flags
- Practical real-world examples
- Best practices for container management
- Troubleshooting common issues
With these skills, you're well-equipped to start deploying applications in containers and taking advantage of Docker's flexibility and power.
Where to Go Next
Now that you understand docker run
, you might want to explore:
- Docker Compose for managing multi-container applications
- Docker Volumes for more advanced data persistence
- Docker Networks for container communication
- Custom Dockerfiles to create your own images
Exercises
- Run an Ubuntu container in interactive mode and install the
nano
text editor. - Create a container running Nginx, map it to port 8080, and replace the default webpage with your own HTML content.
- Run a MySQL container with custom environment variables and connect to it using the mysql client.
- Try running a container with memory constraints and observe what happens when your application exceeds those limits.
- Use the
--restart
flag to create a container that automatically restarts if it crashes.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)