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
Using the configuration SHOW_TOOLBAR_CALLBACK woked for me
I hope that helped :)
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
In total my settings look like this
You could just make
INTERNAL_IPS
an object which contains everything. This is what I do: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_IPSSolved. Checked the value for REMOTE_ADDR in request headers and added that to INTERNAL_IPS.
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:With that set, the following two lines in
settings.py
detected it and allowed the host to see the toolbar: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:
For reference, this is the link to the django-cookiecutter local.py settings file.