What is the syntax of the Dockerfile EXPOSE Command? - docker

Reading the docker documentation at https://docs.docker.com/engine/reference/builder/#expose the expose command syntax is described as:
EXPOSE <port> [<port>/<protocol>...]
To me, this indicates that I can use it like:
EXPOSE 8080
EXPOSE 8080 8081/tcp 8082/udp
but not
EXPOSE 8080/tcp
The examples they give contradict this:
EXPOSE 80/udp
and to expose the same port on different protocols they suggest using two lines:
EXPOSE 80/tcp
EXPOSE 80/udp
What does the syntax description actually mean?
Does EXPOSE 8080 8081 expose two ports?
Is EXPOSE 80/tcp 80/udp illegal?

The syntax is actually something like
"EXPOSE ", { p };
where
p = port, [ "/", proto ], " ";
(in EBNF)
Does EXPOSE 8080 8081 expose two ports?
Yes
Is EXPOSE 80/tcp 80/udp illegal?
No

Related

Is there a way to unexpose a port in Dockerfile?

I am trying to deploy a mosquitto MQTT broker in our corporate cloud through docker image. The allowed ports that are exposed are in the range of 10000-10999.
By default eclipse-mosquitto image exposes port 1883. Is there a way to unexpose port 1883 and expose 10883?
This is my Dockerfile:
FROM eclipse-mosquitto:latest
COPY mosquitto.conf /mosquitto/config/
COPY docker-entrypoint.sh mosquitto-no-auth.conf /
EXPOSE 10883
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["/usr/sbin/mosquitto", "-c", "/mosquitto/config/mosquitto.conf"]
Just because the container exposes port 1883 that doesn't mean that's the port you need to use access a running instance.
When you start the container using the docker run command you get to decide what port on the host machine is mapped to that port on the container.
E.g.
docker run -d -p 10883:1883 eclipse-mosquitto
This will expose port 10883 on the host and map it to 1883 on the container.
"Expose" in dockerfile is kind of a meta data which tells which port you should work with. It does not open any port. So you can easily open any port you want.

The server doesn't respond anymore after I switch framework Gin to Echo

I used to use Gin(Golang framework) and deploy docker image to GKE.
It was working totally fine.
But the server doesn't respond anymore when I switched Gin to Echo(it is also Golang framework)
I think it is because there is something wrong with port combination(port forwarding).
My echo server code is like below.
func main() {
e := presentation.Router()
e.Logger.Fatal(e.Start(":8080")) // listen and serve on :8080
}
and my dockerfile is like below.
FROM alpine:3.9
WORKDIR /app
ADD main /app
ENV PORT 80
EXPOSE 80
CMD ["./main"]
When request reaches to 80 port, it has to render to 8080 port (container port).
But it doesn't seem that it is working like above at the moment.
How can I match outer port and inner port??
Use the command docker run -p 80:8080 image_name for running the container, it will publish the port 8080 of the container and map it with port 80 of the host.

Unable to run application on Docker if used any other port except default port 80

I have a demo app which is hosted on docker. The exposed port for Docker is 80 and the app is running fine on local machine and I am able to see landing page for my app on localhost:8888.
Docker file is as given below
FROM microsoft/aspnetcore:2.0
COPY dist /app
WORKDIR /app
EXPOSE 80/tcp
ENTRYPOINT ["dotnet", "demoapp.dll"]
Whenever I change line "EXPOSE 80/tcp" to for ex- "EXPOSE 8080/tcp" , "EXPOSE 5000/tcp" etc to expose any other port except 80 of Docker container as given in many online available sample codes, I am unable to run my app on browser. Any port except 80 is not working.
I am able to create image and create container for application too. Everything goes well but when I try to run app on browser (localhost:8080/5000/9000 etc.) The app landing page doesn't load.
Any suggestions? Do I need to do some port related configuration or contact my network team? or any code which I am missing here?
You should be able to expose any port inside the container.
However you publish the exposed port on the host during the start of the container.
This is done with the -p flag of the docker run command.
When you say you are able to access the application using localhost:8888 it means you have run the docker run command with -p 8888:80. This publishes the container port 80 onto the host as port 8888.
To use any other port just change the docker run command to -p 8888:<new exposed port> and that should do it.
See the docker run command help for more info:
https://docs.docker.com/v17.12/edge/engine/reference/commandline/run/#publish-or-expose-port--p-expose
Publish or expose port (-p, –expose)
$ docker run -p 127.0.0.1:80:8080 ubuntu bash
This binds port 8080 of the container to port 80 on
127.0.0.1 of the host machine. The Docker User Guide explains in detail how to manipulate ports in Docker.
If your application runs at port suppose 8080 then make sure to do port mapping while running the container.
docker run -itd -p 8080:8080 <image>
This will map port 8080 of host on port 8080 inside the container. (-p hostport:containerport)
If you don't want port mapping then run docker container in host mode.
docker run -itd --net=host <image>
In this case your container use host network, so whatever port your application is running inside it should get exposed.
For microsoft/aspnetcore, it sets the ASPNETCORE_URLS environment variable to http://+:80 which means that if you have not explicity set a URL in your application, via app.UseUrl in your Program.cs for example, then your application will be listening on port 80 inside the container.
Reference: microsoft/aspnetcore
If you want to change the default port 80, you need to use UseUrls in Program.cs with like below, and use EXPOSE 8080/tcp in dockerfile.
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseUrls("http://+:8080")
.UseStartup<Startup>();
Or, you need to change ASPNETCORE_URLS environment like
FROM microsoft/aspnetcore:2.0
COPY dist /app
WORKDIR /app
EXPOSE 8080/tcp
ENV ASPNETCORE_URLS=http://+:8080
ENTRYPOINT ["dotnet", "demoapp.dll"]
Command to run
docker run -it -p 8080:8080 mytest

How to expose more ports on a running docker container

I have exposed port 3306 on my docker container, and I would like to install a web server on it and expose port 80 on the same container.
I don't think you can actually expose more port as the container is running, you'll have to recreate it and expose all of your ports

Close Docker expose port from parent file

I have made my own Dockerfile for a apache server that starts with an standard parent file. See first line in my Dockerfile below:
FROM php:7.0-apache
EXPOSE 8080
This parent exposes port 80. Now have I exposed port 8080 in my Dockerfile. Only when I run it both ports are exposed.
It it posible to close the parent port 80 in my Dockerfile? As I cannot edit that file.
Unfortunately, this is currently impossible.
But you can follow this issue on Docker's GitHub. It's from 2014, but it is still Open. Never know...
As an alternative, rather than editing the configuration in the docker image you can also use port mapping to achieve the same result.
For example mapping port 8080 on the host to port 80 within the docker image, like so:
docker run -d -p 8080:80 image_name
Apart from telling docker to expose the port, you must configure apache to listen 8080, doing these two editions:
/etc/apache2/ports.conf
/etc/apache2/sites-enabled/000-default.conf
Dockerfile:
FROM php:7.0-apache
RUN sed -si 's/Listen 80/Listen 8080/' /etc/apache2/ports.conf
RUN sed -si 's/VirtualHost .:80/VirtualHost *:8080/' /etc/apache2/sites-enabled/000-default.conf
EXPOSE 8080
Then:
docker run -d -p 8080:8080 image_name
Edit:
About port 80. The port is not opened and it's not exposed if you use the previous command. If you don't see the ->80 symbol in docker ps, the port is not exposed:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
100fbb367226 php7 "docker-php-entryp..." 2 minutes ago Up 46 seconds 80/tcp, 0.0.0.0:8080->8080/tcp musing_snyder
And:
▶ docker inspect 100fbb367226 -f "{{json .NetworkSettings.Ports}}"
{"80/tcp":null,"8080/tcp":[{"HostIp":"0.0.0.0","HostPort":"8080"}]}

Resources