docker-compose
ports
expose
container networking
docker configuration

What is the difference between ports and expose in docker-compose?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Docker Compose is a powerful tool for defining and running multi-container Docker applications. Terminology and nuances within Docker Compose can sometimes cause confusion, especially when it comes to understanding how different components interact with networking. Two such terms that often cause confusion are ports and expose. This article aims to elucidate the differences and purposes of ports and expose directives in Docker Compose.

Understanding ports and expose in Docker Compose

Overview

Both ports and expose directives are related to how Docker containers handle networking, particularly regarding the visibility and availability of services running within containers. However, their usage and implications differ.

ports

  • Function: The ports directive is used to publish ports on the containers to make them accessible from the host. This typically involves mapping a port on the host to a port on the container.
  • Usage: It is defined in the docker-compose.yml file within a service definition.
  • Syntax: The syntax generally involves specifying the host port followed by a colon and the container port, such as 8080:80.
  • Example:
yaml
1    version: '3.8'
2    services:
3      web:
4        image: nginx
5        ports:
6          - "8080:80"

In the example above, port 80 on the container is mapped to port 8080 on the host machine, making the service accessible via localhost:8080.

expose

  • Function: The expose directive is used to expose ports without making them accessible from the host machine. It merely informs other services in the same network of its existence, acting as an internal-only mapping.
  • Usage: Like ports, it is also defined in the docker-compose.yml file within a service definition.
  • Syntax: Unlike ports, it only requires a single port number since it doesn't involve host port mapping.
  • Example:
yaml
1    version: '3.8'
2    services:
3      app:
4        image: myapp
5        expose:
6          - "3000"

In this example, port 3000 is accessible only to other services defined within the same Docker Compose setup or network.

Key Differences

To help further clarify the differences between ports and expose, here is a summary table:

Featureportsexpose
Host AccessibilityYes, via specified host portNo, only within Docker network
Network FunctionalityHost-to-container mappingService-to-service communication
Syntax Requirementhost_port:container_portJust container port (container_port)
Practical Use CaseMaking services available externally; testing via host browser Internal service communication; microservices communication

Additional Details

Implications on Network Mode

  • When using ports, the network mode defaults to bridge, allowing host-to-container communication via mapped ports.
  • When using expose, the default setting often applies more in service networking modes, where internal communication between containers is relevant, and host mapping is irrelevant.

Security Considerations

  • ports: Mapping many host ports can expose applications to external access, which could potentially create security vulnerabilities if not managed correctly. It's important to secure Docker containers (e.g., through firewalls) effectively.
  • expose: By not opening up ports to the host, the expose directive inherently limits unnecessary external exposure, thus offering a more secure approach for internal communications only.

Practical Scenarios

  • ports: Ideal for web applications that need frequent testing or demonstration directly from host machines, as it allows developers to quickly iterate by accessing services via localhost.
  • expose: Useful for microservices architectures, where services need to discover and communicate with one another internally without exposing all services to external traffic.

In conclusion, understanding the difference between ports and expose in Docker Compose involves recognizing the scope of accessibility each one offers. While ports is crucial for enabling external connectivity, expose serves a vital role in facilitating internal communication among containerized services. This discernment can be critical for designing efficient, secure containerized applications tailored to various networking demands.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.