When building and running Docker containers, exposing ports is a common requirement to allow external access to applications inside the container.
Many developers know how to expose a single port using the EXPOSE instruction in the Dockerfile or the -p flag in docker run. But what if your application requires multiple ports to be exposed—for example, a web server on port 80 and an API service on port 5000?
In this blog, we’ll explore how to expose multiple ports in Docker using different approaches.
✅ Why Expose Multiple Ports?
- Microservices where a single container serves multiple purposes.
- Applications that need both HTTP (port 80) and WebSocket (e.g., port 3000).
- Database containers exposing both database port and admin UI port.
- Custom applications that use multiple services inside the same container.
✅ 1️⃣ Exposing Ports in Dockerfile
In your Dockerfile, you can expose multiple ports using multiple EXPOSE statements:
FROM node:16-alpine
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
EXPOSE 5000
CMD ["node", "index.js"]
This defines that your container will expose both port 80 and 5000.
However, keep in mind that EXPOSE is only metadata for documentation purposes. It does not automatically publish the ports to the host system when running the container.
✅ 2️⃣ Publishing Ports with docker run
To actually map container ports to host ports, use multiple -p flags in the docker run command:
docker run -d \
-p 8080:80 \
-p 5000:5000 \
my-image
This maps:
- Container port
80to host port8080 - Container port
5000to host port5000
✅ 3️⃣ Using Docker Compose for Multiple Ports
If you use Docker Compose, defining multiple port mappings is simple and elegant.
Example docker-compose.yml:
version: "3.8"
services:
myapp:
image: my-image
ports:
- "8080:80"
- "5000:5000"
Running docker-compose up -d will expose both ports as defined.
✅ 4️⃣ Best Practices
- Only expose the ports that are necessary for external access.
- For internal-only services, avoid exposing ports to reduce attack surface; instead, use Docker networking.
- Keep container and host port mappings consistent to avoid confusion.
✅ Conclusion
Exposing multiple ports in Docker is straightforward:
- Use multiple
EXPOSEcommands in your Dockerfile for metadata. - Use multiple
-poptions indocker runfor explicit port mapping. - Use the
portssection indocker-compose.ymlfor declarative configuration.
This flexibility makes Docker a great tool for complex applications needing multiple exposed services, all while keeping configuration simple and maintainable.