django_debug_toolbar and Docker

不羁岁月 提交于 2020-06-10 07:31:33

问题


So I got docker and Django to work locally, first by building an image from a Dockerfile, then using Fig to get postgres image, link it to the base image, and run the localserver. Everything works just fine, except for django_debug_toolbar. For some reason it just won't show up. Have the dockerhost ip as well in the internal_ips. Can anyone help me out with it? Docker is running on mac via boot2docker.

Thanks!

My settings:

init.py

import os

if 'DEBUG' not in os.environ or not os.environ['DEBUG']:
    from .local import *
else:
    pass

base.py

""" common and global settings """

from sys import path
from os import environ
from os.path import abspath, basename, dirname, join, normpath
from django.core.exceptions import ImproperlyConfigured
import dj_database_url


def get_env_variable(var_name):
    try:
        return environ[var_name]
    except KeyError:
        error_msg = "Set the environment variable" % var_name
        raise ImproperlyConfigured(error_msg)

# Paths
DJANGO_ROOT = dirname(dirname(abspath(__file__)))
SITE_ROOT = dirname(DJANGO_ROOT)
SITE_NAME = basename(DJANGO_ROOT)
# End Paths


# URLs
MEDIA_ROOT = normpath(join(SITE_ROOT, 'media'))
MEDIA_URL = "/media/"

STATIC_ROOT = normpath(join(SITE_ROOT, 'assets'))
STATIC_URL = "/static/"

STATICFILES_DIRS = (
    normpath(join(SITE_ROOT, 'static')),
)

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

ROOT_URLCONF = '%s.urls' % SITE_NAME

path.insert(0, join(DJANGO_ROOT, 'apps'))  # add apps folder to system path
# End URLs


# Database
# example:  postgres://joris:luna@localhost/bitbybit
DATABASES = {'default': dj_database_url.config(
   default='postgres://postgres@db:5432/postgres')}
# End Database

# Templates
TEMPLATE_CONTEXT_PROCESSORS = (
    'django.contrib.auth.context_processors.auth',
    'django.core.context_processors.debug',
    'django.core.context_processors.i18n',
    'django.core.context_processors.media',
    'django.core.context_processors.static',
    'django.core.context_processors.tz',
    'django.contrib.messages.context_processors.messages',
    'django.core.context_processors.request',
)

TEMPLATE_LOADERS = (
   'django.template.loaders.filesystem.Loader',
   'django.template.loaders.app_directories.Loader',
)

TEMPLATE_DIRS = (
    normpath(join(SITE_ROOT, 'templates')),
)
# End Templates


# SECURITY WARNING: keep the secret key used in production secret!
# make it unique and store it as an environment variable
SECRET_KEY = r"d%g7_h6cz=xbhs*5-i+e$c7mns*s)^_+#^8n@^-2dno@uie-z9"


# Application
DJANGO_APPS = (
   'django.contrib.admin',
   'django.contrib.auth',
   'django.contrib.contenttypes',
   'django.contrib.sessions',
   'django.contrib.messages',
   'django.contrib.staticfiles',
)

LOCAL_APPS = (
   'home',
)

INSTALLED_APPS = DJANGO_APPS + LOCAL_APPS

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'debug_toolbar.middleware.DebugToolbarMiddleware',
)

WSGI_APPLICATION = '%s.wsgi.application' % SITE_NAME
# End Application


# Internationalization
LANGAUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True
# End Internationalization

Local.py

from .base import *

# Debug config
DEBUG = True
TEMPLATE_DEBUG = DEBUG
# End Debug config

# Hosts
ALLOWED_HOSTS = ['127.0.0.1', 'localhost']
# End Hosts


# Django Debug Toolbar config
INSTALLED_APPS += (
    'debug_toolbar', )

INTERNAL_IPS = ('127.0.0.1', 'localhost')
# End Django Debug Toolbar config

回答1:


Using the configuration SHOW_TOOLBAR_CALLBACK woked for me

def show_toolbar(request):
        return True

DEBUG_TOOLBAR_CONFIG = {
    'SHOW_TOOLBAR_CALLBACK': show_toolbar,
}

I hope that helped :)




回答2:


You could just make INTERNAL_IPS an object which contains everything. This is what I do:

if DEBUG:
    # `debug` is only True in templates if the vistor IP is in INTERNAL_IPS.
    INTERNAL_IPS = type(str('c'), (), {'__contains__': lambda *a: True})()

Of course you should never do this on a production host!

Explanation:

The type function (three arguments variant: https://docs.python.org/3/library/functions.html#type) creates a new class which in this case only has a __contains__ method (https://docs.python.org/3/reference/datamodel.html#object.contains) -- contains is used to implement membership tests, meaning that this method is called when running e.g. "if ip in INTERNAL_IPS". The contains method itself would probably be clearer if written as "def __contains__(self):\n return True". The newly created class is immediately instantiated (the final "()") and assigned to INTERNAL_IPS




回答3:


If you would like to do this programatically and not copy/pasting your container IP, I'd suggest you do like the django-cookiecutter folks. In your local settings file:

INTERNAL_IPS = ['127.0.0.1', ]
import socket

# tricks to have debug toolbar when developing with docker
ip = socket.gethostbyname(socket.gethostname())
INTERNAL_IPS += [ip[:-1] + '1']

For reference, this is the link to the django-cookiecutter local.py settings file.




回答4:


IP address that allowed me to display Django Debug Toolbar was the IP of the gateway associated with my docker container. To obtain IP of the gateway I run this command

docker inspect my_container_name | grep -e '"Gateway"'
# "Gateway": "172.18.0.1",

In total my settings look like this

INSTALLED_APPS = (
    'debug_toolbar',
)
INTERNAL_IPS = ['172.18.0.1']



回答5:


Solved. Checked the value for REMOTE_ADDR in request headers and added that to INTERNAL_IPS.




回答6:


Using the accepted answer at https://unix.stackexchange.com/questions/87468/is-there-an-easy-way-to-programmatically-extract-ip-address I was able to get this to work by passing the address of the host's Docker bridge to the docker run command as an environment variable:

-e "DOCKER_HOST=$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')"

With that set, the following two lines in settings.py detected it and allowed the host to see the toolbar:

if "DOCKER_HOST" in os.environ:
    INTERNAL_IPS = [os.environ["DOCKER_HOST"]]



回答7:


Here's a hacky way that doesn't require injecting the address into the container. I'm not sure how it would work if your container is connected to multiple networks and could break if docker changed the way they assign addresses (though that doesn't seem likely).

import subprocess

route = subprocess.Popen(('ip', 'route'), stdout=subprocess.PIPE)
network = subprocess.check_output(
    ('grep', '-Po', 'src \K[\d.]+\.'), stdin=route.stdout).decode().rstrip()
route.wait()
network_gateway = network + '1'
INTERNAL_IPS = [network_gateway]


来源:https://stackoverflow.com/questions/26898597/django-debug-toolbar-and-docker

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!