Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Debugging Django apps running in Docker using ptvsd - Visual Studio (Code)

Remote debugging in Docker (for Django apps)

In order to enable debugging for your Django app running in a Docker container, follow these steps using Visual Studio (Code):

  1. Install ptvsd:
pip install ptvsd
  1. 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).

  1. To your manage.py, add this:
  os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project.settings")   # This already exists
  
  import ptvsd
  from your_project import settings
  
  if settings.DEBUG:
      import ptvsd
      ptvsd.enable_attach(address = ('0.0.0.0', 3000))
   
   execute_from_command_line(sys.argv)                                        # This already exists
  1. Be sure to open port 3000 in your docker command or docker-compose.yml

  2. Run your app:

  python manage.py runserver --noreload --nothreading 0.0.0.0:8000

The --noreload and --nothreading options are necessary for ptvsd, so at this point debugging with live reload is not possible with this method. See also this thread

Line-by-line debugging

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"

@veuncent

This comment has been minimized.

Copy link
Owner Author

commented Sep 13, 2017

There have been some problems reported regarding remote debugging from Visual Studio Code using ptvsd > 3.0.0.
The issue mentioned most often is that VSC 'just hangs' when trying to connect to your remote debugger.

For now, use ptvsd 3.0.0:
pip install ptvsd==3.0.0

@veuncent

This comment has been minimized.

Copy link
Owner Author

commented Sep 17, 2017

Another problem can be caused by using ptvsd.wait_for_attach().
This can lead to the same problem as described above, where VSC just hangs while connecting to the remote debugger.

Try replacing wait_for_attach() with a simple time.sleep(10) and connect within the 10 seconds.

@veuncent

This comment has been minimized.

Copy link
Owner Author

commented Oct 9, 2017

Yet another problem can occur when using forward slashes in your launch.json.

E.g. change "remoteRoot": "/remote_root/of/your/app",
into "remoteRoot": "\\remote_root\of\your\app",

@lebnic

This comment has been minimized.

Copy link

commented Oct 29, 2018

Thanks a lot for sharing @veuncent , it really helped me figure out how to debug my django container within vscode

Here's what worked for me:

  1. add ptvsd == 4.1.4 to your requirements.txt file

  2. add the following inside your manage.py file (as suggeste in above gist)

#!/usr/bin/env python
import os
import sys


if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "api.settings")

    if os.environ.get("DJANGO_DEBUGGER", False):
        import ptvsd

        ptvsd.enable_attach(address=("0.0.0.0", 3000))

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

  1. install vscode extension ms-python.python
    image

  2. add the following configuration inside your launch.json file:

"configurations": [
    {
        // requires vscode extension: ms-python.python
        "name": "runserver",
        "type": "python",
        "request": "attach",
        "pathMappings": [
            {
                "localRoot": "${workspaceFolder}",
                "remoteRoot": "/home"
            }
        ],
        "port": 3000,
        "host": "localhost",
    }
]
  1. execute the following in your terminal:
docker-compose run -p 3000:3000 -p 8080:8001 --rm web sh -c 'DJANGO_DEBUGGER=True python api/manage.py runserver --noreload --nothreading 0.0.0.0:8001'
  1. once your server is running, start debugging by selecting runserver launch configuration in vscode's debug menu
    image

  2. that's it, you are debugging in vscode !
    image

@christippett

This comment has been minimized.

Copy link

commented Jan 9, 2019

Thanks @lebnic, that was helpful too. The approach I've settled with is calling python -m ptvsd from the command line instead of embedding it in manage.py.

My tasks.json looks like this (note the sleep 5 at the end of the command, this is needed to allow the debugger time to attach):

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "start_container",
            "type": "shell",
            "command": "docker-compose run -d -p 3000:3000 -p 8000:8000 --rm web bash -c 'python -m ptvsd --host 0.0.0.0 --port 3000 --wait manage.py runserver --noreload --nothreading 0.0.0.0:8000' && sleep 5"
        },
        {
            "label": "stop_container",
            "type": "shell",
            "command": "docker rm -f $(docker ps -a -q --filter ancestor=web --format='{{.ID}}')",
        }
    ]
}
@lebnic

This comment has been minimized.

Copy link

commented Jan 15, 2019

@christippett I'll also need to implement a similar waiting in order to execute my unit tests; Your comment will surely help me, thanks :-)

@callect

This comment has been minimized.

Copy link

commented Aug 13, 2019

thanks a lot's. my debuger is worked.
btw,I use python manage.py runserver 0.0.0.0:8000 make debuger connected,but add option --noreload --nothreading not work

@veuncent

This comment has been minimized.

Copy link
Owner Author

commented Aug 14, 2019

Hi @callect , what is the error you get when running with --noreload --nothreading? One of the problems you may run into without those settings is that, when you edit your python code, Django will reload the development server and run ptvsd.enable_attach() (in your manage.py) again, which could throw an error.

@callect

This comment has been minimized.

Copy link

commented Aug 14, 2019

hi,@veuncent
I'm try add those options again, it's worked from now on.
I don't know why it doesn't work, and can not refresh page at yesterday. I'm sorry that I can't reproduce right now :(

@veuncent

This comment has been minimized.

Copy link
Owner Author

commented Aug 14, 2019

No worries @callect! Glad it is solved.

@callect

This comment has been minimized.

Copy link

commented Aug 15, 2019

@veuncent thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.