Skip to content
BreezeDelegatePublic

About

Docker Compose preflight: find port conflicts, bind mount problems and configuration changes before deployment

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

31 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BeforeUp: Docker Compose checks before deployment

BeforeUp

GitHub release file downloads Latest stable release MIT license

Release download totals count requests for individual release files, including preview builds, checksums and maintainer verification. They are not unique users or installations.

See what your next Docker Compose deployment would change before replacing running containers.

docker compose config can validate a Compose file without comparing it with the stack already running. BeforeUp adds two read-only checks on a native Linux Docker host:

  • beforeup compare -f compose.yaml compares the proposed configuration with running containers from the same Compose project. It reports selected changes to published ports, data mounts, declared environment settings and image references. Where available, it also checks local image IDs for unchanged tags.
  • beforeup check -f compose.yaml examines selected host-side conditions that configuration validation does not establish, including occupied ports, missing local bind sources or build directories, Docker access and low disk headroom.
beforeup compare -f compose.yaml
beforeup check -f compose.yaml

BeforeUp never runs up, down, pull or build, and does not change your containers. A clean report does not guarantee a safe or successful deployment. Comparison is partial and requires access to the relevant running containers.

Demo: Compose validation passes, but a host port is busy

18-second BeforeUp terminal demonstration: Docker Compose validates the configuration, then BeforeUp reports an occupied host port and a missing bind source

18-second animated replay of results observed on an isolated Linux Compose fixture. This demonstrates check, not compare. An occupied port is a warning, not proof that deployment will fail. Watch the MP4 | Static preview

Try it

Requirements: Docker CLI with Compose v2, Linux, and ss (from iproute2). Syntax validation works without Engine access; host and running-container checks require permission to access Docker. BeforeUp reports missing access instead of requesting privilege escalation.

Debian/Ubuntu (amd64): download beforeup_0.4.4_amd64.deb from the v0.4.4 release, verify its hash against SHA256SUMS, then install:

sha256sum -c SHA256SUMS --ignore-missing
sudo apt install ./beforeup_0.4.4_amd64.deb
beforeup check -f compose.yaml

For other supported Linux hosts, download the amd64 or arm64 tarball and verify its SHA-256 checksum. You can also build from source with Go 1.24 or newer:

git clone https://github.com/BreezeDelegate/beforeup.git
cd beforeup
go build -o beforeup .
./beforeup check -f compose.yaml

See the full installation guide and compatibility matrix. A separately verified experimental Windows Docker Desktop preview is available for Linux containers only; the stable Linux release remains v0.4.4.

beforeup check
beforeup check -f compose.yaml --format json
beforeup check -f compose.yaml --profile debug --env-file staging.env
beforeup compare -f compose.yaml
beforeup compare -f compose.yaml --strict --format json

Run it in a directory containing your Compose project, or provide -f. Repeated -f, --profile, and --env-file options are supported.

Compare a planned change to what is running

beforeup compare -f compose.yaml checks the proposed Compose configuration against running containers belonging to the same Compose project. It can tell when:

  • a published host port is added or removed;
  • an existing container's bind source or named volume would change;
  • a currently mounted data path would no longer be mounted;
  • a declared environment setting or image reference differs from the running container (without printing secret values);
  • a local image with the same tag is now different from the image used by the running container (when the image IDs can be inspected);
  • an existing running service is absent from the proposed resolved Compose model;
  • an intended service has no running counterpart.

Use repeated -f options for overrides, just as you would with Docker Compose. This is read-only: it does not simulate a replacement, stop containers or create volumes.

A matching report means only the inspected port bindings, data mounts, declared environment settings and image reference appear unchanged. It may also compare a locally available image ID. It does not prove that the remote registry image, inherited environment, command, networks or application behavior are unchanged. Stopped services do not have a reliable running baseline. When a service has multiple running replicas, BeforeUp reports REPLICAS_UNSUPPORTED for that service while still checking unrelated services; it does not claim the whole stack is unchanged. A missing baseline is reported explicitly, never treated as healthy.

What it checks

Finding What it means
COMPOSE The Docker configuration was resolved successfully
DAEMON Docker Engine is reachable by the current account
RESTART_POLICY_OVERRIDDEN On verified Compose 5.5.0, 5.5.1, 5.6.0 and 5.6.1, an incomplete deploy policy can silently replace an explicit service restart policy (warning)
RESTART_POLICY_INVALID On those versions, a positive max_attempts without condition: on-failure can prevent container creation (warning)
PRE_START_REPLICA_UNSUPPORTED On independently tested Compose 5.5.0, 5.5.1, 5.6.0 and 5.6.1, pre_start.per_replica: true passes config validation but is rejected at startup (warning)
PORT_IN_USE A requested TCP/UDP host port has an unassigned listener
PORT_OWNED_BY_SERVICE The running version of this service already owns its published port
PORT_BINDING_CHANGED The running service uses the requested port on a different host address
PORT_USED_BY_OTHER Another Docker service publishes the requested port
PORT_COLLISION Two services in the same project have a confirmed host-port collision
PORT_DUAL_STACK_UNCERTAIN IPv4/IPv6 bindings may conflict, depending on host dual-stack policy
ROOTLESS_LOW_PORT A rootless Docker host port below 1024 may need additional permissions
ROOTLESS_BIND_UNVERIFIED Existing bind sources may still fail due to rootless UID/GID mapping
DESKTOP_VM Docker Desktop on Linux uses a VM; local host probes are skipped
BIND_MISSING A local bind source is absent; an explicitly non-creatable path blocks startup
DISK_LOW The filesystem holding Docker's data has less free space than the configured threshold
CONTEXT A remote Docker endpoint prevents meaningful local host checks
ENV_CHANGED Declared container environment differs from running settings, with no values printed
IMAGE_REFERENCE_CHANGED Proposed image reference differs from running container reference
LOCAL_IMAGE_UPDATED A locally available image with the same tag now differs from the running container image
SERVICE_ABSENT_FROM_PROPOSAL Running service missing from proposed resolved model; may remain as an orphan
PORT_ADDED / PORT_REMOVED A proposed deployment changes a published host port
MOUNT_REMOVED / MOUNT_SOURCE_CHANGED A mounted data path or its source changes
NO_ACTIVE_SERVICES No services are selected by the current Compose profiles

Bind source paths are deliberately omitted from reports, because environment interpolation can place sensitive values in them. A missing bind source using legacy short syntax is a warning, not necessarily a failure: Docker may create a new empty directory. A port in use is also a warning. An already-running Compose stack can legitimately own its own published port.

These runtime-mismatch warnings are enabled only for Docker Compose 5.5.0, 5.5.1, 5.6.0 and 5.6.1, independently reproduced with Docker Engine 29.8.1 on native Debian 13. Other Compose versions are not classified by these checks until tested; their absence is not proof of compatibility. These warnings do not run containers or change restart settings. For suspected restart-policy problems, compare docker compose config with the container's HostConfig.RestartPolicy via docker inspect on an isolated deployment. Removing per_replica changes hook semantics and is not a universal fix.

The default disk warning threshold is 2 GiB. Change it with --min-free-gib N, or use zero to disable that check. The warning concerns available headroom, not the space your images will actually need.

For rootless Docker, BeforeUp does not assume that an existing host bind source can be accessed by the container. Privileged host ports may be allowed through system or RootlessKit settings; those cases remain warnings, never confirmed blockers. On Docker Desktop for Linux, local socket, bind-source and disk checks are skipped because Docker Engine runs inside a VM. Container-metadata comparison can still run.

For CI/CD on the target Linux host, see the preflight pipeline guide and its reproducible exit-code test.

Output and exit codes

The normal output is text suitable for a terminal; --format json emits findings with stable IDs, severity, service and advice.

You can reproduce 14 Docker Compose configuration scenarios locally after building BeforeUp:

go build -o beforeup .
python3 tests/compose_matrix.py --binary ./beforeup
python3 tests/compose_runtime_guards.py --binary ./beforeup  # only these four tested Compose versions

This optional test needs Python 3 and authorized local Docker Engine access. It only calls Docker Compose configuration validation and read-only host queries. The running-project ownership and comparison scenarios are covered separately in Go tests and validation notes.

  • 0: checks completed without a confirmed blocker. Warnings may be present.
  • 1: at least one blocker, or a warning when --strict is set.
  • 2: configuration could not be inspected or the command was invalid.

--strict affects only the exit status; it does not change the severity or certainty of any finding. Use it only when warnings should fail CI. A passed check is not a guarantee of a successful deployment. See real troubleshooting examples for cases where the native Docker commands already solve the problem.

What it does not know

BeforeUp cannot predict whether an image will pull, whether a service will become healthy, whether an app will reach its database, or whether another process will claim a port between the check and startup. It does not scan container images for vulnerabilities.

Local filesystem and socket checks are skipped for remote or Docker Desktop VM endpoints. Run on the intended native Docker host for those checks. Docker rootless, IPv6-only sockets and SELinux configurations still need independent end-to-end validation.

Docker Compose still processes your project and its environment files. Although BeforeUp does not print resolved environment values, you should treat Compose configurations as sensitive material.

BeforeUp does not run up, create directories, change permissions, clean Docker resources or modify your configuration. It runs read-only inspection commands. See security notes.

Contributing

Issues about false positives, genuine missing checks and small reproducible Compose examples are welcome. Please remove credentials and customer details before sharing a configuration.

See CONTRIBUTING.md, common Docker Compose problems, validation notes and the French README.

MIT licensed. LICENSE. Maintained by BreezeDelegate; professional work at vitrine.bar.

About

Docker Compose preflight: find port conflicts, bind mount problems and configuration changes before deployment

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages