Today I learned that even though expose in Docker Compose doesn’t actually publish a port to the host (like ports does), it’s still useful — especially for clarity and internal networking.

When I was reading about Docker Compose’s expose vs ports, I realized expose serves a different purpose:
it tells other containers in the same Docker network which ports a service is listening on, without exposing them to the outside world.

For example:

services:
  backend:
    build: ./backend
    expose:
      - "4000"

  frontend:
    build: ./frontend
    depends_on:
      - backend

Here, the frontend can call the backend using http://backend:4000,
but my host machine can’t access port 4000 — and that’s the point.

What I learned:

  • expose is for internal visibility, while ports is for external access.
  • It helps document internal communication between containers.
  • It keeps sensitive services (like databases or APIs) isolated from the outside world.
  • It also makes the network design easier to understand later.

Small detail, big value — especially when your Compose file starts to grow and clarity becomes gold.

Difference Between Expose and Ports in Docker Compose | Baeldung on Ops
Explore the differences between expose and ports when using Docker Compose.

#TIL - Why expose in `Docker Compose` Still Matters

TIL that expose in Docker Compose is more than just decoration — it’s for internal visibility, clarity, and security between services.