docker compose restart is not a deploy command.
That sentence would have saved me an annoying debugging session.
Docker Compose is declarative on paper. The running container is an object created from an earlier configuration, and restart does not rebuild that object.
So when you edit docker-compose.yml, run docker compose restart, and nothing changes, Docker is obeying a lifecycle boundary you forgot existed.
The Volume Mount That Would Not Move
Start with a boring service:
version: '3.8'
services:
webapp:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./initial-content:/usr/share/nginx/html
Now change the source directory for the NGINX content:
version: '3.8'
services:
webapp:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./new-content:/usr/share/nginx/html # The change is here
The natural command is the wrong command:
docker compose restart
The service restarts. The old files are still served from ./initial-content.
So you try the longer version of the same mistake:
docker compose stop
docker compose start
Same result. The container stops. The container starts. The mount does not change.
docker inspect Tells the Truth
The file says one thing. The container says another. Ask the container:
"Mounts": [
{
"Type": "bind",
"Source": "/path/to/project/initial-content",
"Destination": "/usr/share/nginx/html",
...
}
]
There it is. The container is still bound to ./initial-content.
restart and stop/start never applied the updated configuration because they were never supposed to.
Restart Manages Containers. Up Reconciles Configuration.
The official Docker Compose documentation
makes the split clear. restart, stop, and start manage existing containers. They do not recreate them from docker-compose.yml. They bring back the same container with the same old mount.
docker compose up
is the command that reconciles configuration. It compares docker-compose.yml with the running services. If the configuration changed, it recreates the affected container.
The correct command was:
docker compose up -d
The -d flag runs the containers in detached mode. After that, docker inspect shows the updated mount point, and NGINX serves ./new-content.
If you want to force the issue, use the --force-recreate flag
.
When You Want a Clean Slate
Sometimes you do not want reconciliation. You want certainty.
Use the two-step reset:
docker compose down: This removes the containers and the networks created byup. It does not remove named volumes by default, which is the right default because accidental data loss is not a feature.
docker compose down
docker compose up: With the old containers gone,upcreates the environment from the currentdocker-compose.yml.
docker compose up -d
This is the blunt, reliable workflow when you cannot afford stale configuration.
The rule is simple:
Use restart when the container definition is unchanged.
Use up -d when docker-compose.yml changed.
Use down && up -d when you want a clean environment and you know what state you are removing.


