Every time when I run a debugger there happen many things but not what I expect.
I’m running a project with docker-compose up
Checking the localhost if backend backend is okay. It’s down.
What’s funny the container is running because I’m attached to this with vscode’s remote containers.
The debugpy
library is installed.
The first approach to run a debugger end with such info in debug console:
Attached!
System check identified some issues:
WARNINGS:
workflow.State.additional_values: (fields.W904) django.contrib.postgres.fields.JSONField is deprecated. Support for it (except in historical migrations) will be removed in Django 4.0.
HINT: Use django.db.models.JSONField instead.
Operations to perform:
Apply all migrations: accounts, auth, contenttypes, files, mambu, otp_totp, sessions, token_blacklist, workflow, zoho
Running migrations:
No migrations to apply.
and it’s down. Backend is also down.
Second try:
Attached!
System check identified some issues:
WARNINGS:
workflow.State.additional_values: (fields.W904) django.contrib.postgres.fields.JSONField is deprecated. Support for it (except in historical migrations) will be removed in Django 4.0.
HINT: Use django.db.models.JSONField instead.
Zoho Configuration failed, check that you have all variables ZOHO_TOKEN_URL, ZOHO_REST_API_KEY, ZOHO_CURRENT_USER_EMAIL
and it’s down but backend is up – I’m able to login etc.
The third try ends with such an error connect ECONNREFUSED 127.0.0.1:5678
.
Any tips?
Code:
manage.py
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def initialize_debugger():
import debugpy
debugpy.listen(("0.0.0.0", 5678))
debugpy.wait_for_client()
print('Attached!')
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
initialize_debugger()
main()
The local docker-compose.yml
version: "3.2"
services:
backend:
container_name: xxx
build:
context: ./backend
dockerfile: ../build/backend.Dockerfile
volumes:
- ./backend:/opt/app
command: ./run.sh
ports:
- "8000:8000"
- "5678:5678"
env_file:
- build/.env-local
links:
- db:db
- rabbit:rabbit
- memcached:memcached
celery:
container_name: xxx
restart: always
build:
dockerfile: ../build/backend.Dockerfile
context: ./backend
command: ./run_celery.sh
env_file:
- build/.env-local
working_dir: /opt/app/
volumes:
- ./backend/:/opt/app
links:
- db:db
- rabbit:rabbit
frontend:
container_name: xxx
build:
context: frontend
dockerfile: ../build/frontend.Dockerfile
environment:
- BROWSER=none
- CI=true
volumes:
- ./frontend/src/:/frontend/src
- ./frontend/public/:/frontend/public
nginx:
container_name: xxx
build:
dockerfile: build/nginx.Dockerfile
context: .
args:
REACT_APP_GOOGLE_ANALYTICS_TOKEN: $REACT_APP_GOOGLE_ANALYTICS_TOKEN
REACT_APP_PAGESENSE_LINK: $REACT_APP_PAGESENSE_LINK
REACT_APP_CHATBOT_TOKEN: $REACT_APP_CHATBOT_TOKEN
REACT_APP_SENTRY_DSN: $REACT_APP_SENTRY_DSN
REACT_APP_SENTRY_ENVIRONMENT: $REACT_APP_SENTRY_ENVIRONMENT
REACT_APP_SENTRY_TRACES_SAMPLE_RATE: $REACT_APP_SENTRY_TRACES_SAMPLE_RATE
REACT_APP_THIRD_PARTY_API_URL: $REACT_APP_THIRD_PARTY_API_URL
ports:
- "5000:80"
depends_on:
- backend
- frontend
env_file:
- build/.env-local
volumes:
- ./build/nginx/nginx.conf:/etc/nginx.conf
db:
container_name: xxx
image: postgres:12
ports:
- "5432:5432"
restart: on-failure
environment:
POSTGRES_DB: postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
rabbit:
container_name: xxx
image: rabbitmq
ports:
- "5672:5672"
memcached:
container_name: xxx
image: memcached
ports:
- "11211:11211"
restart: always
flower:
image: mher/flower:0.9.5
environment:
- CELERY_BROKER_URL=amqp://xxx-rabbitmq//
- FLOWER_PORT=8888
ports:
- 8888:8888
and the launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "CF: Remote Attach",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}/backend",
"remoteRoot": "/opt/app/"
}
],
"django": true
}
]
}
2
Answers
Django don’t support debugging by its own
this is what I fount of surfing in 2 min
this might help you
There could be many reasons why debugging does not work as intended. Troubleshooting is usually the reasonable thing to do. Starting from something simple and adding complexity until figuring out what step is not working as intended. I would recommend starting with a simple debugging session using
pdb
, before adding VS Code complexity. In order to accomplish that, you just need to add abreakpoint()
in your backend code where you want to debug. In yourdocker-compose.yaml
, you want to add to yourbackend
service, the following additional configurationsIn your terminal, start your application with
docker-compose up
. Open a second terminal and attach to your container withdocker attach <project name>_backend
. You should normally get a promptpdb>
at the location where yourbreakpoint
was hit.Based on your description, here are the points I would investigate.
debugpy installation
Make sure debugpy is installed in the Docker image and not locally.
WSGI HTTP server
I presume you’re using
python manage.py runserver 0.0.0.0:8000
to start the WSGI HTTP server. Just in case you’re using something like gunicorn, it’s worth mentioning that you should only use 1 worker. As an example, if using gunicorn, you can provide the amount of workers at the command line:gunicorn --workers=1 --timeout=1200 --bind 0.0.0.0:8000 your_application.wsgi:application
.Note also the huge timeout. You might want to set a high value both for your WSGI HTTP server and for Nginx. If one of them times out while you’re debugging, you will get a 502 or 504 error depending on which one timed out first and your debugging session will terminate.
debugpy location
I usually place the code importing
debugpy
inwsgi.py
, right before the call toget_wsgi_application()