What does docker compose up -d actually do?
It builds, creates, and starts everything your compose.yaml describes, detached into the background. What -d changes, stop vs down, and who restarts the container when it dies.
docker compose up reads the compose.yaml in your project and, per the official reference, “builds, (re)creates, starts, and attaches to containers for a service”: everything the file describes, brought to life in one command. The -d flag is detached mode: “run containers in the background,” giving you your terminal back instead of streaming logs into it. Together they’re the standard way to start a service and leave it running, which is why nearly every self-hosting guide ends with this exact command.
Each word, unpacked
docker compose is Docker’s tool for “defining and running multi-container applications” from one YAML file: services, networks, volumes, all declared rather than typed out as a chain of docker run flags. (Note the space: docker-compose with a hyphen is the legacy v1 tool from the Python era; everything current is the docker compose plugin.) up makes reality match the file: creating networks and volumes, then creating and starting containers, recreating any whose config changed. Without -d it stays attached, aggregating every container’s output in your terminal, and Ctrl-C stops the containers: fine for watching a first boot, wrong for anything meant to outlive your session.
Living with a detached service
docker compose ps # what's running, and its ports
docker compose logs -f # follow the logs you gave up
docker compose stop # stop containers, keep them
docker compose down # stop AND remove containersThe pair to understand is stop vs down. stop halts containers “without removing them”; down removes containers and networks entirely. The reassuring part: named volumes (where well-behaved setups keep their data) survive down unless you explicitly pass -v. So down followed by up -d is the ordinary, safe way to recreate a service from scratch; down -v is the one that erases data, and deserves a pause before Enter.
Who restarts it when it dies?
Detached doesn’t mean supervised. Whether a crashed or rebooted container comes back is set by the service’s restart policy in the compose file. The default is no: nothing restarts. Long-running services almost always want unless-stopped: restart on crashes and on daemon/machine restarts, except when you deliberately stopped the container. Your stop is respected until you start it again. (always differs in exactly one way: a manually-stopped container returns anyway when the Docker daemon restarts.) And if a service crashes the moment it starts, restart policies dutifully produce a crash loop: the logs, not the policy, are where the answer lives.
The worked example
OpenClaw’s Docker setup is this whole page in one file: the Gateway as a service built from a pinned image, state directories mounted so the disposable container never holds the agent’s life, restart: unless-stopped so the agent returns after a crash or server reboot without also overriding your deliberate stops, and docker compose up -d as the single command that brings the whole thing to life in the background. Run it once and the service is on its own; from then on your relationship with it is ps, logs -f, and the occasional deliberate down.