Docker Compose Rebuild: Force a Clean Build and Recreate
Updated July 27, 2026
docker compose up -d --build: it rebuilds images and recreates only the containers whose image or configuration changed. Reach for docker compose build --no-cache when the layer cache itself is stale (old apt packages, cached downloads), and --force-recreate when containers must be replaced even though nothing changed. If your code changes are not showing up, the cause is usually not the build at all. It is a volume shadowing the image content.docker compose up -d --buildStep 1: the everyday rebuild
up --build is build plus up in one step: images are rebuilt (using the layer cache, so unchanged layers are instant), and Compose recreates exactly the services whose image or config differs from the running containers. For day-to-day code changes with a correct Dockerfile, this is all you need: COPY layers invalidate automatically when file content changes.
docker compose up -d --build
# one service only:
docker compose up -d --build apiStep 2: bust the layer cache with --no-cache
--no-cache reruns every instruction from scratch. You need it when a layer is stale without its instruction text changing: RUN apt-get update && apt-get install picked up its package lists months ago, a RUN curl fetched an artifact that has since changed, or a base tag like :latest moved. Add --pull to also refresh the base image instead of using the locally cached one.
docker compose build --no-cache api
docker compose build --no-cache --pull # also re-pull base images
docker compose up -dStep 3: force-recreate containers
up -d --force-recreate replaces containers even when Compose detects no changes: useful after editing files a container reads at startup, or when a container is in a weird state you want thrown away. Pair with --renew-anon-volumes (-V) to also discard anonymous volumes, the classic fix for a node_modules anonymous volume serving stale dependencies over a rebuilt image.
docker compose up -d --force-recreate
docker compose up -d --force-recreate --renew-anon-volumes apiStep 4: the full clean slate
When you want to eliminate every source of staleness at once (cache, containers, networks) tear down and rebuild from nothing. Only add --volumes if you genuinely intend to delete named volumes too: that is your database data.
docker compose down
docker compose build --no-cache --pull
docker compose up -d
# nuclear (DELETES named volumes / data):
docker compose down --volumesWhy your code changes still do not show up
If a rebuild "does nothing", check mounts before blaming cache. A bind mount of your source directory overrides whatever COPY baked into the image: the container always runs the mounted files, and rebuilding changes nothing. An anonymous volume on a subpath (the node_modules pattern) persists across recreates and keeps serving old content until renewed. docker compose config shows the effective merged configuration, including mounts you forgot were in an override file.
docker compose config # effective config incl. volumes
docker inspect <container> --format "{{json .Mounts}}"Build commands are where "helpful" automation gets expensive: an AI agent that reflexively reaches for --no-cache and down --volumes turns a ten-second rebuild into a twenty-minute one, or deletes a dev database it did not know was load-bearing. Nexus lets you set policy at exactly this granularity: agents may rebuild freely, but destructive flags like --volumes require approval, and every build an agent triggers is attributed in the audit trail with its cost in time and compute.
Explore Swfte NexusCommon questions
- What is the difference between docker compose build and up --build?
- build only produces images: running containers keep using the old ones until recreated. up --build rebuilds and then recreates the affected containers in one step, which is almost always what you actually want during development.
- When do I actually need --no-cache?
- When a layer is stale even though its Dockerfile instruction did not change: cached apt/apk package lists, RUN commands that fetch remote content, or moved base tags. For ordinary source-code changes, COPY invalidates the cache by content hash and --no-cache just wastes minutes.
- Does docker compose restart apply my compose file changes?
- No: restart bounces containers with their existing configuration and never re-reads the compose file. Apply changes with docker compose up -d, which recreates exactly the services whose configuration or image changed.
- Why does my container still have old node_modules after a rebuild?
- An anonymous volume is mounted over that path and survives container recreation, shadowing the rebuilt image content. Recreate with docker compose up -d --force-recreate --renew-anon-volumes, or remove the container and its anonymous volumes with docker compose rm and up.
- Does docker compose down delete my data?
- Plain down removes containers and networks but preserves volumes, so database data survives. down --volumes (or -v) additionally deletes named and anonymous volumes declared by the project. That is the flag that destroys data, so use it deliberately.