Add `--no-ports-bind` flag to skip port bindings during `docker-compose up`
Description
✏️ Pull Request Description
What
This PR adds:
docker-compose up --no-ports-bind
to skip ports: host bindings in docker-compose.yml during container creation.
Why
By default, Docker Compose respects all ports: mappings so containers can be accessed from the host (e.g., browsers, Postman) during local development.
However, in CI pipelines, port bindings are often unnecessary:
- Containers communicate internally over Docker networks.
- Skipping port bindings allows multiple isolated instances of the same Compose stack to run in parallel on a single CI runner, avoiding port conflicts.
- This enables parallel test execution for PHP projects that require real MySQL, filesystem, and cache access during tests, leveraging all CI cores efficiently.
Currently, teams must:
- Edit YAML files,
- Maintain override files,
- Use scripts to remove
ports:, to achieve this behavior in CI.
Example
-
Local dev:
docker-compose up(with ports for host/browser access)
-
CI parallel tests:
docker-compose up --no-ports-bind(no host port conflicts, safe for N parallel instances)
Let me know what you think.
The recommended approach to distinguish development environment (where you want port exposed) and other targets (CI/production) is to rely on override files. Typically, you could have a compose.override.yaml file with ports declared for development (which will be loaded automatically) and set CI to only target the main compose.yaml file.
We also introduced develop section, which I had in mind could offer a set of ports that would be only exposed in "development mode" (TBD)
Typically, you could have a
compose.override.yamlfile with ports declared for development (which will be loaded automatically) and set CI to only target the maincompose.yamlfile.
The override could also just exist in the CI to unset configured the ports too which might make more sense in this context.
Closing as "not planned". Distinction between dev/CI/prod environment is better managed with an explicit override file