docker run is the command you type most. Its flag list is long, but the working set is small. This page is that working set, grouped by what each flag actually does, with the patterns I reach for daily: detached services, interactive shells, port and volume mappings, environment variables, networks, restart policies, resource limits, and the one-shot --rm pattern for quick experiments.
Use the inputs above to swap the placeholders (IMAGE, CONTAINER, HOST_PORT, CONTAINER_PORT, VOLUME) into the commands below.
Set your image, container name, ports, and a volume name. Every example below updates as you type.
Jump to:
- The 30-second shape of
docker run - Detached vs interactive
- Naming and auto-cleanup
- Publishing ports
- Volumes and bind mounts
- Environment variables
- Networking
- Restart policies
- Resource limits (memory, CPU, PID)
- Platform, user, working directory
- Overriding ENTRYPOINT and CMD
- Common one-liners
- FAQ
The 30-second shape of docker run
docker run [FLAGS] :image [COMMAND] [ARGS...]Everything before the image is a flag for docker run. Everything after the image is a command to run inside the container, overriding the image's CMD (and sometimes ENTRYPOINT). When in doubt about where the image goes:
docker run -d --name :container -p :host_port::container_port :imageImage is always in the middle. Flags before, command after.
Detached vs interactive
Detached: container runs in the background, prints the container ID, returns the shelldocker run -d --name :container :imageInteractive shell: attach a TTY and stdin, give me a shelldocker run -it --name :container :image bashUse sh when the image does not ship bash (alpine, distroless, scratch)docker run -it --name :container :image sh-d is for services (databases, web servers). -it is for sessions where you are typing into the container. -i keeps stdin open, -t allocates a pseudo-TTY; the two are almost always used together when you want a shell.
If you start a service with -d and want a shell inside it later, do not re-run; use docker exec -it :container bash to attach. See docker exec.
Naming and auto-cleanup
Name your container so you can find it againdocker run -d --name :container :imageRemove the container automatically when it exits (great for one-shots)docker run --rm -it :image command--rm + -it for a throwaway interactive shelldocker run --rm -it :image bashWithout --name, Docker invents a name like gracious_lalande. Fine for quick tests, miserable when you want to docker logs db after you've forgotten what it picked. With --rm, the container disappears the instant its main process exits — perfect for docker run --rm -it python:3.12 python style scratchpads.
Names must be unique. If you try to reuse one while the old container still exists (even stopped), the run fails. Either docker rm OLD_NAME first or pick a different name.
Publishing ports
Publish container port 80 on host port 8080docker run -d --name :container -p :host_port::container_port :imagePublish on all interfaces (default) — accessible from anywhere on the networkdocker run -d -p :host_port::container_port :imagePublish only on localhost — not exposed to your LANdocker run -d -p 127.0.0.1::host_port::container_port :imageRandom host port (read the assignment with docker port :container)docker run -d -p :container_port :imageUDP port (default is TCP)docker run -d -p :host_port::container_port/udp :imageMultiple portsdocker run -d -p 80:80 -p 443:443 :imageOrder matters: HOST:CONTAINER. The container always listens on its own port; the host side is what your browser / app on the host connects to. Containers on the same Docker network do not need published ports to reach each other — service-name DNS handles that. Publishing is only for traffic from the host or the outside world.
Volumes and bind mounts
Named volume — Docker manages the underlying storagedocker run -d --name :container -v :volume:/path/in/container :imageBind mount — map a host directory into the containerdocker run -d --name :container -v /host/path:/path/in/container :imageRead-only bind mountdocker run -d -v /host/path:/path/in/container:ro :imageAnonymous volume — no name, persists in /var/lib/docker/volumes, hard to clean updocker run -d -v /path/in/container :imagetmpfs — in-memory only, gone when the container stopsdocker run -d --tmpfs /tmp :imageThe rule of thumb: named volumes for data you care about (databases, uploads, generated files); bind mounts for code you are editing on the host (development); tmpfs for caches and scratch space.
The full breakdown of when to use each is in Docker Volumes vs Bind Mounts.
Environment variables
Single env vardocker run -e KEY=VALUE :imagePass an existing host env var through (no = sign)docker run -e DATABASE_URL :imageMultipledocker run -e KEY1=VALUE1 -e KEY2=VALUE2 :imageLoad from a filedocker run --env-file .env :image--env-file reads a file of KEY=VALUE lines (one per line; # for comments). It is the cleanest way to keep secrets out of shell history. The trade-off is that everything in that file becomes an environment variable inside the container — there is no scoping.
ARG (build-time) and ENV (runtime) are different things. Full breakdown in Docker Environment Variables.
Networking
Default bridge — works, but container-to-container by name does NOT resolve heredocker run -d --name :container :imageCreate and use a user-defined bridge — service-name DNS worksdocker network create app-net
docker run -d --name :container --network app-net :imageHost network (Linux only — on Mac and Windows this is more limited)docker run -d --network host :imageNo network at alldocker run -d --network none :imageAdd an /etc/hosts entrydocker run --add-host db:192.168.1.10 :imageThe most useful network is a user-defined bridge (docker network create). On that network, containers can find each other by name: ping db from one container resolves to the container named db on the same network. The default bridge does not give you that.
--network host puts the container on the host's network stack — same IPs and ports. On Linux this is convenient and fast. On macOS and Windows it is more limited because Docker is running in a VM and "host" means the VM, not your Mac/PC. Full picture in Docker Networking Basics.
Restart policies
Never restart (default)docker run -d --restart no :imageRestart if the process exits with a non-zero code, up to N timesdocker run -d --restart on-failure:5 :imageRestart always, even if you manually stopped itdocker run -d --restart always :imageRestart unless you explicitly stopped it (best default for services)docker run -d --restart unless-stopped :imageunless-stopped is what I use for almost every long-running service: it survives container crashes and host reboots, but it does not fight you when you actually meant to stop it. Compose uses the same values via restart: in docker-compose.yml. See Docker Restart Policies and Health Checks.
Resource limits (memory, CPU, PID)
Cap memory at 512 MB (container OOM-kills past this)docker run -d --memory 512m :imageMemory + swap (the total)docker run -d --memory 512m --memory-swap 1g :imageCap CPU at 0.5 cores (50% of one core)docker run -d --cpus 0.5 :imagePin to specific CPUs (cores 0 and 2)docker run -d --cpuset-cpus 0,2 :imageCap process countdocker run -d --pids-limit 200 :imageMemory caps are the most useful — without them, a single container can OOM the whole host. On a multi-container host, set them. --cpus is fractional and easier to reason about than the older --cpu-quota / --cpu-period pair. Exit code 137 in docker logs (or docker inspect) is the OOM kill signature.
Platform, user, working directory
Force the image platform (Apple Silicon running x86 images)docker run --platform linux/amd64 :imageRun as a specific UID:GIDdocker run --user 1000:1000 :imageRun as a named user inside the image (must exist in /etc/passwd)docker run --user node :imageOverride the working directorydocker run --workdir /app :imageSet the container hostnamedocker run --hostname app-1 :image--user is the cheapest way to avoid leaving root-owned files behind on bind mounts. --platform linux/amd64 is the workaround when an image lacks an arm64 manifest and you are on Apple Silicon — slower (emulation) but unblocks you. See exec format error — Apple Silicon and Multi-Arch Docker Images.
Overriding ENTRYPOINT and CMD
Override CMD (the default) by passing a new command after the imagedocker run :image echo helloOverride ENTRYPOINTdocker run --entrypoint sh :imageBoth — explicit entrypoint with argumentsdocker run --entrypoint /bin/sh :image -c "echo hello && sleep 1"Inside a Dockerfile, ENTRYPOINT is the executable and CMD is the default arguments. At docker run time, anything after the image overrides CMD. To override ENTRYPOINT, you need the --entrypoint flag explicitly. This is the unlock for getting into images that ship with a stubborn ENTRYPOINT and refuse a shell otherwise:
docker run --rm -it --entrypoint sh :imageCommon one-liners
# Throwaway interactive shell — gone when you exit
docker run --rm -it :image bash
# Throwaway shell in alpine (no bash)
docker run --rm -it :image sh
# Run a one-shot command with the working directory bind-mounted
docker run --rm -v $(pwd):/work -w /work :image command
# Run a one-shot command as the current user (no root-owned files)
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/work -w /work :image command
# Try a CLI tool without installing it (e.g. jq, yq, ffmpeg)
docker run --rm -i ghcr.io/jqlang/jq <<< '{"a":1}'
# Run a service with the common production-ish defaults
docker run -d --name :container -p :host_port::container_port \
-v :volume:/data --restart unless-stopped :image
# Run with a healthcheck attached
docker run -d --name :container \
--health-cmd 'curl -f http://localhost/healthz || exit 1' \
--health-interval 30s --health-retries 3 :imageFor the full "run X without installing X" pattern across databases, web servers, language runtimes, and dev tools, see How to Run Anything on Your Computer Without Installing It.
FAQ
Sources
Authoritative references this article was fact-checked against.
- docker run — official CLI referencedocs.docker.com
- Networking in Dockerdocs.docker.com
- Volumes — Docker docsdocs.docker.com




![Bash While Loops: Syntax, read-line, Retry Patterns (2026) Bash while loop reference: read files with while IFS= read -r, retry-with-backoff, wait-for-service polling, the subshell-scoping bug fix, the until and select siblings, plus [[ ]] vs [ ] vs (( )) test contexts.](https://images.techearl.com/bash-while-loop/bash-while-loop-1536.webp?v=2026-06-01T12%3A00%3A00Z)
