Docker Compose Restart Does Not Apply Your New Config

Docker Compose Restart Does Not Apply Your New Config

If you changed docker-compose.yml and only restarted the container, Docker did exactly what you asked: it restarted the old container definition.

Mike Chumba Mike Chumba
3 min read
448 words

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:

  1. docker compose down: This removes the containers and the networks created by up. It does not remove named volumes by default, which is the right default because accidental data loss is not a feature.
    docker compose down
  1. docker compose up: With the old containers gone, up creates the environment from the current docker-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.