This project supports remote debugging of Django running inside Docker containers using the Debug Adapter Protocol (DAP). This works with VS Code, LazyVim/Neovim, and any other DAP-compatible editor.
- Quick Start
- PyCharm Setup
- VS Code Setup
- LazyVim/Neovim Setup
- How It Works
- Port Configuration
- Debugging Best Practices
- Other DAP-Compatible Editors
- Additional Resources
just start_with_debugpyThis starts all services with the debugger enabled. Wait for the message:
Debugger listening on 0.0.0.0:5678
Note
Important: Auto-reload is disabled when debugging. You must manually restart the server after code changes.
The debugger will be listening on localhost:5678.
PyCharm Professional supports debugging Django applications running in Docker Compose directly.
- Open Settings/Preferences → Project → Python Interpreter
- Click the gear icon → Add Interpreter → On Docker Compose
- Configure:
- Server: Docker (should auto-detect)
- Configuration files:
./compose.yml - Service:
web - Python interpreter path:
/opt/venv/bin/python
- Click OK and wait for PyCharm to build the interpreter
- Go to Run → Edit Configurations
- Click + → Django Server
- Configure:
- Name: Django Server (Debug)
- Host: 0.0.0.0
- Port: 8000
- Python interpreter: Select the Docker Compose interpreter from step 1
- Environment variables: Add any needed variables from your
.envfile - Working directory:
/srv/app
- Click OK
- Ensure containers are stopped:
just stop - Set breakpoints in your Python code by clicking in the gutter
- Click the Debug button (bug icon) or press Shift+F9
- PyCharm will start the Docker Compose services and attach the debugger
- Make requests to http://localhost:8000 to hit your breakpoints
- Click the Stop button or press Cmd/Ctrl+F2
- PyCharm will stop the Django server
- Run
just stopto clean up any remaining containers
- PyCharm's debugger includes hot-reload by default
- You can use all standard PyCharm debugging features (watches, evaluate expression, etc.)
- This approach is simpler than using debugpy since PyCharm manages everything
- Requires PyCharm Professional (not available in Community Edition)
The project includes pre-configured launch configurations in .vscode/launch.json.
-
Start Django with debugging:
- Run:
just start_with_debugpy - Wait for "Debugger listening on 0.0.0.0:5678" in the terminal output
- Run:
-
Attach the debugger:
- Press F5 or select "Django: Attach Debugger" from the debug dropdown
- Set breakpoints in your Python code
- Make requests to your Django app (http://localhost:8000)
-
Switch to normal mode:
- Stop containers:
just stop - Start in normal mode:
just start(with auto-reload)
- Stop containers:
VS Code Tasks (Alternative):
If you prefer using VS Code tasks:
- Command Palette → "Tasks: Run Task" → "Django: Runserver with Debugging"
- Then press F5 to attach
| Command | Purpose |
|---|---|
just start_with_debugpy |
Start Django with debugger (no auto-reload) |
just start |
Start Django in normal mode (with auto-reload) |
just stop |
Stop all containers |
VS Code Tasks (optional alternative):
- "Django: Runserver with Debugging"
- "Django: Runserver"
- "Django: Stop All Containers"
"Django: Attach Debugger"
- Attaches to debugpy running on port 5678
- Use after starting "Django: Runserver with Debugging" task
- Press F5 to attach
- "Cannot connect to runtime process": Make sure containers are running with debugger enabled
- Breakpoints not hitting: Ensure the code path is being executed and breakpoints are in valid locations
- "Source not found": Check that path mappings in launch.json are correct
- Containers not stopping: Use "Django: Stop All Containers" task from Command Palette
LazyVim and Neovim use nvim-dap for debugging. Here's a sample configuration:
Using lazy.nvim:
{
"mfussenegger/nvim-dap",
dependencies = {
"mfussenegger/nvim-dap-python",
"rcarriga/nvim-dap-ui",
},
config = function()
local dap = require("dap")
local dap_python = require("dap-python")
-- Configure Python adapter for remote debugging
dap.adapters.python = {
type = 'server',
host = 'localhost',
port = 5678,
}
-- Configure Django debugging
dap.configurations.python = {
{
type = 'python',
request = 'attach',
name = 'Django: Attach to Docker',
host = 'localhost',
port = 5678,
pathMappings = {
{
localRoot = vim.fn.getcwd(),
remoteRoot = '/srv/app',
},
},
},
}
end,
}- Start with debugging:
just start_with_debugpy - Wait for "Debugger listening on 0.0.0.0:5678"
- Open your file in Neovim
- Set breakpoints:
:lua require('dap').toggle_breakpoint() - Start debugging:
:lua require('dap').continue() - Use standard nvim-dap commands to step through code
Note: Auto-reload is disabled when debugging. Restart manually after code changes.
Add these to your Neovim config:
vim.keymap.set('n', '<F5>', function() require('dap').continue() end)
vim.keymap.set('n', '<F10>', function() require('dap').step_over() end)
vim.keymap.set('n', '<F11>', function() require('dap').step_into() end)
vim.keymap.set('n', '<F12>', function() require('dap').step_out() end)
vim.keymap.set('n', '<Leader>b', function() require('dap').toggle_breakpoint() end)When you run just start_with_debugpy:
- Django starts with debugpy listening on
0.0.0.0:5678inside the container - Docker exposes port 5678 to
localhost:5678on your host machine - Your editor connects via the Debug Adapter Protocol (DAP)
- You can set breakpoints, inspect variables, and step through code
Note
- Auto-reload is disabled when debugging - you must manually restart after code changes
- For normal development with auto-reload, use
just startinstead
- Django: http://localhost:8000
- Debugpy: localhost:5678
- Vite (frontend): http://localhost:3000
- MkDocs (docs): http://localhost:4000
- Use conditional breakpoints to avoid stopping on every iteration in loops
- Inspect the call stack to understand the execution flow
- Watch variables to track state changes
- Use the debug console to evaluate expressions
- Remember to disable debugging when not needed to enable auto-reload
The debugpy server works with any editor that supports DAP:
- PyCharm/IntelliJ IDEA: See dedicated PyCharm section above for native Docker Compose debugging (recommended), or use "Python Debug Server" run configuration with debugpy
- Emacs: Use dap-mode
- Sublime Text: Use Debugger package
- Eclipse: Use PyDev
For non-PyCharm editors, configure them to connect to localhost:5678 with path mapping from your local workspace to /srv/app.