Reputation: 79
In Docker we all know how to expose ports, EXPOSE instruction publishes and -p or -P option to expose during runtime. When we use "docker inspect" or "docker port" to see the port mappings and these configs output are pulled /var/lib/docker/containers/container-id/config.v2.json.
The question I got is when we expose port how does Docker actually changes the port in container, say the Apache or Nginx, say we can have the installation anywhere in the OS or file path, how does Docker finds the correct conf file(Apache /etc/httpd/conf/httpd.conf) to change if I suppose Docker does this on the line "Listen 80" or Listen "443" in the httpd.conf file. Or my whole understanding of Docker is in stake:)
Any help is appreciated.
Upvotes: 0
Views: 8477
Reputation: 17372
"docker" does not change anything in the internal configuation of the container (or the services it provides).
There are three different points where you can configure ports
the service itself (for instance nginx) inside the image/container
EXPOSE xxxx
in the Dockerfile
(ie at build time of the image)
docker run -p 80:80
(or the respective equivalent for docker compose
) (ie at the runtime of the container)
All three are (in principle) independent of each other. Ie, you can have completely different values in each of them. But in practice, you will have to adjust them to each other to get a working system.
We know, EXPOSE xxxx
in the dockerfile doesn't actually publish any port at runtime, but just tells the docker service, that that specific container is running some service that supposed to be listening to port xxxx
at runtime. You can see this as sort of documentation for that image. And those EXPOSE
d ports will be used when running an image via docker run -P someimage
. So it's your responsibility as creator of the Dockerfile
to provide the correct values here. Because anyone using that image, will probaby rely on that value.
But regardless, of what port you have EXPOSE
d (or not, EXPOSE
is completely optional) you still have to publish/bind that port when you run the container For instance when using docker run
via -p aaaa:xxxx
or when using docker compse
via a ports: ...
definition in your dockercompose.yml
file. Or you could use docker run -P
which will pickup the EXPOSE
d ports and create an automated binding for them. But be aware that -P
uses random ports on the host machine.
Now let us assume you have an nginx image which has the nginx service configured to listen to port 8000. Regardless of what you define with EXPOSE
or -p aaaa:xxxx
, that nginx service will always listen to port 8000 only and nothing else.
So if you now run your container with docker run -p 80:80
, the runtime will bind port 80 of the host to port 80 of the container. But as there is no service listening on port 80 within the container, you simply won't be able to contact your nginx service on port 80. And you also won't be able to connect to nginx on port 8000, because it hasn't been published.
So in a typical setup, if your service in the container is configured to listen to port 8000, you should also EXPOSE 8000
in your dockerfile and use docker run -p aaaa:8000
to bind port aaaa
of your host machine to port 8000 of your container, so that you will be able to connect to the nginx service via http://hostmachine:aaaa
Upvotes: 2