Невозможно запустить отладчик vscode с докеризованным проектом django
Каждый раз, когда я запускаю отладчик, происходит много вещей, но не то, что я ожидаю.
Я запускаю проект с docker-compose up
Проверяю локалхост, все ли в порядке с бэкендом. Не работает. Что забавно, контейнер запущен, потому что я подключен к нему с помощью удаленных контейнеров vscode.
Библиотека debugpy
установлена.
Первый подход к запуску отладчика заканчивается такой информацией в консоли отладки:
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.
и он не работает. Бэкэнд также не работает.
Вторая попытка:
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
и он не работает, но бэкэнд работает - я могу войти в систему и т.д.
Третья попытка заканчивается такой ошибкой connect ECONNREFUSED 127.0.0.1:5678
.
Есть советы?
Код:
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()
Локальный 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
и файл 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
}
]
}
Django не поддерживает отладку самостоятельно
вот что я узнал о серфинге за 2 минуты
Вы не можете отлаживать в django. В следующий раз, когда будете писать, пожалуйста, покажите доказательства предварительного исследования вопроса. Тем не менее, спасибо, что спросили.
Может быть много причин, по которым отладка не работает так, как задумано. Поиск и устранение неисправностей обычно является разумным решением. Начиная с чего-то простого и добавляя сложности, пока не выяснится, какой шаг не работает так, как нужно. Я бы рекомендовал начать с простой сессии отладки с помощью pdb
, прежде чем добавлять сложности VS Code. Чтобы добиться этого, вам просто нужно добавить breakpoint()
в код бэкенда, где вы хотите отлаживать. В вашем docker-compose.yaml
, вы хотите добавить к вашей backend
службе следующие дополнительные конфигурации
services:
backend:
- tty: true
- stdin_open: true
В своем терминале запустите свое приложение с помощью docker-compose up
. Откройте второй терминал и подключитесь к вашему контейнеру с помощью docker attach <project name>_backend
. Обычно вы должны получить подсказку pdb>
в том месте, где была нажата ваша клавиша breakpoint
.
Основываясь на вашем описании, вот пункты, которые я бы исследовал.
установка отладочной машины
Убедитесь, что debugpy установлен в образ Docker, а не локально.
WSGI HTTP-сервер
Предполагаю, что вы используете python manage.py runserver 0.0.0.0:8000
для запуска HTTP-сервера WSGI. На всякий случай, если вы используете что-то вроде gunicorn, стоит упомянуть, что вы должны использовать только 1 рабочий. В качестве примера, если вы используете gunicorn, вы можете указать количество рабочих в командной строке: gunicorn --workers=1 --timeout=1200 --bind 0.0.0.0:8000 your_application.wsgi:application
.
Обратите внимание на огромный таймаут. Возможно, вы захотите установить большое значение как для вашего HTTP-сервера WSGI, так и для Nginx. Если один из них прервется во время отладки, вы получите ошибку 502 или 504 в зависимости от того, какой из них прервался первым, и ваша сессия отладки завершится.
местоположение отладочного устройства
Обычно я помещаю код, импортирующий debugpy
в wsgi.py
, прямо перед вызовом get_wsgi_application()
"""
WSGI config for {{ project_name }} project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/{{ docs_version }}/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '{{ project_name }}.settings')
import debugpy
debugpy.listen(('0.0.0.0', 5678))
debugpy.wait_for_client()
print('Attached!')
application = get_wsgi_application()