Debug Python within a container

When adding Docker files to a Python project, tasks and launch configurations are added to enable debugging the application within a Docker container. To accommodate the various scenarios of Python projects, some apps may require additional configuration.

Configuring the Docker container entry point

You can configure the entry point of the Docker container by setting properties in tasks.json. VS Code automatically configures the container entry point when you first use the Docker: Add Docker Files to Workspace... command.

Example: Configuring the entry point for a Python module

{
  "tasks": [
    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": [
        "docker-build"
      ],
      "python": {
        "module": "myapp"
      }
    }
  ]
}

Example: Configuring the entry point for a Python file

{
  "tasks": [
    {
      "type": "docker-run",
      "label": "docker-run: debug",
      "dependsOn": [
        "docker-build"
      ],
      "python": {
        "args": [
          "runserver",
          "0.0.0.0:8000",
          "--nothreading",
          "--noreload"
        ],
        "file": "manage.py"
      }
    }
  ]
}

Automatically launching the browser to the entry page of the application

You can select the Docker: Python - Django or Docker: Python - Flask launch configurations to automatically launch the browser to the main page of the app. This feature is enabled by default, but you can configure this behavior explicitly by setting the dockerServerReadyAction object in launch.json.

This feature depends on several aspects of the application:

Here is an example of using dockerServerReadyAction to launch the browser to open the about.html page based on a specific server message pattern:

{
  "configurations": [
    {
      "name": "Docker: Python - Django",
      "type": "docker",
      "request": "launch",
      "preLaunchTask": "docker-run: debug",
      "python": {
        "pathMappings": [
          {
            "localRoot": "${workspaceFolder}",
            "remoteRoot": "/app"
          }
        ],
        "projectType": "django"
      },
      "dockerServerReadyAction": {
        "action": "openExternally",
        "pattern": "Starting development server at (https?://\\S+|[0-9]+)",
        "uriFormat": "%s://localhost:%s/about.html"
      }
    }
  ]
}

Note: The regex found in the pattern attribute simply attempts to capture a logged message similar to "Starting development server at http://localhost:8000". It accommodates variations in the url for http or https, any host name, and any port.

Important dockerServerReadyAction object properties

How to debug your app with Gunicorn

The Docker: Python - Django and Docker: Python - Flask launch configurations automatically override the Gunicorn entry point of the container with the Python debugger. More information about Python debugger import usage can be found here.

To debug your app running with Gunicorn (or any other web server):

  1. Add ptvsd to your requirements.txt file:

    python ptvsd==4.3.2

  2. Add the following code snippet to the file that you wish to debug:

    python import ptvsd ptvsd.enable_attach(address=('0.0.0.0', 5678)) ptvsd.wait_for_attach()

  3. Add a Python: Remote Attach configuration to launch.json in the .vscode folder:

    json { "name":"Python: Remote Attach", "type":"python", "request":"attach", "port":5678, "host":"localhost", "pathMappings":[{ "localRoot":"${workspaceFolder}", "remoteRoot":"/app"} ] }

  4. Save the launch.json file.

  5. Modify the docker-compose.yml file to expose the debugger port by adding 5678:5678 to the ports section. If you are using docker run to run your container from the terminal, you must append -p 5678:5678.
  6. Start the container by right-clicking on a docker-compose.yml file and selecting Compose Up or doing docker run from the command line.
  7. Set a breakpoint in the chosen file.
  8. Navigate to Run and Debug and select the Python: Remote Attach launch configuration.
  9. Hit kb(workbench.action.debug.start) to attach the debugger.

Next steps

Learn more about: