Beginner · Docker · topic 17 of 53 · 35 min
Running containers: ports, volumes, networks and limits
Explanation
The everyday commands
docker run -d --name shop-api -p 8080:3000 -e NODE_ENV=production shop-api:2.1.0
docker ps # running containers (add -a to include stopped ones)
docker logs -f shop-api # follow the logs
docker exec -it shop-api sh # open a shell inside the running container
docker stop shop-api # graceful stop: SIGTERM, then SIGKILL after a timeout
docker start shop-api # start it again (same container, same writable layer)
docker rm shop-api # delete the stopped container
docker run --rm -it python:3.12-slim python # throwaway container, removed on exitdocker images # local images
docker build -t shop-api:2.1.0 . # build from the Dockerfile in this folder
docker pull postgres:17 # download
docker tag shop-api:2.1.0 ghcr.io/acme/shop-api:2.1.0
docker push ghcr.io/acme/shop-api:2.1.0 # upload (after docker login ghcr.io)
docker inspect shop-api # full JSON details: IP, mounts, env, restart policyPublishing ports
A container has its own network namespace, so an app listening on port 3000 inside it is not reachable from outside until you publish the port. -p 8080:3000 means "send traffic arriving on host port 8080 to container port 3000". The host part comes first.
| Option | Meaning |
|---|---|
| -p 8080:80 | Host port 8080 on all interfaces → container port 80 (TCP) |
| -p 127.0.0.1:5432:5432 | Only reachable from the host itself, not from the network |
| -p 53:53/udp | UDP instead of the default TCP |
| -p 3000 | Container port 3000 → a random free host port (see docker port) |
Storage: volumes, bind mounts and tmpfs
Anything a container writes into its writable layer disappears when the container is removed, for example when you upgrade to a new image. Data that must survive goes outside the container.
| Type | What it is | Use it for |
|---|---|---|
| Volume | Storage managed by Docker (under /var/lib/docker/volumes on Linux) | Databases and any data that must persist; easiest to back up and move |
| Bind mount | A folder or file from the host mapped into the container | Development (live code reload), or giving a container one config file |
| tmpfs | Memory-only storage, gone when the container stops | Temporary files and sensitive scratch data (Linux hosts) |
docker volume create pgdata
docker run -d --name db -e POSTGRES_PASSWORD=devonly \
-v pgdata:/var/lib/postgresql/data postgres:17 # named volume
docker run --rm -v "$(pwd)":/app -w /app node:24-slim npm test # bind mount the current folder
docker run -d --tmpfs /tmp --read-only shop-api:2.1.0 # read-only root, writable /tmp in memoryNetworks
Docker creates a default bridge network, a private network inside the host. Containers on it can reach the internet, but they cannot find each other by name. Create your own (user-defined) bridge network instead: Docker then runs a small DNS server, so a container called db is reachable at the host name db.
docker network create shopnet
docker run -d --name db --network shopnet -e POSTGRES_PASSWORD=devonly postgres:17
docker run -d --name api --network shopnet -p 8080:3000 \
-e DATABASE_URL=postgres://postgres:devonly@db:5432/postgres shop-api:2.1.0With --network host, the container uses the host's network directly with no isolation and no port mapping. It is occasionally useful for network tools and works fully on Linux hosts; avoid it for normal apps.
Restart policies and resource limits
| --restart | Behaviour |
|---|---|
| no (default) | Never restart automatically |
| on-failure[:N] | Restart only if the process exits with a non-zero code, optionally at most N times |
| always | Always restart; also starts again when the Docker daemon starts, even if you had stopped it by hand |
| unless-stopped | Like always, but stays stopped after the daemon restarts if you stopped it yourself |
docker run -d --name worker --restart unless-stopped \
--memory 512m --cpus 1.5 shop-worker:2.1.0
docker stats # live CPU and memory use per containerCleaning up
docker ps -a # find old stopped containers
docker image prune # remove dangling images (untagged leftovers)
docker system prune # remove stopped containers, unused networks, dangling images and build cacheCommon mistakes
- docker system prune -a --volumes on a server "to free space" can delete the volume holding your database if its container is stopped at that moment. Read the warning, and back up volumes first.
- Getting the -p order wrong: it is host:container. -p 3000:8080 sends host port 3000 to container port 8080.
- The app inside listens on 127.0.0.1 only, so -p seems not to work. Inside a container, the app must listen on 0.0.0.0.
- Using container IP addresses in config. They change on restart; use names on a user-defined network.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Running containers: ports, volumes, networks and limits · 1/8
docker run -d --name shop-api -p 8080:3000 shop-api:2.1.0docker run starts a container. Dash d runs it in the background, name gives it a name, and rm deletes it when it exits.
Prefer a video by a teacher? Find free videos on “docker run volumes bind mounts networks tutorial” on YouTube ↗
In real life: A hospital lab report service in Kochi
A hospital IT team runs a small lab-report service on one Linux server. The report database runs in a container with a named volume, so upgrading Postgres images never touches the data, and it is not published to the network at all. The web app joins the same user-defined network, reaches the database as db, and is published on port 8080 behind the hospital's reverse proxy. Both containers use --restart unless-stopped, so after a power cut and reboot they come back on their own, and a memory limit stops the PDF generator from starving the database.
docker network create labnet
docker run -d --name db --network labnet --restart unless-stopped \
-v labdata:/var/lib/postgresql/data -e POSTGRES_PASSWORD_FILE=/run/secrets/pg postgres:17
docker run -d --name web --network labnet --restart unless-stopped \
--memory 1g -p 8080:8000 lab-reports:1.8.2Practice (0/3 done)
Your app listens on port 5000 inside the container. Which option makes it reachable at http://localhost:8000 on your laptop?
Write parse_port(spec) for docker run -p values. Return a dict with "host_ip" (None means all interfaces), "host_port" (None means Docker picks a random one), "container_port" (an int) and "protocol" ("tcp" by default). Formats: "3000", "8080:80", "127.0.0.1:5432:5432", "127.0.0.1::80" (empty host port) and any of these followed by "/udp", "/tcp" or "/sctp". Raise ValueError for another protocol, a port that is not a number, or a port outside 1 to 65535. IPv6 addresses are not tested.
On your own machine, run Postgres with a named volume, create a table and a row, then delete the container and start a NEW container with the same volume. Prove the row is still there. Then run a second container on a user-defined network that connects to the database by name.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Docker Compose: multi-container appsDocker · same module
- Containers with Podman: images, run, ports and logsLinux and Red Hat (RHCSA to RHCE) · Boot, recovery and containers
- Docker: packaging your appBackend Development · Deployment and scaling
- Persistent storage and containers as systemd servicesLinux and Red Hat (RHCSA to RHCE) · Boot, recovery and containers
- Namespaces, ConfigMaps, Secrets, resources and probesKubernetes fundamentals
- LVM: physical volumes, volume groups and logical volumesLinux and Red Hat (RHCSA to RHCE) · Storage: partitions, file systems and LVM
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What happens to files a container wrote into its own file system when you run docker rm on it?
Answer: They are deleted with the container
The writable layer belongs to the container. Use a volume for data that must survive.
Two containers are on the default bridge network. Why can the api container not reach the database at the host name db?
Answer: The default bridge network has no DNS by container name; use a user-defined network
User-defined bridge networks provide name resolution; the default bridge does not.
Which restart policy restarts a container only when its process exits with an error code?
Answer: on-failure
on-failure restarts on a non-zero exit code, optionally up to a maximum number of times.
Which is the best way to share your source folder with a container for live reloading during development?
Answer: A bind mount of the project folder
A bind mount maps a host folder into the container, so edits appear inside at once.
What does --memory 512m do?
Answer: Sets a hard memory limit; going over it gets the container's process killed
Memory limits are enforced with cgroups; the kernel kills the process when the limit is exceeded.
Which command removes the containers AND deletes the project's named volumes?Related
Answer: docker compose down -v
The -v flag removes named volumes declared in the file and anonymous volumes. Plain down keeps them.
Why can't a rootless container publish host port 80 by default?Related
Answer: Ports below 1024 need root privileges
Unprivileged users cannot bind low ports by default.
What is the difference between an image and a container?Related
Answer: An image is the package (recipe); a container is a running copy of it
You build an image once and start one or many containers from it.
What happens to files written inside a container (not in a volume) after podman rm?Related
Answer: They are deleted with the container
The container layer is removed.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- 2 more topics in “Docker” before its exam: Docker Compose: multi-container apps, Image and container security.
- Module 4 exam: Docker · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Kubernetes fundamentals. 53 topics left in the course before the final exam.
← Previous: Writing Dockerfiles: caching, multi-stage builds and small images