Here’s a table detailing the differences between the EXPOSE
and PUBLISH
commands in Docker:
Feature | EXPOSE | PUBLISH |
---|---|---|
Definition | EXPOSE is a Dockerfile instruction used to specify which ports an application inside a Docker container listens on. | PUBLISH (often used with the -p flag in Docker CLI commands) maps a container’s port to a host’s port, making it accessible from the host. |
Scope | Dockerfile instruction. It doesn’t actually publish the port but documents which ports are intended to be exposed. | CLI command option during container runtime, actively binds container ports to host ports. |
Syntax Example | EXPOSE 80/tcp | docker run -p 80:80/tcp myimage |
Effect on Networking | It has no effect on accessibility from the host, serves as documentation and a hint for networking between containers. | Makes the container’s port accessible from the host, directly affecting network accessibility. |
Used During | Build-time in Dockerfile, affects the image metadata. | Run-time, affects the running container. |
Default Behavior | Does not make ports accessible from the host, but can be used by linked containers. | Explicitly maps and makes container ports accessible on the host machine. |
Visibility | Ports exposed are visible and can be inspected using the docker inspect command. | Published ports are active and visible both in Docker inspection and from the host network. |
Flexibility | Static, as it’s embedded into the image during the build and cannot be changed unless the image is rebuilt. | Flexible, can be set differently each time a container is run, without changing the Docker image. |
How to Use “EXPOSE” or “–expose” in Docker
The EXPOSE
in the Dockerfile
and the --expose
in the docker run
command work similarly and are used to inform what ports the containerized application listens on. This can be used for inter-container communication. To use the EXPOSE
or --expose
command in Docker, go through the following steps.
Step 1: Create HTML File
First, you’ll need to create a simple HTML program for demonstration. For instance, we have created an index.html
file in nano editor to create an HTML program. You can also use our code for practice:
To create a file, execute the following command:
sudo nano index.html
Now, paste the following snippet into the file. To save the file, hit “CTRL+S” and exit the editor through “CTRL+X”:
<!DOCTYPE html>
<html>
<head>
<title>Sample Application</title>
<style>
body {
background-color: #D2B48C;
}
.container {
text-align: center;
padding: 50px;
}
p {
color:#800000;
font-weight: bold;
}
</style>
</head>
<body>
<div class="container">
<h1>Welcome to Hands-On.Cloud</h1>
</div>
</body>
</html>
Step 2: Generate Dockerfile
Create another file in the nano editor named Dockerfile
and the given snippet into the file:
FROM nginx:latest
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]
In the above snipped, the EXPOSE
command is used to expose the container for inter-container communication, but it cannot be accessible outside the Docker on the host machine:
Step 3: Make a Docker Image
Generate the container blueprint (image) from the Dockerfile
instructions. For this purpose, utilize the given command:
docker build -t html-image .
In the above command, the -t
option will utilized to set the image name, and “.” is used to read the Dockerfile
context from the current working directory:
Step 4: Fire Up Container
Now, fire up the container through the docker run
command:
docker run --name demo-cont html-image
In the given command, --name
is utilized to set the name of the container:
Step 5: List Down the Container
For confirmation, list the Docker containers:
docker ps -a
Here, you can see the demo-cont
is accessible on port 80, specified by the EXPOSE
command. However, this will expose service from inside the container but cannot be accessible on the host machine:
Step 6: Access Containerized Application
Now, access the container shell to access the containerized service from inside the container. For this purpose, execute the docker exec -it <container-name> sh
command:
docker exec -it demo-cont sh
After that, execute the curl http://localhost:80
command inside the container shell to check if the application is executing or not:
The above output shows that we have effectively exposed the application inside the container.
In this case, if the user directly tries to access the containerized service outside the container by directly browsing the http://localhost:80
through the curl
command, they will get the error “Failed to connect to localhost port 80” as shown below:
The above error occurs because the EXPOSE
or --expose
command will expose the containerized service inside the container only. This service cannot be accessible from outside the Docker environment on a host system.
Use “–expose” Option
Alternatively, the user can expose the containerized service for inter-container communication through the --expose
option of the docker run
command:
docker run --name demo-cont --expose 80 html-image
That is how users can expose the containerized service only for containers inside the Docker.
How to Use “-p” or “–publish” in Docker
In order to access the containerized service outside the container on the Host machine, the user can forward the container port on the host system through the --publish
or -p
option of the docker run
command.
For this purpose, go through the mentioned steps.
Step 1: Execute Container
Run the container through the docker run -p <host-port>:<container-port> -- name <container-name> <image-name>
command:
docker run -p 80:80 --name demo-cont1 html-image
The above command will expose the container port “80” on the host system on port “80”:
Step 2: View Containers
List down the containers for verification:
docker ps -a
The below output shows that we have effectively mapped the container port on the host system:
Step 3: Access the Application on the Host System
Now, access the containerized service from outside the container shell directly from the system through the curl
command:
curl http://localhost:80
In this case, we did not get any error and successfully accessed the containerized service on the host machine:
Users can access the containerized service or application from the browser by navigating to http://localhost:80
URL:
We have demonstrated the key difference between --expose
and --publish
in Docker.
Conclusion
The key difference between “–expose” and “–publish” in Docker is that “expose” or “EXPOSE” are utilized to expose the containerized service inside the container. It will be accessible to containers running in Docker but cannot be accessed from outside the Docker on the host machine. In contrast, the “-p” or “–publish” command will be used for port mapping and publishing the container port on the host. This means, containerized service can be accessible outside the container on the host machine. This write-up has covered practical examples to understand the key difference between “–expose” and “–publish” in Docker.