1

I am developing a Python Django app in a Dockerized container. I have successfully setup remote debugging to attach to my Django server inside of a container. Me configuration is as follows.

launch.json

{
  "name": "Remote Django App",
  "type": "python",
  "request": "attach",
  "pathMappings": [
    {
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/app"
    }
  ],
  "port": 9001,
  "host": "localhost"
}

manage.py

#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'llf_api.settings')
    try:
        from django.core.management import execute_from_command_line
        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', 8001))
              print("Attached remote debugger")

    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__':
    main()

docker-compose.yml

services:
  api:
    image: ${DOCKER_IMAGE_BASE}:${DOCKER_TAG}
    build:
      context: .
      dockerfile: ./Dockerfile.development
    env_file:
      - .env
    environment:
      - DATABASE_URL=postgres://username:password@db/db_name
    volumes:
      - .:/app
    command: >
      bash -c "wait-for-it --service db:5432
      && python3 manage.py runserver 0.0.0.0:8000"
    ports:
      - "9000:8000"
      - "9001:8001"
    depends_on:
      - db
    tty: true
    stdin_open: true

The problem is that I run VS Code inside of a dev container (the Dockerfile.development above). So VS Code is essentially running within the same container the Django server is running which would make me think I need to attach to the local port (8001) the ptvsd is running on by setting my launch.json to the following:

launch.json

{
  "name": "Local Django App",
  "type": "python",
  "request": "attach",
  "host": "api",
  "port": 8001
}

However this doesn't work. When I try to attach the debugger in VS Code it appears to eventually timeout. Does anyone know how this could be accomplished?

1 Answer 1

1

My understanding of how VS Code and my server were running was inherently wrong. The server and VS Code are running off of the same image but NOT the same containers. The containers are running side by side and therefore the local networking is not available to either.

To make this work I realized I needed the VS Code container to access the server's container via the debugging port opened on the host. The only way I know how to do that is by using docker.for.mac.localhost as the host. So all that needed to change from my original setup was the launch.json configuration.

launch.json

{
  "name": "Remote Django App",
  "type": "python",
  "request": "attach",
  "pathMappings": [
    {
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/app"
    }
  ],
  "port": 9001,
  "host": "docker.for.mac.localhost"
}

VS Code now attaches to port 9001 which has been exposed on the host and connects to the host using docker.for.mac.localhost. It works!

Sign up to request clarification or add additional context in comments.

6 Comments

With this setup can you set breakpoints in python django code and stop on those breakpoints using vscode instance you have running on your linux or windows desktop?
Do you mean breakpoint() in python? With this setup it will break on the VS Code breakpoints only because the server itself ignores breakpoint() AFAIK.
yes i'm referring to breakpoints set in vscode view of sources, i.e. soft breakpoints, not python breakpoint(), i.e. hard breakpoints.
fyi, readers of this using wintel setups might want to be aware that the "Intel(R) Graphics Command Center Service" service parks on tcp/9001 and so you'd need to go into services and set it to manual or disabled if you want to use that remote attach port for debugging
Take a look at code.visualstudio.com/docs/remote/containers. In regards to the why, for Python it circumvents using a virtual environment and manually installing the base set of dependencies as they get picked up from the Docker container being used to serve the web api. It has it's own trade-offs however.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.