What this fixes
- Errors like: unknown flag: --build, unknown flag: --no-cache, or -d used in the wrong place
- Running options before the subcommand (e.g., docker compose --build up)
- Mixing flags that belong to build with up, or placing flags after service names
- Confusion between docker compose (v2) and docker-compose (v1)
Why the error happens
- Flag scope: Some flags belong to docker compose up (e.g., --build, -d). Others belong to docker compose build (e.g., --no-cache, --pull). Using a flag with the wrong subcommand yields unknown flag.
- Option order: In Docker’s CLI, options must precede positional args (e.g., service names). For up, put flags before services: docker compose up --build web, not docker compose up web --build.
- Subcommand position: Global options (like -f) go before the subcommand. Subcommand options go after it: docker compose -f compose.yaml up --build -d.
- Version mismatch: Old binaries or mixing docker compose (v2) with docker-compose (v1) can change availability of flags or error messages.
Quickstart: correct patterns
- Build then start (rebuild only when needed):
- docker compose build
- docker compose up -d
- Build during up:
- docker compose up --build -d
- Rebuild without cache:
- docker compose build --no-cache
- docker compose up -d
Common mistakes that trigger unknown flag:
- docker compose --build up # wrong; --build must follow up
- docker compose up web --build # wrong; flags must come before service names
- docker compose up --no-cache # wrong; --no-cache is for build, not up
Minimal working example
Create three files in an empty directory.
Dockerfile:
FROM alpine:3.20
RUN echo "hello from image" > /hello.txt
CMD ["sh", "-c", "cat /hello.txt && sleep 3600"]
compose.yaml:
services:
app:
build:
context: .
image: example/app:dev
container_name: example-app
Commands (correct order):
# 1) Clean build, then start detached
docker compose build --no-cache
docker compose up -d
# 2) Or build on the fly when starting
docker compose up --build -d
# 3) Using a custom file (global -f before subcommand)
docker compose -f compose.yaml up --build -d
Examples that fail with unknown flag:
# Wrong: subcommand options placed before the subcommand
docker compose --build up
# Wrong: options after service names
docker compose up app --build
# Wrong: build-only flags used with `up`
docker compose up --no-cache
Step-by-step fix
Identify your subcommand
- Are you starting services (up) or only building images (build)? Choose the right one first.
Place options correctly
- Global options (e.g., -f) go before the subcommand: docker compose -f compose.yaml up ...
- Subcommand options go right after the subcommand: docker compose up --build -d
- Put service names at the end: docker compose up --build web api
Use the right flag for the job
- Rebuild images while starting: up --build
- Ignore cache: build --no-cache (then up)
- Pull latest base images: build --pull (then up)
Check your Compose variant and version
- docker compose version # v2 plugin
- docker-compose version # legacy v1
- Prefer docker compose (v2). If one is missing or very old, update Docker/Compose.
Retry with the minimal example
- If the example works, the issue is command order/flags in your project.
Flag scope reference
| Goal | Correct command |
|---|---|
| Start containers (no rebuild) | docker compose up -d |
| Start and rebuild if needed | docker compose up --build -d |
| Force a clean rebuild | docker compose build --no-cache |
| Pull base images before build | docker compose build --pull |
| Specify compose file | docker compose -f compose.yaml up -d |
| Start only selected services | docker compose up --build web api |
Notes:
- Flags for up (e.g., --build, -d, --no-deps, --force-recreate) must follow up and precede services.
- Flags for build (e.g., --no-cache, --pull, --progress) must follow build.
Pitfalls to avoid
- Mixing v1 and v2: docker-compose up vs docker compose up within the same project may mask issues. Standardize on docker compose.
- Flags after services: up web --build is parsed as an argument; Compose won’t see the flag.
- Wrong working directory: run commands in the folder containing compose.yaml (or point to it with -f).
- Expecting up to accept build-only flags: --no-cache and --pull belong to build.
- Misplacing -f: docker compose -f file up --build is correct; docker compose up -f file --build is not.
Performance notes
- Avoid always using --build: it forces checks and potential rebuilds. If images didn’t change, a plain up is faster.
- For deterministic CI builds, prefer: docker compose build --pull --no-cache; then docker compose up -d.
- Build cache efficiency: small, ordered Dockerfile layers and pinned bases speed rebuilds.
- Parallelism: docker compose build can build multiple services; leverage that instead of serial docker build calls.
FAQ
Q: Why does docker compose --build up fail? A: --build is an option for up, so it must follow the subcommand: docker compose up --build.
Q: Can I use --no-cache with up? A: No. Use docker compose build --no-cache, then docker compose up.
Q: Do flags go before or after service names? A: Before. Example: docker compose up --build web; not docker compose up web --build.
Q: What’s the difference between docker compose and docker-compose? A: docker compose is the v2 plugin (preferred). docker-compose is legacy v1. Use one consistently, ideally v2.