I’m trying to figure out best practices for Docker Compose, which I’m pretty new to.
Scenario:
- I have one container with a Flask app, served through gunicorn (which binds on port 8080).
- I have an nginx container that acts as a reverse proxy for TLS termination, request routing to other containers, etc. It needs to be able to forward requests to gunicorn/Flask in the first container.
I’m using Docker Compose to do a quick deployment of these containers. Since the gunicorn/Flask container should only accept traffic from nginx, and not any direct requests, I’d like to configure it such that the gunicorn/Flask port (8080 in the container) is only exposed to the nginx container, and not to anything else on the host.
Is this possible?
2
Answers
Yes, this is one of the main use cases for using docker-compose. You basically only need to expose the port of nginx in your
docker-compose.yaml
and let the flask app not expose any ports to the outside world of the container.From the docker-compose docs: By default Compose sets up a single network for your app. Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by them at a hostname identical to the container name.
For example, imagine your flask app service inside your
docker-compose.yml
is calledmy-flask-app
where the app inside the container is running on port 8080. Then you can access the endpoint from the withinnginx
container by the servicename such as http://my-flask-app:8080. You can try this by usingcurl
from inside the flask container.Just don’t publish
ports:
for the thing you don’t want accessible from outside Docker space.Your Nginx configuration can still
proxy_pass http://backend:8080
, but the Flask application won’t be directly reachable from outside of Docker.ports:
specifically allows a connection from outside Docker into the container. It’s not a required option. Connections between containers don’t requireports:
, and ifports:
remap one of the application ports, that remapping is ignored.Technically this setup only allows connections from within the same Docker network, so if you had other services in this setup they could also reach the Flask container. On a native-Linux host there are tricks to directly contact the container, but they don’t work on other host OSes or from another system. IME usually these limitations are acceptable.