'Get NGINX ip address in docker in Django settings.py for Django-debug-toolbar

I have a dockerized DRF project with installed NGINX in it. All works fine except one thing:

Django debug toolbar requires INTERNAL_IPS parameter to be specified in settings.py.

For docker I use this one:

    hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
    INTERNAL_IPS = [ip[:-1] + "1" for ip in ips]

It also works fine but not with NGINX as NGINX use it’s own ip dynamically(probably?) definded inside or assigned by docker or anything else.

I can get this ip from server logs:

172.19.0.8 - - [09/Oct/2020:17:10:40 +0000] "GET /admin/ HTTP/1.0" 200 6166 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.228"

and add it to setting.py:

hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
INTERNAL_IPS = [ip[:-1] + "1" for ip in ips]
INTERNAL_IPS.append('172.18.0.8')

but I expect that this ip might be different on different machines etc, so it is not reliable enough.

So that question is -is it possible somehow to get NGINX docker ip in settings.py dynamically or fix docker-compose somehow???

docker-compose:

version: '3.8'

volumes:
    postgres_data:
    redis_data:
    static_volume:
    media_volume:

services:
  web:
    build: .
    #command: python /code/manage.py runserver 0.0.0.0:8000
    command: gunicorn series.wsgi:application --config ./gunicorn.conf.py
    env_file:
      - ./series/.env
    volumes:
      - .:/code
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
#    ports:
#      - 8000:8000
    expose:
      - 8000
    depends_on:
      - db
      - redis
      - celery
      - celery-beat
    links:
      - db

  nginx:
    build: ./nginx
    volumes:
      - static_volume:/home/app/web/staticfiles
      - media_volume:/home/app/web/mediafiles
    ports:
#      - 1337:80
      - 8000:80
    depends_on:
      - web

  db:
    build:
      context: .
      dockerfile: postgres.dockerfile
    restart: always
    env_file:
      - ./series/.env
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
    volumes:
      - postgres_data:/var/lib/postgresql/data/
    ports:
      - target: 5432
        published: 5433
        protocol: tcp
        mode: host

  redis:
    image: redis:alpine
    command: >
      redis-server
      --appendonly yes
      --appendfsync no
      --auto-aof-rewrite-percentage 100
      --auto-aof-rewrite-min-size 64mb
    ports:
      - target: 6379
        published: 6380
        protocol: tcp
        mode: host
    volumes:
        - redis_data:/data
    restart: always
    environment:
      - REDIS_REPLICATION_MODE=master

  celery:
    build: .
    command: celery worker -A series  --loglevel=INFO --concurrency=4 -E
    restart: always
    environment:
      - C_FORCE_ROOT=1
    volumes:
      - .:/code
    depends_on:
      - db
      - redis
    hostname: celery-main

  celery-beat:
      build: .
      command: celery -A series beat --loglevel=INFO --pidfile=
      restart: always
      volumes:
        - .:/code
      depends_on:
        - db
        - redis
      hostname: celery-beat

  flower:
    # http://localhost:8888/
    image: mher/flower
    environment:
      - CELERY_BROKER_URL=redis://redis:6379/1
      - FLOWER_PORT=8888
    depends_on:
      - celery
      - celery-beat
      - redis
    restart: always
    ports:
      - target: 8888
        published: 8888
        protocol: tcp
        mode: host

dockerfile of NGINX:

FROM nginx:1.19.0-alpine

RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d

Thank you



Solution 1:[1]

Following an approach similar to the latest cookiecutter-django code which adds an internal IP address for gulp, we can add the nginx container's IP address dynamically there as well (no need to hard-code the IP address):

        hostname, _, ips = socket.gethostbyname_ex(socket.gethostname())
        INTERNAL_IPS += [".".join(ip.split(".")[:-1] + ["1"]) for ip in ips]
        # Since our requests will be routed to Django via the nginx container, include
        # the nginx IP address as internal as well
        hostname, _, nginx_ips = socket.gethostbyname_ex("nginx")
        INTERNAL_IPS += nginx_ips

In the above code, we use the hostname nginx to match the name of the docker service you specified in your docker-compose file. (I had the same issue as you, and this worked for me.)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Steven D.