Limits and Restarts

Resource Limits and Restart Policies in Compose

deploy.resources.limits once applied only to Swarm 514 ; Compose V2 514 applies cpus and memory to ordinary containers as the same cgroup settings as docker run --cpus --memory (Resource Limits). The daemon, not Compose, enforces the restart policy:

Restart policies
Policy Restarts after Stays stopped after
no (default) Never Any exit
on-failure[:N] A non-zero exit, at most N times Exit code 0
always Any exit; daemon start A manual stop, until the daemon restarts
unless-stopped Any exit; daemon start A manual stop, even across daemon restarts

Check the limits, then kill the API's process from the host as the out-of-memory killer would:

Limits in force, and a crash the daemon recovers fromShell
docker stats --no-stream --format '{{.Name}}  {{.MemUsage}}' $(docker compose $P ps -q)
sudo kill -9 "$(docker inspect -f '{{.State.Pid}}' l3-booknest-prod-api-1)"
sleep 3; docker inspect l3-booknest-prod-api-1 --format '{{.State.Status}} {{.RestartCount}}'
docker compose $P stop api >/dev/null 2>&1
docker inspect l3-booknest-prod-api-1 --format '{{.State.Status}} {{.RestartCount}}'
docker compose $P down -v >/dev/null 2>&1
git add compose.yaml compose.dev.yaml compose.prod.yaml db/index.js .gitignore
git commit -q -m "Add healthchecks, a test profile, watch rules and dev/prod Compose files"
git log --oneline -1
Output
l3-booknest-prod-api-1  19.65MiB / 256MiB
l3-booknest-prod-db-1  39.15MiB / 512MiB
running 1
exited 1
7f8f131 Add healthchecks, a test profile, watch rules and dev/prod Compose files

The daemon restarted the killed API at once; after stop it stayed down. A policy revives a crashed process but not a hung one, so pair it with a healthcheck, and watch RestartCount: a service that restarts every few minutes passes every single check.