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.