In order to enable debugging for your Django app running in a Docker container, follow these steps using Visual Studio (Code):
- Add
ptvsd
to your requirements.txt file
ptvsd == 4.3.2
- To your
launch.json
, add this:
{
"name": "Remote Django App",
"type": "python",
"request": "attach",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/remote_root/of/your/app"
}
],
"port": 3000,
"host": "localhost"
}
(Edit the remoteRoot
option to reflect your app).
- To your
manage.py
, add this:
if __name__ == "__main__": # This already exists
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project.settings") # This already exists
from django.core.management import execute_from_command_line # This already exists
from django.conf import settings
if settings.DEBUG:
if os.environ.get('RUN_MAIN') or os.environ.get('WERKZEUG_RUN_MAIN'):
import ptvsd
ptvsd.enable_attach(address = ('0.0.0.0', 3000))
print "Attached remote debugger"
execute_from_command_line(sys.argv) # This already exists
Note: The third if
statement here ensures the debugger does not get attached again after a live reload.
-
Be sure to open port 3000 in your
docker
command ordocker-compose.yml
-
Run your app:
python manage.py runserver 0.0.0.0:8000
Note: In some (non-Django) cases line-by-line debugging does not work, unless you use double backslashes (\) in your remoteRoot parameter (Viscual Studio Code), even though the remote server runs on Linux. E.g. "remoteRoot": "\\remote_root\\of\\your\\app"
- When running a (non-Django) app using
docker-compose run
instead ofdocker-compose up
, you need to add the additional--service-ports
flag to open the ports defined in yourdocker-compose.yml
:
docker-compose run --service-ports your_app
Otherwise, you will see a Connection refused
error when trying to attach, as the required debug port (usually 3000
) is not opened.
Shoutout to this exellent blog post describing how you can keep live reload
turned on while remote debugging. (Previously we had to disable Django's live reload
function because it would attach the debugger twice, thus throwing an error). We really can have our cake and eat it too.
Note: Be sure to use the latest version of ptvsd
, as some old versions will throw an exceptions.SystemExit
when you are attached from VS Code and the server gets reloaded. This happened to me using `ptvsd == 4.1.3.
I can make ptvsd work using manage.py calls and command line
python -m ptvsd --host 0.0.0.0 --port 5678 manage.py runserver --noreload
but when i try and use either within context of docker container using ubuntu:18.04 the 5678 port listener isn't created.If i
docker -it exec django_webservice bin/bash
into the container and do apip list
i see ptvsd and if i do anetstat -tunlp
it shows nginx web server tcp/80 listener but not the ptvsd tcp/5678 port so it doesn't matter that i exposed port in "docker run -p 8000:80 -p 5678:5678 . . . " command it seems something about initializing ptvsd from within that environment isn't working. i tried adding Dockerfile EXPOSE 5678 in addition to EXPOSE 80 that was already there and that makes no difference and docs suggest EXPOSE is optional documentation syntax only.Any thoughts on how to debug "docker run . . . " to determine what's causing failure?