The EXPOSE instruction in a Dockerfile informs Docker that the container will listen on specified network ports at runtime, serving as documentation without actually publishing the ports.
The EXPOSE instruction declares the ports on which the container will listen for network connections. It serves primarily as documentation for developers and as metadata for the image, indicating which ports the application inside expects to use. However, it's important to understand that EXPOSE does not actually publish the ports or make them accessible from outside the container—it simply records the information for future reference.
When you specify EXPOSE in your Dockerfile, the information becomes part of the image metadata. You can view this information with docker inspect or docker image history, and other tools can use it to understand what ports the application expects. For example, when running a container with the -P flag (uppercase P), Docker will automatically publish all exposed ports to random high-numbered ports on the host, which can be useful for testing.
EXPOSE does not actually make ports accessible from the host—it's purely informational .
To make ports accessible, you must publish them at runtime using -p (lowercase) or -P (uppercase) with docker run .
The -p flag overrides EXPOSE, allowing you to publish any port regardless of what's declared .
EXPOSE accepts TCP (default) or UDP protocol specifications .
Multiple EXPOSE instructions can be used, or you can list multiple ports in one instruction .
The combination of EXPOSE and the -P flag is particularly useful: docker run -P my-image will automatically map all exposed ports to random ports on the host, which you can discover with docker port. This is convenient for development and testing when you don't care which host ports are used. For production, you'll typically use explicit -p mappings to control exactly which host ports are used.