Initial

PuDB is my first choice to go python debugging tool. I use it whenever I can.

PuDB

As they say in the PuDB doc:

Its goal is to provide all the niceties of modern GUI-based debuggers in a more lightweight and keyboard-friendly package.

I’m always suprised that how few people on the Python sphere know about it. Although I’m not a GUI guy, I couldn’t imagine my dev workflow without it.

Using PuDB

You can install PuDB from pip package manager:

$ pip install pudb==2022.1.3

After that, you may set a breakpoint as below:

from pudb import set_trace; set_trace()

If you use Python 3.7+, you can define PYTHONBREAKPOINT environment variable to make PuDB default for breakpoint():

# Set breakpoint() in Python to call pudb
export PYTHONBREAKPOINT="pudb.set_trace"

Inside Docker

You can launch PuDB inside a running python docker container as we’ve shown above, however the best way would be using remote debugging.

First put an entrypoint with some modification:

from pudb.remote import set_trace; set_trace(term_size=(200, 60), host="0.0.0.0", port=6900)

On your docker-compose.yml file, map container’s 6900 port to your host’s 6900 port.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
version: "3"

services:
  web:
    build:
      context: .
      dockerfile: ./Dockerfile

    ...

    ports:
      - "8000:8000"  # web server
      - "6900:6900"  # PuDB telnet

    ...

After hitting this entrypoint, the code will stop, debugger will look for the port (6900 in our case) and wait for a telnet connection:

pudb:6900: Please start a telnet session using a command like:
telnet 0.0.0.0 6900
pudb:6900: Waiting for client...

Now run telnet command from another terminal session as described above:

$ telnet 127.0.0.1 6900

Note

If you are a Mac user and you don’t have any telnet client, you can install one via Homebrew. Type $ brew install telnet on your terminal.

Then proceed as usual.

PuDB config

One annoying thing is that every time you rebuild the container, you have to re-enter your choices for PuDB configuration.

Luckily there is a solution for that.

All PuDB information is stored in a location specified by the XDG Base Directory Specification. Usually, it is ~/.config/pudb. You can change this directory by defining/exporting XDG_CONFIG_HOME environment variable.

From the terminal:

export XDG_CONFIG_HOME="/code/.config"

Or set it from docker-compose.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
version: "3"

services:
  web:
    build:
      context: .
      dockerfile: ./Dockerfile

    ...
    environment:
      - XDG_CONFIG_HOME="/code/.config"


    ports:
      - "8000:8000"  # web server
      - "6900:6900"  # pudb telnet

    ...

As a bonus point, I’d like to mention that you can use your local config as mounting your config directory onto the container:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
version: "3"

services:
  web:
    build:
      context: .
      dockerfile: ./Dockerfile

    ...
    environment:
      - XDG_CONFIG_HOME="/code/.config"


    ports:
      - "8000:8000"  # web server
      - "6900:6900"  # pudb telnet

    volumes:
      - ~/.config/pudb:/code/.config/pudb
    ...

All done!