docker-gen icon indicating copy to clipboard operation
docker-gen copied to clipboard

Bad IP when container have multiple network in docker-compose

Open Nasjoe opened this issue 7 years ago • 4 comments

Hi. I use docker-compose to up all my services. I have created many network for different services : nginx-proxy, postgresql, frontend etc...

i create a new network with "docker network create -d bridge nginx-proxy"

My docker-compose nginx-proxy look like :

version: '2'
networks:
  proxy-tier:
    external:
      name: nginx-proxy

services:
  nginx:
    image: nginx
    container_name: nginx
    volumes:
         [certs, conf etc......]
    ports:
      - 80:80
      - 443:443
    networks:
      - proxy-tier

  docker-gen:
    image: jwilder/docker-gen
    depends_on:
      - nginx
    container_name: docker-gen
    volumes_from:
      - nginx
    volumes:
      - "[...]nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro"
      - "/var/run/docker.sock:/tmp/docker.sock:ro"
    command: -notify-sighup nginx -watch -only-exposed -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf

  letsencrypt-gen:
      [some good conf, it's work like a charm]


All works very well when i launch an app with the same networks as nginx-conf like that :

version: '2'
networks:
  proxy-tier:
    external:
      name: nginx-proxy

services:
  django:
    build: .
    ports:
      - "8066:80"
    networks:
      - proxy-tier
    command: python manage.py runserver 0.0.0.0:80
    environment:
      VIRTUAL_HOST: "myhost.mydns.com"
      VIRTUAL_PORT: "8066"
      LETSENCRYPT_HOST: "myhost.mydns.com"
      LETSENCRYPT_EMAIL: "[email protected]"

The django service are on the same network as the nginx-proxy, and the docker-gen build a good upstream with the ip of the django container (172.21.0.5:8066)

The problem appear when i start a container with two or more network, like a postgresql :

networks:
  proxy-tier:
    external:
      name: nginx-proxy
  postgres-tier:
    external:
      name: postgresql-network

services:
  django:
    build: .
    ports:
      - "8066:80"
    networks:
      - proxy-tier
      - postgres-tier
    command: python manage.py runserver 0.0.0.0:80
    environment:
      VIRTUAL_HOST: "myhost.mydns.com"
      VIRTUAL_PORT: "8066"
      LETSENCRYPT_HOST: "myhost.mydns.com"
      LETSENCRYPT_EMAIL: "[email protected]"

  postgresql:
      image: postgresql
      expose:
          - 5432
      networks:
          - postgres-tier

I don't want the postgresql and nginx on the same network. And all work well like that. Django and Postgres can talk together, and nginx can talk to Django only.

So Django are now on two networks : proxy-tier (172.21.0.x) and postgres-tier ( 172.24.0.x ).

My problem is this :

Docker-gen look at the ip of the django and randomly fills the nginx config file with the proxy-tier ip (172.21.0.4) or the postgres-tier (172.24.0.12). He did not choose the ip in common with nginx all the time. So, i have sometime (when i launch new services) a nginx conf file with upstream ip that nginx can not talk.

Did you know how can i fix this ? Actually, i add nginx in all network, but it seem a little hacky, and not very secure. Not fully automated too, cause i can't create new network without relaunch all my nginx-proxy docker-compose for add the new network.

Thank you.

Nasjoe avatar Nov 09 '16 11:11 Nasjoe

Hello,

I'm having the same issue and tried several of the methods proposed in the other issues, without any success.

Thank you anyway for this tool, it's very nice !

kermorgant avatar Nov 16 '16 20:11 kermorgant

Same here

purplefish32 avatar Dec 09 '16 14:12 purplefish32

This should do the trick:

upstream {{ $virtual_host }} {
{{- range $container := $containers }}
  {{- $network := index (where $container.Networks "Name" "XXXXXXXXXX") 0 }}
  {{- $address := index (where $container.Addresses "Port" $container.Env.VIRTUAL_PORT) 0 }}
  # {{ $container.Name }}
  server {{ $network.IP }}:{{ $address.Port }};
{{- end }}
}

You need to change the XXXXXXXXXX to the name of your shared network then it will select the IP of this one.

Angel0fDarkness avatar Jan 07 '17 14:01 Angel0fDarkness

For anyone else who runs into this issue with docker-compose, here was my hack of a solution.. motivated by @Angel0fDarkness's idea and somewhat merged into the Master Template.

  1. Pass in an env variable to docker-gen with the name of the network.
    To do so, requires var of COMPOSE_PROJECT_NAME to be explicitly defined/passed into docker-compose, otherwise yml will default to the name of your project you define.... then appends the underscore plus your network name: https://gist.github.com/jonovate/fe1c65b1bfe8c73ab3627ec755daefb3#file-docker-compose-yml-L27-L28

  2. Wrap existing template in check if our env variable exists .. wish it could be cleaned up better (I'm new-new at golang html templates), suggestions? https://gist.github.com/jonovate/fe1c65b1bfe8c73ab3627ec755daefb3#file-nginx-upstream-tmpl-L4-L73

jonovate avatar Jun 02 '17 03:06 jonovate

This repo should no longer handle issues or discussions related to nginx-proxy / the nginx-proxy template, unless there is something we need to change / fix in docker-gen in order to allow a change / fix in nginx-proxy.

buchdag avatar May 16 '24 12:05 buchdag