skip to content

A container's process listens on port 8080 but nothing off the host reaches it — what does publishing a host port do?

level: juniorimportance: must knowfreq 74%

answer

  1. two claims, not one
  2. the process binds inside only
  3. the host claims a port too
  4. a rule rewrites arriving traffic
  5. host port and container port differ freely

basics

~20 s

Publishing claims a port on the host and installs an address-translation rule, so traffic arriving at that host port is rewritten and delivered to the container's own address and port. The process inside binds nothing on the host and is unchanged.

solid answer

~40 s

The process binds `8080` in the container's own network view, not on the machine. That socket exists on an address only that view can reach, so a client dialling the host on `8080` is refused — nothing there is listening. Publishing is a separate act the platform performs on the host: it claims a port on a host address, installs a rule translating traffic that arrives there into the container's address and port, and installs the reverse rewrite so replies look like they came from the host. The two numbers are independent — host `18080` can map onto container `8080`. Nothing inside the container changes: the application never learns it was published, which is why images normally hard-code one container port and let the host side vary per deployment.

code

yaml · 10 lines
yaml
workload: order-api

# what the process does, entirely inside its own network view
listensInsideOn: 8080

# what the platform does on the host, as a separate claim
publish:
  - acceptedOnHostAddress: loopback   # or: every address the host holds
    arrivesOnHostPort: 18080
    deliveredToPort: 8080

go deeper

for a junior

Remember that binding a port inside a container claims it only in that container's own network view. Reaching it from outside needs a second, separate claim on a host port plus a rule that translates traffic into the container.

for a middle

Be able to explain the mechanics: which side claims what, that the two port numbers are independent, that the rule also rewrites replies, and that a claim is on an address-and-port pair rather than a bare number.

for a senior

Show the triage. Separate "the process is not listening where I think" from "there is no mapping" from "the mapping is on a host address the client cannot reach", and say which evidence distinguishes them.

for a principal

Treat host ports as a scarce, machine-scoped resource that someone must allocate. Decide whether workloads reach each other through published host ports at all, or whether that hop belongs only at the edge of the estate.

## The port the process binds is not a port on the host A container's process asks for a port exactly the way any process does: it opens a listening socket on `8080` and waits. The difference is **whose network stack it asked**. A container is given a private view of the network with its own address, so the socket exists on an address that only that view — and whatever is deliberately routed into it — can reach. From the machine's point of view, nothing at all is listening on `8080`. That is why a client dialling the host's address on `8080` gets a refusal rather than a hang: the host has no claim on that port to hand the connection to. **Publishing a port** is a second, separate act, and the platform performs it on the host, not inside the container: 1. it **claims** the chosen port on one or on every address the host has, so nothing else can take it; 2. it installs a **translation rule** that rewrites traffic arriving there so the packets are delivered to the container's address and the container's port; 3. it installs the **reverse rewrite**, so replies leaving the container are turned back into replies from the host address and port the client actually contacted. How step 2 is implemented is one of the places platform designs genuinely differ: some install the rule in the machine's packet-handling path, others run a small relay process on the host that terminates the incoming connection and opens a second one to the container. What does not differ is the shape — two independent port claims joined by translation. ## The two numbers are independent | | the container port | the host port | |---|---|---| | who picks it | the application, usually fixed in the image | whoever deploys the workload | | where it is claimed | inside the container's own network view | on one or all of the host's addresses | | who has to know it | the process, and the mapping | every client outside the host | | what it can collide with | nothing outside that container's view | every other claim on the same host address | Because they are independent, the ordinary convention is a **fixed container port** baked into the image and a **host port chosen per deployment**. An order API can ship listening on `8080` forever while one host publishes it as `18080` for testers and another as `443`-fronted traffic from a partner integration — with no change to the image, the command line or the application's configuration. Some platforms will also claim an arbitrary free high port for you and report back which one it took. That is convenient when many instances of the same workload share a machine, and awkward when an external client has the port written into its own configuration. ## Which host address accepts the traffic A claim is on an **address and a port together**, not on a bare number. Publishing can therefore target the loopback address only — reachable from processes on that machine and nothing else — or every address the host holds, which includes whichever interface faces the partner network. Platforms differ in what they do when you name no address, and the distinction is exactly what separates "a port I opened so testers on this box can poke the order API" from "a port the internet can reach". If a mapping meant to be local turns out to be reachable from outside, the usual explanation is that it was claimed on all addresses rather than on loopback. ## What publishing does not do - It does **not** change what the process bound to. The application still listens on its container port and can be entirely ignorant of the mapping. - It does **not** make the container's own address routable from other machines; only the host port is reachable, and only through the rule. - It does **not** guarantee the application will see the client's real source address — the same hop commonly rewrites the source as well. - It does **not** give the workload a stable name that survives being replaced; that is a different mechanism entirely. - It does **not** survive the workload moving to another machine: the claim belongs to the host it was made on. ## Reading the failure When "it works inside, not outside", the question is which of three claims is missing. Is the process actually listening in the container's view, and on the address you think — or only on that view's loopback? Is there a mapping at all? And is the mapping claimed on a host address the client can reach? Those are three separate facts, each checkable on its own, and each with a different fix.

  • If the mapping is claimed on only one host address, what changes for callers arriving on the others?
    They are refused, because no claim exists there. That is the deliberate way to publish a port for use on the machine itself — a tester's tunnel, a local check — without exposing it to whichever network the host's other addresses face.
  • Does publishing change anything inside the container?
    No. The process binds the same port in the same view whether or not a mapping exists, and it is not told the host port. That independence is why one image can be published as a different host port on every machine it runs on.
  • What happens when no host port is chosen and the platform picks one?
    It claims a free high-numbered port and reports which one it took. Many instances of one workload can then share a machine without coordination, but every external client has to discover the port rather than having it configured, so fixed integrations usually pin it.

saying these in an interview costs you the question

  • Thinks a container is reachable from outside as soon as the process binds
  • Believes the host port and container port must be the same number
  • Thinks publishing changes which port the application listens on
  • Claims publishing makes the container's own address routable from other machines
  • Treats a successful loopback test inside the container as proof it is published