docker stop, start, restart
docker stop, docker start, and docker restart control the lifecycle of containers that already exist. They matter because a container is not just an image: it has a name, configuration, writable layer, mounts, networking setup, logs, and a main process that can be stopped and started again.
These commands are the daily tools for pausing a service, bringing back a stopped container, and applying a simple restart without recreating the container. Used well, they help you avoid accidental data loss and make debugging much clearer.
Overview: How Container Lifecycle Control Works
A Docker image is a read-only template made of layered filesystem content and image metadata. A container is an instance of that image with Docker-managed runtime configuration and a thin writable layer on top. When a container is running, Docker also tracks its main process, network attachments, port publications, mounts, logs, and exit status. When it is stopped, the process is gone, but the container object and its writable layer still exist.
docker stop asks Docker to stop a running container gracefully. By default Docker sends the container’s main process a termination signal, normally SIGTERM, and waits for a grace period. If the process does not exit in time, Docker sends SIGKILL. This two-stage behavior matters for databases, web servers, queues, and anything that needs time to flush data, finish requests, or close files cleanly.
docker start starts an existing stopped container. It does not create a new container, pull a newer image, reread a changed docker run command, or change port mappings. Docker reuses the container’s stored configuration: image reference, command, environment variables, mounts, name, and published ports. Any files left in the container’s writable layer are still there unless the container was removed.
docker restart combines the same idea: stop the container, then start it again. It is useful when a process needs a clean boot, but it is not the same as rebuilding an image or recreating a container from changed options. If you need a new image version, different environment variables, different ports, or different mounts, you usually remove and recreate the container, or let docker compose up -d reconcile the service from a Compose file.
The Docker CLI sends these lifecycle requests to the Docker daemon. On Linux, the daemon controls container processes through the runtime using Linux namespaces and cgroups. On Docker Desktop for macOS and Windows, Linux containers run inside a managed Linux VM, but the CLI behavior is essentially the same: the client requests a lifecycle operation and the daemon performs it.
Syntax
docker stop [OPTIONS] CONTAINER [CONTAINER...]
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker restart [OPTIONS] CONTAINER [CONTAINER...]
| Command or option | Meaning |
|---|---|
CONTAINER |
A container name or ID, such as web-demo. You can pass more than one container. |
docker stop |
Gracefully stops a running container by sending a stop signal, waiting, then killing if needed. |
docker start |
Starts one or more stopped containers using their existing stored configuration. |
docker restart |
Stops and then starts one or more containers. |
-t or --time |
Sets the number of seconds Docker waits before forcing a stop. This is accepted by docker stop and docker restart. |
-a or --attach |
For docker start, attach STDOUT and STDERR from the container after starting it. |
-i or --interactive |
For docker start, attach STDIN as well. This is mostly useful for interactive containers originally created with an open input stream. |
Use names for containers you plan to manage repeatedly. A command such as docker stop web-demo is easier and safer than copying a long generated container ID from docker ps.
Examples
Example 1: Stop a Running Web Container
docker run -d --name web-lifecycle -p 8080:80 nginx:1.27-alpine
docker stop web-lifecycle
Output:
4f8b2c1d9a0e5c7b6d3a2f1e0b9c8d7a6f5e4d3c2b1a09876543210fedcba987
web-lifecycle
The first command creates and starts a container from nginx:1.27-alpine. The second command asks Nginx to stop gracefully. Docker prints the container name when the stop completes. The image remains available, and the stopped container still exists until you remove it with docker rm.
Example 2: Start the Same Container Again
docker start web-lifecycle
docker ps --filter name=web-lifecycle --format "{{.Names}} {{.Status}} {{.Ports}}"
Output:
web-lifecycle
web-lifecycle Up 3 seconds 0.0.0.0:8080->80/tcp
docker start reuses the existing container. It does not create a second container and it does not change the published port from 8080 to something else. If you visit host port 8080 after starting it, the same Nginx container is serving again.
Example 3: Restart with a Longer Grace Period
docker restart --time 20 web-lifecycle
Output:
web-lifecycle
This tells Docker to allow up to 20 seconds for the container process to shut down before forcing it. That extra time can matter for applications that handle in-flight requests or write state on shutdown. If the process exits quickly, Docker starts the container again immediately after the stop completes.
Example 4: Check State Before and After
docker ps -a --filter name=web-lifecycle --format "{{.Names}} {{.Status}}"
docker stop web-lifecycle
docker ps -a --filter name=web-lifecycle --format "{{.Names}} {{.Status}}"
Output:
web-lifecycle Up 2 minutes
web-lifecycle
web-lifecycle Exited (0) 4 seconds ago
docker ps shows only running containers by default. docker ps -a includes stopped containers too, which is why it is the right command when something appears to have disappeared. The exit code 0 means the process stopped successfully.
How It Works Step by Step
- You run
docker stop web-lifecycle. The CLI sends a request to the Docker daemon naming the existing container. - The daemon looks up the running container and identifies its main process. Docker containers are built around one primary process; when that process exits, the container is stopped.
- Docker sends the configured stop signal to that process. For most images this is
SIGTERM, though images can declare a different stop signal with Dockerfile metadata. - Docker waits for the configured timeout. During this time the application can flush buffers, close sockets, finish cleanup, and exit normally.
- If the process is still alive after the timeout, Docker sends a forceful kill signal. This protects the host from containers that ignore shutdown forever.
- The container state changes to exited. Its writable layer, logs, name, mounts, and stored configuration remain.
- When you run
docker start, Docker prepares the same mounts, reconnects networking, reapplies stored configuration, and starts the same configured command again. - When you run
docker restart, Docker performs the stop sequence and then the start sequence as one operation.
This is why stop and start are lifecycle operations, not deployment operations. They do not update image layers. If the tag nginx:1.27-alpine changes in a registry, an existing container does not magically change. You must pull or build the new image and create a new container from it.
Common Mistakes
Expecting docker start to Apply New Options
docker start -p 9090:80 web-lifecycle
This is wrong because docker start does not accept new port mappings. Ports are part of the container’s creation configuration. The fix is to remove and recreate the container with the desired mapping:
docker stop web-lifecycle
docker rm web-lifecycle
docker run -d --name web-lifecycle -p 9090:80 nginx:1.27-alpine
Forgetting Stopped Containers Still Exist
docker stop web-lifecycle
docker ps
docker ps can make the container look gone because it only lists running containers. Use docker ps -a to see stopped containers:
docker ps -a --filter name=web-lifecycle
Using restart When You Really Need a New Image
docker pull nginx:1.27-alpine
docker restart web-lifecycle
Pulling an image and restarting an existing container does not replace that container’s filesystem with the newly pulled image content. If you need the new image, recreate the container after pulling:
docker pull nginx:1.27-alpine
docker stop web-lifecycle
docker rm web-lifecycle
docker run -d --name web-lifecycle -p 8080:80 nginx:1.27-alpine
Killing Too Quickly for Stateful Services
docker stop --time 1 database-demo
A one-second timeout may be too short for a database or queue to shut down cleanly. Use a realistic grace period, and store data in a named volume so it is not trapped in a removable container layer:
docker stop --time 30 database-demo
Best Practices
- Name containers that you will start, stop, or restart by hand.
- Use
docker ps -awhen investigating lifecycle state; stopped containers are hidden from plaindocker ps. - Give stateful services enough stop time with
--time. A clean shutdown is better than a forced kill. - Remember that
docker startreuses existing configuration. Recreate a container to change ports, mounts, environment variables, or the image version. - Use named volumes for persistent data. Stopping a container preserves its writable layer, but removing the container deletes that layer.
- Use explicit image tags such as
nginx:1.27-alpineinstead of relying onlatest, which can move over time. - Inspect logs with
docker logs CONTAINERbefore removing a failed container. - For multi-container projects, prefer
docker compose stop,docker compose start, anddocker compose restartso related services are managed together from the Compose file.
Practice Exercises
- Start an
nginx:1.27-alpinecontainer namedpractice-lifecycleon host port8090, stop it, and confirm it appears indocker ps -a. - Start
practice-lifecycleagain and verify that the original port mapping is still present. Hint: usedocker ps --filter name=practice-lifecycle --format. - Restart the same container with a 15-second timeout. Expected end state: Docker prints the container name and the container is running again.
Summary
docker stopgracefully stops a running container, then forces it only if the timeout expires.docker startstarts an existing stopped container with the same stored configuration.docker restartperforms a stop followed by a start.- Stopped containers still exist; use
docker ps -ato find them. - Restarting does not pull a new image into an existing container or apply new port and mount options.
- Stopping preserves the container object, but removing the container deletes its writable layer.
- Use named volumes and reasonable shutdown timeouts for services that keep important data.
