Docker Compose Ports
Here is a comprehensive reference page for the ports configuration in Docker Compose.
Overview
The ports configuration in docker-compose.yml maps ports from the Container to the Host machine. This allows external traffic (from your browser, other computers, or the host itself) to access services running inside your containers.
1. The Short Syntax
This is the most common method. It uses a string format to define the mapping.
Note: Always use quotes (e.g.,
"80:80") when using the short syntax. If you omit them, YAML may interpret ports like22:22as a base-60 number, causing errors.
Format: [HOST:]CONTAINER[/PROTOCOL]
| Format | Description | Example |
| “HOST:CONTAINER” | Maps a specific host port to a container port. | - "8080:80" (Host 8080 $\to$ Container 80) |
| “CONTAINER” | Maps the container port to a random ephemeral port on the host. | - "3000" |
| “IP:HOST:CONTAINER” | Binds the port to a specific network interface (IP) on the host. | - "127.0.0.1:8001:8001" |
| Range | Maps a range of ports. | - "3000-3005:3000-3005" |
Example: Short Syntax
services:
web:
image: nginx
ports:
- "8080:80" # Map host 8080 to container 80
- "127.0.0.1:3000:80" # Map localhost 3000 to container 80 (Restricted to host only)
- "443:443" # Map HTTPS
2. The Long Syntax
The long syntax allows for more configuration options and is generally more readable. It is available in Compose file formats v3.2 and later.
Attributes:
-
target: The port inside the container.
-
published: The port exposed on the host.
-
protocol:
tcporudp(defaults to tcp). -
mode:
host(publish on every node) oringress(load balanced).
Example: Long Syntax
services:
database:
image: postgres
ports:
- target: 5432
published: 5433
protocol: tcp
mode: host
3. Protocol Specification (TCP/UDP)
By default, Docker assumes TCP. To expose UDP ports (common for DNS, streaming, or gaming servers), you must specify it.
Short Syntax:
ports:
- "53:53/udp"
- "53:53/tcp"
Long Syntax:
ports:
- target: 53
published: 53
protocol: udp
4. ports vs. expose
Users often confuse these two configuration keys.
| Feature | ports | expose |
| Accessibility | Accessible from the Host machine and external network (internet). | Accessible ONLY to other services within the same Docker network. |
| Use Case | Web servers, APIs, Databases you need to access from your laptop. | Databases or Redis caches that only your backend app needs to talk to. |
| Example | - "80:80" |
- "6379" |
Common Pitfalls & Best Practices
-
Security Risk (0.0.0.0): By default,
- "3000:3000"binds to0.0.0.0, meaning anyone with your IP address can access that port. If you are developing locally, always bind to localhost to prevent outside access:YAMLports: - "127.0.0.1:3000:3000" -
Port Conflicts: If you try to run two containers mapping to the same Host port (e.g., both trying to use port 80), Docker will fail to start the second one. You must change the Host side of the mapping (e.g.,
"8081:80").
