Mastering Docker Run: Essential Command Options Explained
Learn the Docker run flags you use most: ports, volumes, env vars, names, detached mode, restart policies, and cleanup.
Mastering Docker Run: Essential Command Options Explained
docker run creates a new container from an image and starts it. The command looks simple at first, but the options decide how your container connects to the network, stores data, receives configuration, and behaves after a restart.
Use this guide when you know the image you want to run but need the right flags for a practical setup.
Basic Syntax
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
IMAGE is the image name, such as nginx or postgres:16. COMMAND and ARG... are optional and override or extend the image's default command.
For a quick foreground test:
docker run hello-world
For real services, you usually add options.
Run in the Background with -d
By default, Docker attaches your terminal to the container's output. Detached mode runs the container in the background:
docker run -d nginx
Docker prints the new container ID and returns your prompt. Check it with:
docker ps
Read logs from a detached container with:
docker logs <container_id_or_name>
Publish Ports with -p
Containers have their own network namespace. If a service listens inside the container, publish the port to reach it from your host:
docker run -d -p 8080:80 nginx
This maps host port 8080 to container port 80, so http://localhost:8080 reaches Nginx.
You can publish more than one port:
docker run -d -p 8080:80 -p 8443:443 nginx
To bind only to localhost on the host, include the host IP:
docker run -d -p 127.0.0.1:8080:80 nginx
That is useful for local tools you do not want exposed on every host interface.
Persist Data with Volumes
Container writable layers are not a good place for durable data. Use a bind mount when you want a specific host path mounted into the container:
docker run -d -p 8080:80 -v "$PWD/html:/usr/share/nginx/html:ro" nginx
This serves files from your local html directory. The :ro suffix makes the mount read-only inside the container.
Use a named volume when Docker should manage the storage location:
docker run -d --name postgres -v pgdata:/var/lib/postgresql/data postgres:16
If pgdata does not exist, Docker creates it. Inspect volumes with:
docker volume ls
For new work, Docker's --mount syntax is more verbose but clearer:
docker run -d --mount type=volume,src=pgdata,dst=/var/lib/postgresql/data postgres:16
Pass Configuration with -e and --env-file
Environment variables are a common way to configure containerized apps:
docker run -d -e APP_ENV=production my-custom-app:latest
Use -e more than once for multiple variables:
docker run -d -e DB_HOST=database.example.com -e DB_USER=app my-app:latest
For many variables, use an env file:
docker run -d --env-file ./app.env my-app:latest
Keep secrets out of committed .env files. Environment variables are easy to inspect from the host and from processes with enough access, so use your platform's secret manager for sensitive production values.
Name Containers with --name
Docker can generate a name, but a clear name makes later commands easier:
docker run -d --name web -p 8080:80 nginx
Then you can use:
docker logs web
docker stop web
docker exec -it web sh
Container names must be unique. If web already exists, remove or rename the old container before reusing the name.
Use Interactive Mode with -it
For shells and troubleshooting sessions, combine interactive mode and a pseudo-TTY:
docker run -it ubuntu bash
When you exit the shell, the container stops. Add --rm for throwaway sessions:
docker run --rm -it alpine sh
Choose a Restart Policy
Restart policies tell Docker what to do when a container exits:
docker run -d --name web --restart unless-stopped -p 8080:80 nginx
Common policies are:
no: do not restart automatically. This is the default.on-failure[:max-retries]: restart only after a non-zero exit code.always: restart whenever the container stops, including after Docker daemon restarts.unless-stopped: restart unless you explicitly stopped the container.
For long-running local services, unless-stopped is often a better fit than always because a manual stop remains respected.
Remove Throwaway Containers with --rm
Stopped containers remain on disk until you remove them. For one-off commands, --rm cleans up the container after it exits:
docker run --rm ubuntu echo "Hello from a temporary container"
Do not use --rm for containers whose stopped state you need to inspect later.
Practical Example
This command runs a web app with a stable name, a published port, a bind-mounted log directory, an environment variable, and a restart policy:
docker run -d \
--name my-app \
--restart on-failure \
-p 3000:80 \
-v "$PWD/logs:/app/logs" \
-e NODE_ENV=production \
my-node-app:1.0
After it starts, verify the container and check logs:
docker ps
docker logs my-app
Takeaway
Start with the smallest docker run command that works, then add options for the behavior you need: -d for background services, -p for access, -v or --mount for data, -e for configuration, --name for operations, --restart for resilience, and --rm for temporary runs.