Home > Blockchain >  Docker Compose: exposing ports only to other containers
Docker Compose: exposing ports only to other containers

Time:08-20

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?

CodePudding user response:

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 called my-flask-app where the app inside the container is running on port 8080. Then you can access the endpoint from the within nginx container by the servicename such as http://my-flask-app:8080. You can try this by using curl from inside the flask container.

CodePudding user response:

Just don't publish ports: for the thing you don't want accessible from outside Docker space.

version: '3.8'
services:
  backend:
    build: .
    # no ports:
  proxy:
    image: nginx
    volumes: ['./nginx.conf:/etc/nginx/nginx.conf']
    ports:
      - '80:80'

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 require ports:, and if ports: 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.

  • Related