What up -d recreates
Each time you run docker compose up -d, Compose compares every service with its existing container:
compose.yaml + images ──► desired state per service
│ compare with the existing container
┌───────────────────┼─────────────────────┐
unchanged changed missing
"Running" "Recreated" "Started"A service counts as changed when its resolved configuration changed (ports, environment, volumes…) or its image ID changed. Editing source code changes neither until the image is rebuilt.
Rebuild after a code change
docker compose up -d --build[+] Building 1.6s (10/10) FINISHED docker:default
=> CACHED [2/5] WORKDIR /app 0.0s
=> CACHED [3/5] COPY requirements.txt . 0.0s
=> CACHED [4/5] RUN pip install --no-cache-dir -r requirements.txt 0.0s
=> [5/5] COPY app.py . 0.1s
...
[+] Running 2/2
✔ Container signup-db-1 Healthy 0.0s
✔ Container signup-web-1 Recreated 10.2srequirements.txt did not change, so the pip install layer came from the cache. Only web got a new image, so only web was recreated. db kept running and kept its connections.
| Command | Effect |
|---|---|
docker compose build | rebuild every service with build:; containers unchanged |
docker compose build web | rebuild one service |
docker compose up -d --build | rebuild, then recreate whatever changed |
docker compose up -d --build web | rebuild and recreate web (and start its dependencies if needed) |
docker compose up -d --force-recreate | recreate every container even if unchanged |
The old image loses its tag and shows as <none> in docker images. docker image prune removes it.
Tear down
| Command | Containers | Networks | Named volumes | Images |
|---|---|---|---|---|
docker compose stop | stopped, kept | kept | kept | kept |
docker compose down | removed | removed | kept | kept |
docker compose down -v | removed | removed | removed | kept |
docker compose down --rmi local | removed | removed | kept | built images removed |
docker compose down[+] Running 3/3
✔ Container signup-web-1 Removed 10.2s
✔ Container signup-db-1 Removed 0.5s
✔ Network signup_default Removed 0.1sThe volume is not in the list. docker volume ls still shows signup_db-data, and the next up -d mounts it again with every row intact.
docker compose down -v[+] Running 4/4
✔ Container signup-web-1 Removed 10.2s
✔ Container signup-db-1 Removed 0.5s
✔ Volume signup_db-data Removed 0.0s
✔ Network signup_default Removed 0.1s