Jirka's Public Notepad

Data Engineering | Python | SQL Server | Teradata

November 8, 2020 By Jiří Hubáček Leave a Comment

Debugging Docker Containers from Visual Studio Code

There wasn’t a necessity for me to debug code running in a container until now. It was because I develop my code on a Mac, run it on Linux boxes, and all dependencies are listed in the requirements file. One thing is missing here though – the Python version.

Source: https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fmemegenerator.net%2Fimg%2Finstances%2F500x%2F72796788%2Fwe-got-all-kind-of-python-cpython-ironpython-jython-pypy.jpg&f=1&nofb=1

Of course, there are ways of running various Python versions on the workstation. However, after a while trying making it work on Big Sur beta, I gave up and went for learning how can I debug a container instead.

Docker tip: to save building time and allowing Docker to reuse layers, move the least frequent changing step to the top of the Dockerfile. Like installing updates and requirements:

FROM ubuntu:18.04 as base

RUN apt-get update
RUN apt-get install -y python3.7-dev python3-pip gcc 

CMD mkdir -p /app/src

WORKDIR /app
COPY ./requirements.txt .
RUN pip3 install -r ./requirements.txt

Dockerfile: I went with two Dockerfiles, one for debug, the other for production.

In the Dockerfile_debug, we need to install debugpy and configure the image’s entry point. More examples are in the debugpy’s repo, my example:

RUN pip3 install debugpy
ENTRYPOINT [ "python3", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "bot.py" ]

The production Dockerfile would merely launch the Python script.

CMD ["python3", "bot.py"]

Docker-compose: It is also possible to have a single Dockerfile with multiple build stages like debug, test, production. The target build stage would be specified in Docker-compose or when running docker run command.

Debugging in Visual Code

First, we need to run a debugpy configured container. If we specify the --wait-for-client parameter, debugpy waits with any code execution before a debugger is attached.

Add a debug configuration and pick Remote Attach, specify localhost and port configured in Dockerfile (5678).

If our code is in the repo’s subfolder (in my case ./app/src, it needs), we need to specify the path so mapping between the local and remote py files would work. If the mapping is incorrect, breakpoints get disabled, and the interpreter swishes through.

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

One more thing, if there’s a code change, we need to rebuild the image and then run the container. A working example of the setup is in my Photo of the Day app repo.

Credits: DevOps Directive

Related

Filed Under: Docker Tagged With: debugging, Docker, vscode

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  • GitHub
  • LinkedIn
  • RSS
  • Twitter
© 2021 · Jiří Hubáček, PGP