Add docker compose support#2295
Conversation
for more information, see https://pre-commit.ci
|
I don't really know docker compose all that well. Would it be possible to expand the docs a bit? Is there no way to somewhat reliably auto detect the value when using compose? |
|
@matthiask I think it's a case of someone using a different host than the convention when running a docker container. The callout on compose is only part of the story from what I understand. Compose allows you to define configuration to customize it, but it's not just a compose feature. I think I'd rather have this documented and ask the dev to implement the function themselves rather than us add a setting. Perhaps we can rework the checks so that we can reuse more of the toolbar's functions? For example def show_toolbar_with_docker(request: HttpRequest) -> bool:
"""
Default function to determine whether to show the toolbar on a given page.
"""
if not show_toolbar(request):
return False
# Test: Docker
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_ip = (
# Convert the last segment of the IP address to be .1
".".join(socket.gethostbyname("host.docker.internal").rsplit(".")[:-1])
+ ".1"
)
if request.META.get("REMOTE_ADDR") == docker_ip:
return True
except socket.gaierror:
# It's fine if the lookup errored since they may not be using docker
pass
# No test passed
return False |
|
No problem, I'll explain you with more detail. Docker compose is a tool to help orchestrate more than one container, it's not something complex like kubernetes and for a long time the docker don't advise to use in production (I don't know if it's the case now). For example in this project that I'm working, besides the Dockerfile I have the compose.yml file services:
web:
build:
context: .
args:
REQUIREMENTS: local.txt
command: python manage.py runserver 0:8000
volumes:
- .:/project
ports:
- ${WEB_PORT:-8000}:8000
depends_on:
- postgres
postgres:
image: postgis/postgis:16-3.5
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
ports:
- ${POSTGRES_PORT:-5432}:5432
volumes:
- pgdata:/var/lib/postgresql/data
selenium:
image: selenium/standalone-firefox:latest
ports:
- "4444:4444"
- "7900:7900" # VNC port for viewing the browser (optional but useful). Password is secret
shm_size: 2gb
volumes:
pgdata:Here I have a container web for django (but I can call anything i want) and I also have the other dependencies, postgres and seleninum,. In the settings I have this DATABASES = {
"default": {
"ENGINE": "django.contrib.gis.db.backends.postgis",
"NAME": "postgres",
"USER": "postgres",
"PASSWORD": "postgres",
"HOST": "postgres",
}
}here the host is the name of the container name. from selenium import webdriver
def get_default_firefox_options():
options = webdriver.FirefoxOptions()
return options
class NewVisitor(unittest.TestCase):
def setUp(self) -> None:
# Connect to the remote Selenium server
self.browser = webdriver.Remote(
command_executor="http://selenium:4444/wd/hub",
options=get_default_firefox_options(),
)
def tearDown(self) -> None:
self.browser.quit()
def test_can_see_homepage(self):
# Access the web service using Docker's internal network
self.browser.get("http://web:8000")This creates the alias for the network. About your question "Is there no way to somewhat reliably auto detect the value when using compose?" I don't know because I can have a celery that runs a python process and I don't know how to catch the name for what you suggested. To my head it only comes a way of reading the compose file, finding the runserver but it's tricky because it doesn't need to run by that and I think it will be easy to have a lot of bugs. In this project to make the package work I did this in my settings DEBUG_TOOLBAR_CONFIG = {
"SHOW_TOOLBAR_CALLBACK": "utils.django_debug_toolbar.show_toolbar_with_docker_compose",
}And that file I have def show_toolbar_with_docker_compose(request):
"""
Default function to determine whether to show the toolbar on a given page.
"""
if not settings.DEBUG:
return False
# Test: settings
if request.META.get("REMOTE_ADDR") in settings.INTERNAL_IPS:
return True
# Test: Docker
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_ip = (
# Convert the last segment of the IP address to be .1
".".join(
socket.gethostbyname(
"web"
).rsplit(".")[:-1]
)
+ ".1"
)
if request.META.get("REMOTE_ADDR") == docker_ip:
return True
except socket.gaierror:
# It's fine if the lookup errored since they may not be using docker
pass
# No test passed
return FalseIt was a bit tricky to make this work and I think it be a good addiction to the package. With this what are your thoughts to make this easier for other person add the package with docker compose? |
|
Thanks for the information @helioascorreia. Can you please clarify what case(s) that the toolbar was not showing up? You mentioned functional tests too. Those probably shouldn't be using the toolbar. Not sure if you mentioned them for completeness or there's a misunderstanding there. |
|
Thanks, both of you! I know what docker compose does, it's just that I don't use podman/docker in development, only in production environments.
Since this is about development it would be easier to replace the toolbar callback with something which just returns DEBUG_TOOLBAR_CONFIG = {
"SHOW_TOOLBAR_CALLBACK": lambda request: True,
}This is obviously unsafe for when the development server is exposed to anyone, even to internal networks. The usual caveats also apply! https://django-debug-toolbar.readthedocs.io/en/latest/configuration.html#show-toolbar-callback (In development I still use the old hack which makes I had some doubts when we introduced the So, despite the additional setting im -0 to +0 on this change. I don't think it will hurt, the easier and more obvious solution would have been a custom |
|
Oh the functional test I only mention for completeness. So when I try to add the debug toolbar to this project I followed the docs https://django-debug-toolbar.readthedocs.io/en/latest/installation.html#process. I read the part talking about docker and I added the debug_toolbar.middleware.show_toolbar_with_docker and it doesn't show the debug toolbar in the pages. I tried to find something about it on the troubleshooting section but I didn't see anything about it. def show_toolbar_with_docker(request: HttpRequest) -> bool:
"""
Default function to determine whether to show the toolbar on a given page.
"""
if not settings.DEBUG:
return False
# Test: settings
if request.META.get("REMOTE_ADDR") in settings.INTERNAL_IPS:
return True
# Test: Docker
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_ip = (
# Convert the last segment of the IP address to be .1
".".join(socket.gethostbyname("host.docker.internal").rsplit(".")[:-1])
+ ".1"
)
if request.META.get("REMOTE_ADDR") == docker_ip:
return True
except socket.gaierror:
# It's fine if the lookup errored since they may not be using docker
pass
# No test passed
return Falseto instead have |
|
I don't think passing service name in is a solution here. I also didn't manage to get built in detection to work, but this does the job just fine: DEBUG_TOOLBAR_CONFIG = {"SHOW_TOOLBAR_CALLBACK": lambda request: DEBUG} |
I think that points to the underlying problem where people try to do too much in the
Exactly. The thing is that we don't recommend using |
Description
This feature is to add support to use this package with the docker compose
Fixes # (issue)
Checklist:
docs/changes.rst.AI/LLM Usage