django-debug-toolbar icon indicating copy to clipboard operation
django-debug-toolbar copied to clipboard

Debug toolbar doesn't show if using a docker webserver container

Open Eraldo opened this issue 1 year ago • 3 comments

I tried the solution approach to auto detect the correct IP and add it to the INTERNAL_IPS:

INTERNAL_IPS = ["127.0.0.1", "10.0.2.2"]
if env("USE_DOCKER") == "yes":
    import socket

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

This correctly detects my "django" container ip (172.18.0.5) and adds it to the INTERNAL_IPS.

However I am using a caddy webserver (172.18.0.6) and so the debug toolbar does not show in the end. If I manually add 172.18.0.6 to the INTERNAL_IPS, it works as expected. (just to confirm)

Any ideas? 😅

Eraldo avatar Oct 25 '24 08:10 Eraldo

I had the same issue. Running django runserver on the host but the rest of the supporting services in a docker compose stack in development.

According to AI this is the solution: import subprocess

   def get_nginx_docker_ip():
       try:
           # Run the `docker inspect` command to get the Nginx IP
           output = subprocess.check_output(
               [
           ``        "docker",
                   "inspect",
                   "-f",
                   "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}",
                   "your_nginx_container_name",  # Replace with your container name
               ],
               stderr=subprocess.DEVNULL
           )
           # Decode byte response to string
           return output.decode("utf-8").strip()
       except subprocess.CalledProcessError:
           # Log this or handle if the container is not running
           print("Error: Could not determine Nginx IP")
           return None

   # Get the Nginx internal Docker IP and add to INTERNAL_IPS
   nginx_ip = get_nginx_docker_ip()

   INTERNAL_IPS = ["127.0.0.1"]  # Include localhost
   if nginx_ip:
       INTERNAL_IPS.append(nginx_ip)

I tried it and it works!

With DEBUG on, it runs it and my setting looks like this:

INTERNAL_IPS: ['127.0.0.1', '127.0.1.1', '172.18.0.3']

Where the last one is the IP of my nginx container.

pjrulez avatar Apr 13 '25 04:04 pjrulez

@pjrulez thanks! I'm surprised this is even necessary when running runserver on the host because the browser will probably always connect from 127.0.0.1 then, and not from the docker gateway IP unless you're using your computer's external IP?

matthiask avatar Apr 13 '25 08:04 matthiask

@Eraldo What's happening is DJDT is looking at the gateway IP for the docker network your containers are running on, and you want it to accept any IP in that subnet, right?

I'm hitting a similar issue, but since docker compose sets up a different docker network (and new subnet) for each compose, just using the IP for host.docker.internal doesn't work. I had to resort to using a modified version of debug_toolbar.middleware.show_toolbar_with_docker() that treats any request coming from the same /24 network as either host.docker.internal or the container ip as a local address.

Basically, I replace the # Test: Docker stanza with this:

    # Test: Docker
    for address in (socket.gethostbyname("host.docker.internal"),
                    socket.gethostbyname(socket.gethostname())):
        try:
            # This is a hack for docker installations. It attempts to look
            # up the IP address of the docker host.
            # This is not guaranteed to work.
            docker_net = address.rsplit(".")[:-1]
            remote_addr_net = request.META.get("REMOTE_ADDR", "").rsplit(".")[:-1]
            if remote_addr_net == docker_net:
                return True
        except socket.gaierror:
            # It's fine if the lookup errored since they may not be using docker
            pass

This is arguably slightly hackier than the existing heuristic (the networks that compose sets up are actually /16s on my laptop, not /24s). But for me, having something that Just Works is worth it.

rascalking avatar Sep 17 '25 17:09 rascalking