Run Containers in Detached Mode
Learn how to run Docker containers in detached mode, enabling background execution for long-running services. This lesson covers the `-d` flag, practical use cases, and how to manage containers without tying them to your terminal.
Focus: run containers in detached mode
You've started a container, watched its logs flood your terminal, and stopped it with a Ctrl+C. But what if you want to run a database, a web server, or a background worker — something that keeps running without locking your shell? That's the exact problem this lesson solves: how to run containers in detached mode so they hum along silently in the background while you reclaim your terminal.
The problem this lesson solves
Imagine you need to launch a PostgreSQL server for your local development environment. If you run docker run postgres, the container starts, but its logs scroll endlessly in your terminal. You can't run other commands in that window, and closing the terminal kills the container. This is attached mode — the default — and it's fine for quick tests but painful for long-running services.
The pain point: Attached mode ties your terminal session to the container's lifecycle. Detached mode frees you from that bondage.
By the end of this lesson, you'll be able to start any container in the background, check its status, stream logs when you need to, and stop it cleanly — all without leaving your command line.
Core concept / mental model
Think of a detached container as a silent worker. You give it a job, and it runs in the background, returning control to you immediately. The key ingredient is the -d (or --detach) flag passed to docker run.
- Attached (default): The container runs in the foreground. Your terminal is "attached" to its standard input, output, and error streams. When you close the terminal, the container receives a
SIGHUPand stops. - Detached: The container runs in the background. Your terminal is free. The container continues until it finishes its main process or you explicitly stop it.
Key definitions:
- docker run -d <image> — Start a container in detached mode.
- Container ID — a unique SHA-256 hash printed when a container starts (usually truncated to 12 characters in output).
- docker ps — Lists running containers (by default, only those in detached or attached-but-still-running state).
Mental model summarised:
-dis like running a program with&in Linux — but Docker manages the container's lifecycle independently of your shell.
How it works step by step
- Prepare your terminal. Open a normal shell (no Docker-in-Docker tricks needed).
- Run a container in detached mode. Use
docker run -d <image>. - Confirm it's running. Use
docker psto see the container's ID, image, status, and uptime. - Interact with it. Use
docker logs <container-id>to view stdout/stderr output without attaching. - Stop and clean up. Use
docker stop <container-id>(graceful shutdown) ordocker kill <container-id>(force stop).
The magic is that -d immediately returns you to your shell prompt after printing the container ID. Unlike attached mode, you never see the container's output unless you ask for it.
Hands-on walkthrough
Let's run a simple Nginx web server in detached mode and verify it works.
Step 1: Run a container in detached mode
docker run -d --name my-nginx -p 8080:80 nginx:alpine
Expected output:
Unable to find image 'nginx:alpine' locally
alpine: Pulling from library/nginx
...
Status: Downloaded newer image for nginx:alpine
4c6f8f6a7b3e12c6f8f6a7b3e12c6f8f6a7b3e12c6f8f6a7b3e12c6f8f6a7b3e1
Your container ID will differ — that's fine. The key is that you get back to your shell without Nginx logs flooding the screen.
Pro tip: Always use
--nameto give your container a human-friendly name. It makes later commands likedocker logs my-nginxeasier than remembering the ID.
Step 2: Verify the container is running
docker ps
Expected output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c6f8f6a7b3e nginx:alpine "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp my-nginx
You'll see the status is Up — the container is alive and serving.
Step 3: Check the logs without attaching
docker logs my-nginx
Expected output:
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
...
You see the startup logs. Now visit http://localhost:8080 in your browser — you should see the Nginx welcome page.
Step 4: Stop the container
docker stop my-nginx
Expected output:
my-nginx
Run docker ps again — the container will no longer be listed. Run docker ps -a to see it with status Exited (0).
Step 5: Attach to a detached container (advanced)
If you want to temporarily see the output of a running background container, use:
docker attach my-nginx
Warning:
docker attachwill attach your terminal's stdin/stdout to the running container. If you pressCtrl+C, it sends aSIGINTto the container's main process (which may kill it). To detach without stopping the container, use the detach sequenceCtrl+PthenCtrl+Q.
Compare options / when to choose what
| Mode | Use case | Pros | Cons |
|---|---|---|---|
Attached (docker run without -d) |
Quick tests, interactive processes like a shell (-it), debugging |
See logs immediately, easy to stop with Ctrl+C | Holds terminal, closes with terminal exit |
Detached (docker run -d) |
Long-running services (web servers, databases, background workers) | Terminal free, container survives terminal close, manageable with docker CLI |
Logs hidden by default, need explicit docker stop |
Detached + interactive (docker run -dit) |
Rare — not typical | Combines background with stdin open | Usually unnecessary; use attached or detached solely |
Key takeaway: Use detached mode for services that should run until you explicitly stop them. Use attached mode for tasks where you need the output in real time.
Troubleshooting & edge cases
Container exits immediately in detached mode
Some containers — like alpine with no command — exit as soon as they start because their main process finishes. To keep them running, provide a long-lived command:
docker run -d alpine sh -c "while true; do echo 'running'; sleep 5; done"
Detaching from an attached container
You pressed docker attach and now your terminal is stuck showing logs. To leave without stopping the container, press Ctrl+P then Ctrl+Q. This is the default escape sequence.
Cannot see logs of a detached container
docker logs my-nginx
If that returns nothing, the container may not be writing to stdout/stderr. Check its definition — some images log to files inside the container. You can exec into the container to inspect:
docker exec -it my-nginx cat /var/log/nginx/access.log
Mistaking -d for no logs at all
Detached mode doesn't discard logs — it just doesn't show them to you. You can always retrieve them with docker logs.
What you learned & what's next
You now know how to run containers in detached mode using the -d flag, check their status with docker ps, view logs with docker logs, and stop them gracefully with docker stop. You understand the mental model: detached for services, attached for tasks.
Key concepts mastered:
- The -d flag and its effect on container lifecycle
- Differentiating attached vs. detached modes
- Using docker logs to stream output from background containers
- Safely detaching from attached containers with Ctrl+P Ctrl+Q
What's next: Now that your containers can run silently in the background, the next lesson will teach you how to restart policies — making containers automatically restart when they crash or when your host reboots. You'll combine detached mode with --restart always for production-like setups.
Practice recap: Try running a Redis container in detached mode (
docker run -d --name my-redis -p 6379:6379 redis:alpine), verify it's running withdocker ps, then stop it. Experiment withdocker logsto see Redis startup commands.
Practice recap
Run docker run -d --name my-redis -p 6379:6379 redis:alpine. Verify it's up with docker ps. Check its logs with docker logs my-redis. Then stop it with docker stop my-redis and confirm it's stopped with docker ps -a. Next, try starting a container with -d and immediately inspecting its processes inside: docker exec -it my-nginx ps aux.
Common mistakes
- Running
docker run -don a container whose main process finishes immediately (likealpinewithout a command) — it exits instantly. Always ensure the image is designed to stay alive. - Forgetting to use
--name— then you must refer to the container by its long ID in all subsequent commands, which is error-prone. - Using
docker attachand then pressingCtrl+Cthinking it only detaches — it actually sends a signal that may stop the container. UseCtrl+P Ctrl+Qto detach safely. - Assuming
docker logsshows zero output in detached mode — it does show all stdout/stderr since the container started, which can be verbose for production images. - Running
docker run -ditby habit — it keeps stdin open unnecessarily. Only use-ditif you truly need an interactive shell while detached, which is rare.
Variations
- Use
docker run --detach(long form) instead of-din scripts for better readability. - Combine
-dwith--restart alwaysto make a service container restart automatically even after crashes or host reboots (next lesson's topic). - Use
docker compose up -dfor multi-container projects — detaches all services defined in acompose.yamlfile at once.
Real-world use cases
- Running a PostgreSQL database container in the background with
docker run -d --name pg -e POSTGRES_PASSWORD=secret postgres:16while you develop your application. - Deploying a Node.js API behind Nginx as two separate detached containers, then connecting them via a Docker network for production-like local testing.
- Launching a batch processing worker (e.g., for image resizing) in detached mode as a service that continuously picks up jobs from a Redis queue.
Key takeaways
- Use
docker run -dto start a container in the background — your terminal is freed immediately. - Check running containers with
docker ps; include-ato see all containers including stopped ones. - View logs of a detached container with
docker logs <container>without attaching to its terminal. - Detach safely from an attached session using
Ctrl+PthenCtrl+Q, notCtrl+C. - Stop a detached container with
docker stop— it sends a gracefulSIGTERMbeforeSIGKILLafter a timeout.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.