-
Notifications
You must be signed in to change notification settings - Fork 8.1k
docs: Add documentation for IP:HOST_PORT:CONTAINER_PORT syntax #22511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add explanation and examples for binding ports to specific network interfaces using the extended syntax. This addresses issue docker#22253.
✅ Deploy Preview for docsdocker ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
|
Hi @Antraxmin - thank you for working on this, it looks good. As @akerouanton noted on the issue, a wider review of the port publishing documentation is needed. It's got quite complicated, and the documentation is incomplete and split between a few places. But, that shouldn't stop us from making this incremental improvement first. In the meantime though ... I think it'd be good to add a link from this new section to https://docs.docker.com/engine/network/packet-filtering-firewalls/#setting-the-default-bind-address-for-containers - it partially describes config param The "Important" note just above this new section hints at what's described in this new text, and links to another page with some of the same description - which might be confusing. Perhaps change change its last sentence to "See [Binding to specific network interfaces] below, and [learn more about published ports here]."? |
Hi @robmry , thank you for your review and suggestions!
I completely understand this is just an incremental improvement while a more comprehensive review of port publishing documentation is pending. I hope this small addition helps users in the meantime. If there's anything I misunderstood, please let me know. If there's no particular problem, I'll work on it in more detail! |
|
Thank you @Antraxmin - that sounds great, much appreciated. |
|
I've updated the PR with the requested changes: 8ad69cc
These changes should help users better understand the options available for controlling which network interfaces their container ports are bound to. Let me know if any further adjustments are needed! |
robmry
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - thank you!
|
@robmry Oops, you already approved this PR, but I accidentally hit the request review button. Please ignore the second request. My mistake! |
No worries! We'll need a review from Docker's docs team, and I think they're a bit short-handed at the moment. |
|
Thanks for the pull request. We'd like to make our product docs better, but haven’t been able to review all the suggestions. If the updates are still relevant, review our contribution guidelines and rebase your pull request against the latest version of the docs, then mark it as fresh with a Prevent pull requests from auto-closing with a /lifecycle stale |
|
/remove-lifecycle stale |
|
cc @ArthurFlag |
ArthurFlag
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, thank you!
akerouanton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for updating that guide!
Please see my comments below — we need to not conflate 'binding on a specific interface' and 'binding on a specific HostIP'.
| ### Binding to specific network interfaces | ||
|
|
||
| By default, when you publish a port, Docker binds to all network interfaces (`0.0.0.0`). However, there are scenarios where you might want to restrict access to a specific network interface or IP address. You can do this by using the extended port syntax: | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of BSD socket API, binding to a specific interface isn't the same as binding on a specific IP address — both can be combined. This is done via SO_BINDTODEVICE.
I think we should not conflate both here. The Engine doesn't support binding to a specific interface, but it supports binding to a specific HostIP.
| #### Common use cases for IP binding | ||
|
|
||
| - **Security**: Binding to localhost (127.0.0.1) to prevent external access to services like databases | ||
| - **Multi-homed hosts**: Binding to specific network interfaces on servers with multiple IP addresses |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not true — and this is where the claim that it can bind to a specific interface may instill a false sense of security.
If a port is mapped to a specific IP address, and the host has multiple interfaces, that IP address will be accessible through all interfaces by default.
This can be easily tested with the following commands on a host running the Engine (or from a dind container):
$ ip netns add test
$ ip link add name veth-dockerd type veth peer name veth-test
$ ip link set veth-test netns test
$ ip addr add 10.10.0.1/24 dev veth-dockerd
$ ip link set veth-dockerd up
$ ip netns exec test ip addr add 10.10.0.2/24 dev veth-test
$ ip netns exec test ip link set veth-test up
The 'multi-homed host' here is a dind container that has its original IP address (e.g. 172.17.0.3), plus 10.10.0.1.
You can then start a container targeting a specific HostIP:
$ docker run --rm -d -p 172.17.0.3:80:80 traefik/whoami
Finally, we can test whether 172.17.0.3:80 is accessible from the 'test' netns, but first we need to add a route to that address to let it know how it can reach it:
$ ip netns exec test ip route add 172.17.0.3/32 via 10.10.0.1
$ ip netns exec test ip -brief route show
10.10.0.0/24 dev veth-test proto kernel scope link src 10.10.0.2
172.17.0.3 via 10.10.0.1 dev veth-test
$ ip netns exec test curl http://172.17.0.3
Hostname: 4ab70ca9633d
IP: 127.0.0.1
IP: ::1
IP: 172.18.0.2
RemoteAddr: 10.10.0.2:43822
GET / HTTP/1.1
Host: 172.17.0.3
User-Agent: curl/7.88.1
Accept: */*
If users don't want that behavior, they need to set up firewall rules. (I'm not sure if that's clearly documented though.)
However, note that this is not true for loopback addresses (i.e. 127.0.0.0/8 and ::1/128) since v28.0 (see this blog post, and this changelog entry), as these aren't supposed to be routed anyway.
Add explanation and examples for binding ports to specific network interfaces using the extended syntax. This addresses issue #22253.
Description
Added documentation for the extended port publishing syntax
IP:HOST_PORT:CONTAINER_PORT, which was missing from the current documentation. This change improves the "Publishing and exposing ports" page by explaining how to bind container ports to specific network interfaces on the host machine.The additions include:
This documentation helps users understand how to restrict container access to specific network interfaces, which is especially important for securing sensitive services like databases.
Related issues or tickets
Fixes #22253
Reviews