TL;DR: Something already owns that host port. Find it with `docker ps` (another container) or `ss -tlnp | grep 8080` (a host process), then stop the other container or pick a different host port like `-p 8081:8080`. Only one listener per host port is allowed, and Docker will not share.

## The error

```text
Bind for the all-interfaces address:8080 failed: port is already allocated
```

## Fix it

1. Check for another container on that port:
   `docker ps --format '{{.Names}} {{.Ports}}' | grep 8080`
   Expected: either a container name (stop or remove it) or nothing.
2. Check host processes:
   `ss -tlnp | grep ':8080'`
   Expected: the process name and PID holding the port.
3. Either free the port (`docker stop [name]`, or stop the host service) or remap:
   `docker run -p 8081:8080 [image]`
   Expected: container starts, reachable on host port 8081.

## When this applies
- `docker run -p` / `--publish` failing with this exact message
- Restarting a container while the old one still holds the port

## When this does NOT apply
- "Ports are not available" (different message, same family; usually the same fix)
- Container-to-container communication (use the container port and docker networks, no host binding needed)

## Versions
All Docker versions, all platforms.

## Why it happens
`-p 8080:8080` asks the daemon to listen on the host's port 8080 for all interfaces. If anything already listens there, the bind syscall fails and the daemon reports it before the container starts.

## Edge cases
- A stopped-but-not-removed container does NOT hold the port; only running ones do. `docker ps -a` showing it is a red herring.
- On Docker Desktop for Mac, host services on the Mac can hold the port; the container port mapping still goes through the VM.
- TIME_WAIT sockets from a just-stopped process can briefly block rebinding; waiting a minute or setting reuse options fixes it.
