✦ For everyone, free.

Practical knowledge for real and everyday life

Home

Service Ports Field

Service Ports Field defines how Docker containers expose applications, linking internal services to external networks through configurable port mappings

The ports field within a Compose service publishes one or more of that service's container ports to the host, making them reachable from outside the Compose-managed network, exactly as the -p flag would for an individual docker run command.

Publishing a Port

The most common form maps a specific host port to a specific container port.

services:
  api:
    ports:
      - "8080:8080"

This makes the API, listening on port 8080 inside its container, reachable at localhost:8080 from the host.

Mapping to a Different Host Port

The host-side and container-side ports don't need to match, allowing the same container port to be exposed differently depending on need.

services:
  api:
    ports:
      - "3000:8080"

The API still listens on port 8080 inside its container, but is reached at port 3000 on the host.

Why Most Services in a Stack Don't Need Published Ports

A service that's only ever reached by other services within the same Compose application — a database, for instance — generally doesn't need a ports entry at all, since Compose's automatic networking already makes it reachable to other services by name without any host-level publishing.

services:
  db:
    image: postgres:16
  api:
    ports:
      - "8080:8080"
    environment:
      - DATABASE_URL=postgres://db:5432/app

Here, only api (which needs to be reached from outside the Compose application, such as from a browser) has a ports entry; db is reachable by api through the network alone.

Publishing to a Specific Host Interface

A port can be bound specifically to a particular host interface, such as localhost only, restricting where the published port is actually reachable from.

services:
  api:
    ports:
      - "127.0.0.1:8080:8080"

Why the Ports Field Matters

Correctly using ports only where a service genuinely needs to be reachable from outside the application avoids unnecessarily exposing internal services, while still ensuring exactly the right entry points into the application are accessible as intended.