Maintenance

Site is under maintenance — quizzes are still available.

Go to quizzes

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

Sponsored

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 SIGHUP and 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: -d is like running a program with & in Linux — but Docker manages the container's lifecycle independently of your shell.

How it works step by step

  1. Prepare your terminal. Open a normal shell (no Docker-in-Docker tricks needed).
  2. Run a container in detached mode. Use docker run -d <image>.
  3. Confirm it's running. Use docker ps to see the container's ID, image, status, and uptime.
  4. Interact with it. Use docker logs <container-id> to view stdout/stderr output without attaching.
  5. Stop and clean up. Use docker stop <container-id> (graceful shutdown) or docker 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 --name to give your container a human-friendly name. It makes later commands like docker logs my-nginx easier 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 attach will attach your terminal's stdin/stdout to the running container. If you press Ctrl+C, it sends a SIGINT to the container's main process (which may kill it). To detach without stopping the container, use the detach sequence Ctrl+P then Ctrl+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 with docker ps, then stop it. Experiment with docker logs to 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 -d on a container whose main process finishes immediately (like alpine without 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 attach and then pressing Ctrl+C thinking it only detaches — it actually sends a signal that may stop the container. Use Ctrl+P Ctrl+Q to detach safely.
  • Assuming docker logs shows 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 -dit by habit — it keeps stdin open unnecessarily. Only use -dit if you truly need an interactive shell while detached, which is rare.

Variations

  1. Use docker run --detach (long form) instead of -d in scripts for better readability.
  2. Combine -d with --restart always to make a service container restart automatically even after crashes or host reboots (next lesson's topic).
  3. Use docker compose up -d for multi-container projects — detaches all services defined in a compose.yaml file 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:16 while 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 -d to start a container in the background — your terminal is freed immediately.
  • Check running containers with docker ps; include -a to 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+P then Ctrl+Q, not Ctrl+C.
  • Stop a detached container with docker stop — it sends a graceful SIGTERM before SIGKILL after a timeout.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.