繁体   English   中英

django_debug_toolbar 和 Docker

[英]django_debug_toolbar and Docker

所以我让 docker 和 Django 在本地工作,首先通过从 Dockerfile 构建图像,然后使用 Fig 获取 postgres 图像,将其链接到基础图像,并运行 localserver。 一切正常,除了 django_debug_toolbar。 出于某种原因,它只是不会出现。 在 internal_ips 中也有 dockerhost ip。 任何人都可以帮我解决这个问题吗? Docker 通过 boot2docker 在 mac 上运行。

谢谢!

我的设置:

初始化.py

import os

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

基础文件

""" 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

本地文件

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

使用配置 SHOW_TOOLBAR_​​CALLBACK 为我唤醒

def show_toolbar(request):
        return True

DEBUG_TOOLBAR_CONFIG = {
    'SHOW_TOOLBAR_CALLBACK': show_toolbar,
}

我希望有帮助:)

如果您想以编程方式执行此操作而不是复制/粘贴您的容器 IP,我建议您像django-cookiecutter 人员一样。 在您的本地设置文件中:

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']

作为参考,这是django-cookiecutter local.py设置文件的链接。

你可以让INTERNAL_IPS成为一个包含一切的对象。 这就是我所做的:

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})()

当然,您永远不应该在生产主机上执行此操作!

解释:

类型功能(三个参数的变体: https://docs.python.org/3/library/functions.html#type )创建一个新的类,在这种情况下,只有具有__contains__方法( HTTPS://docs.python。 org/3/reference/datamodel.html#object. contains ) -- contains 用于实现成员资格测试,这意味着在运行时调用此方法,例如“ if ip in INTERNAL_IPS ”。 如果写成“ def __contains__(self):\\n return True ”, contains 方法本身可能会更清晰。 新创建的类立即实例化(最后的“()”)并分配给 INTERNAL_IPS

允许我显示Django 调试工具栏IP 地址是我的 docker 容器(运行 Django 应用程序的容器)的网关 IP

要获取网关的 IP 地址,请运行此命令。

# replace django_container_name with your container name!
docker inspect django_container_name | grep -e '"Gateway"'
# "Gateway": "172.18.0.1",

接下来,将此Getway IP添加到settings.py您的配置可能如下所示。

INSTALLED_APPS = (
    ...
    'debug_toolbar',
    ...
)

MIDDLEWARE = [
    ...
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    ...
]

INTERNAL_IPS = ['172.18.0.1']

当然,将__debug__添加到urls.py

import debug_toolbar
from django.conf import settings
from django.urls import include, path

urlpatterns = [
    ...
    path('__debug__/', include(debug_toolbar.urls)),
]

只需按照djdt 安装指南进行操作!

使用https://unix.stackexchange.com/questions/87468/is-there-an-easy-way-to-programmatically-extract-ip-address 上接受的答案,我能够通过传递地址来使其工作将主机的 Docker 桥接至docker run命令作为环境变量:

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

使用该设置, settings.py的以下两行检测到它并允许主机看到工具栏:

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

解决了。 检查请求标头中 REMOTE_ADDR 的值并将其添加到 INTERNAL_IPS。

正如人们所提到的,您可以使用回调来确定是否应出现调试工具栏。 我将它与通过docker-compose传入的环境变量一起使用。

设置.py

def show_toolbar_callback(*args, **kwargs):
    if os.getenv("LOCAL_DEV"):
        return True
    return False


DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": show_toolbar_callback}

docker-compose.yaml

services: 
  django:
    container_name: "django"
    build: "./"
    ports: 
      - "8000:8000"
    volumes:
      - ".:/opt/service"
    environment: 
      LOCAL_DEV: "true"
    depends_on: 
      - "db"

这是一种不需要将地址注入容器的hacky方法。 我不确定如果你的容器连接到多个网络它会如何工作,并且如果 docker 改变它们分配地址的方式可能会中断(尽管这似乎不太可能)。

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]
DEBUG_TOOLBAR_CONFIG = {
    "SHOW_TOOLBAR_CALLBACK": lambda request: not request.is_ajax()
}

1- 在目录 docker-compose 或 Dockerfile 中运行此命令并获取网络 ID:

sudo docker network list

并查看列表所有网络

NETWORK ID     NAME                DRIVER    SCOPE
556e2e7123er   admin_default       bridge    local
aq3033sc09c1   bridge              bridge    local
1983cf1x2cb9   cockroach           bridge    local
0cc1be23b543   flask               bridge    local

2-运行此命令:

ip addr

.
.

8: br-556e2e7123er: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether **:**:**:**:**:** brd ff:ff:ff:ff:ff:ff
    inet 162.21.0.1/16 brd 172.22.255.255 scope global br-556e2e7123er
       valid_lft forever preferred_lft forever

.
.

3-获取您的IP

NETWORK ID : 556e2e7123er == 8: br-556e2e7123er => ip 162.21.0.1

4- 将 ip 添加到 INTERNAL_IPS = [..., 162.21.0.1, ...] ‍‍‍‍‍‍‍‍‍

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM