Search code examples
dockernetwork-programmingdocker-composedocker-network

Isolating certain Docker containers from one another


I have a couple of containers sitting behind an nginx reverse proxy and while nginx should and can talk to all of the containers, they shouldn't be able to talk to one another. The primary reason for wanting this is that the containers are independent of one another and in the event that one of them gets compromised, at least it won't allow access to the other ones.

Using my limited understanding of networking (even more so with Docker), I naively assumed that creating a separate network for each container and assigning all networks to the nginx container would do the job, though that doesn't seem to work. Here's what my docker-compose.yml looks like based on that attempt:

services:
  nginx:
    networks:
      - net1
      - net2
      - net3

  container1:
    networks:
      - net1

  container2:
    networks:
      - net2

  container3:
    networks:
      - net3

networks:
  net1:
    name: net1
  net2:
    name: net2
  net3:
    name: net3

Is what I'm trying to do possible? Is it even worth going through the effort of doing it for the sake of security?


Solution

  • You idea really works, see next example:

    docker-compose.yaml:

    version: "3.7"
    
    services:
      nginx:
        image: debian:10
        tty: true
        stdin_open: true
        networks:
          - net1
          - net2
      container1:
        image: debian:10
        tty: true
        stdin_open: true
        networks:
          - net1
      container2:
        image: debian:10
        tty: true
        stdin_open: true
        networks:
          - net2
    
    networks:
      net1:
        name: net1
      net2:
        name: net2
    

    verify:

    root@pie:~/20221014# docker-compose exec nginx ping -c 1 container1
    PING container1 (172.19.0.2) 56(84) bytes of data.
    64 bytes from 20221014_container1_1.net1 (172.19.0.2): icmp_seq=1 ttl=64 time=0.083 ms
    
    --- container1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.083/0.083/0.083/0.000 ms
    root@pie:~/20221014# docker-compose exec nginx ping -c 1 container2
    PING container2 (172.20.0.2) 56(84) bytes of data.
    64 bytes from 20221014_container2_1.net2 (172.20.0.2): icmp_seq=1 ttl=64 time=0.062 ms
    
    --- container2 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.062/0.062/0.062/0.000 ms
    root@pie:~/20221014# docker-compose exec container1 ping -c 1 container2
    ping: container2: Temporary failure in name resolution
    root@pie:~/20221014# docker-compose exec container2 ping -c 1 container1
    ping: container1: Temporary failure in name resolution
    

    And, networking in compose demo an example which same scenario as you:

    The proxy service is isolated from the db service, because they do not share a network in common - only app can talk to both.

    
    services:   
      proxy:
        build: ./proxy
        networks:
          - frontend   
      app:
        build: ./app
        networks:
          - frontend
          - backend   
      db:
        image: postgres
        networks:
          - backend
    
    networks:   
      frontend:
        # Use a custom driver
        driver: custom-driver-1   
      backend:
        # Use a custom driver which takes special options
        driver: custom-driver-2
        driver_opts:
          foo: "1"
          bar: "2" ```