debug python code running in docker container from host using vscode - python

I have a container running on my host with a python process and I have the vs code installed on the host. Is it possible to debug the python process from the host installed vscode ? If yes, how can this be achieved ?

Since I do not know what python process you have running, I'll use FastAPI as an example.
First, you need to define a new configuration in the file <project_root>/.vscode/launch.json. To access this file, you can go to the Run & Debug section on the activity bar, and press the cog/wheel at the top.
Add a new item in the configurations like shown below.
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: Remote Attach",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
]
}
]
}
Now you need to include debugpy. If you are using a requirements file, you can just add it there. If you use Poetry, you can run poetry add debugpy in your terminal (the Dockerfile example shows how you can use Poetry in a docker image).
First option - In your Dockerfile you need to run debugpy and make it listen for port 5678.
Now the debugger will start every time you run the container and await attachment.
FROM python:3.10.0
# Set the working directory:
WORKDIR /usr/src
# Copy the pyproject.toml file (or requirements.txt) to cache them in the docker layer:
COPY [ "./src/pyproject.toml", "./"]
# Set the python path if needed.
# For example, if main.py is not located in the project root:
ENV PYTHONPATH="$PYTHONPATH:${PWD}"
# Upgrade pip and install Poetry:
RUN pip install --upgrade pip && pip install poetry==1.1.12
# Project initialization using Poetry:
RUN poetry config virtualenvs.create false \
&& poetry install --no-interaction --no-ansi
# Run the application:
CMD ["python", "-m", "debugpy", "--wait-for-client", "--listen", "0.0.0.0:5678", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--reload", "--reload-exclude", "tests"]
EXPOSE 8000 5678
Second option - Set up the debugger in the main.py file by adding the lines below. This means that the debugger will be attached to the container when it starts; if the debugger variable is set to True.
debugger = True
if __name__ == "__main__":
if debugger:
import debugpy
debugpy.listen(("0.0.0.0", 5678))
debugpy.wait_for_client()
uvicorn.run(
"main:app",
host="localhost",
port=8000,
log_level="info",
reload=True,
)
Both examples need the Dockerfile to expose the port 5678.
Now, after running the container, the debugger will "pause" and await attachment. To attach the debugger, go back to Run & Debug section on the activity bar in VSCode and select Python: Remote Attach from the dropdown menu and press play.
Now you should be able to use the debugger inside the docker container.

Related

Debugging dockerized Django in VS Code results in error "Timed out waiting for launcher to connect"

I want to debug my Django application using a docker container in Visual Studio Code.
Microsoft published a guide how to do that, which I followed step by step:
https://code.visualstudio.com/docs/containers/quickstart-python
But when I try to run the debugger, I get the following error message:
Timed out waiting for launcher to connect
Here is what I did step by step:
I initialized a simple Django application using django-admin startproject helloworld
In VS Code I opened the folder including the manage.py
Opened Command Palette Ctrl + Shift + P, and then selected Docker: Add Docker Files to Workspace...
Select Application Platform Python: Django
Include Docker Compose files No
Relative path to the app's entrypoint manage.py
What ports does your app listen on? 8000
VS Codes then creates several files (see below).
When I try to start the debugger (like in the guide), I get the following error message:
The terminal doesn't show any error messages, but the commands executed:
.vscode/launch.json:
{
"configurations": [
{
"name": "Docker: Python - Django",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug",
"python": {
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
],
"projectType": "django"
}
}
]
}
.vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"type": "docker-build",
"label": "docker-build",
"platform": "python",
"dockerBuild": {
"tag": "dockerdebugging:latest",
"dockerfile": "${workspaceFolder}/Dockerfile",
"context": "${workspaceFolder}",
"pull": true
}
},
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": [
"docker-build"
],
"python": {
"args": [
"runserver",
"0.0.0.0:8000",
"--nothreading",
"--noreload"
],
"file": "manage.py"
}
}
]
}
Dockerfile:
# For more information, please refer to https://aka.ms/vscode-docker-python
FROM python:3.8-slim-buster
EXPOSE 8000
# Keeps Python from generating .pyc files in the container
ENV PYTHONDONTWRITEBYTECODE 1
# Turns off buffering for easier container logging
ENV PYTHONUNBUFFERED 1
# Install pip requirements
ADD requirements.txt .
RUN python -m pip install -r requirements.txt
WORKDIR /app
ADD . /app
# Switching to a non-root user, please refer to https://aka.ms/vscode-docker-python-user-rights
RUN useradd appuser && chown -R appuser /app
USER appuser
# During debugging, this entry point will be overridden. For more information, please refer to https://aka.ms/vscode-docker-python-debug
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "helloworld.wsgi"]
requirements.txt:
# To ensure app dependencies are ported from your virtual environment/host machine into your container, run 'pip freeze > requirements.txt' in the terminal to overwrite this file
django==3.0.3
gunicorn==20.0.4
VS Code Version: 1.47.1
Python Extension Version: v2020.7.94776
The idea of debugging in vs code is to:
use debugpy to launch your code with a port, say 5678
in vscode to 'Remote Attach' to that process.
I may be wrong but what i can see from your code, you didn't attach to your process.
I wrote the way I did here, I use docker-compose and docker. My way is different with yours but you will get the idea...:)
My issue were missing packages. Docker usually works fine, I haven't had any issues before at all.
I originally installed docker like described in the official documentation:
https://docs.docker.com/engine/install/ubuntu/
But after I tried installing the docker.io package, debugging worked fine in VS Code:
sudo apt install docker.io
There's no errors compared to the vscode tutorial in your project. Cause the error is timeout waiting for luncher to connect, try restart docker service and reload your window in vscode.
Here is a clue and a workaround:
The instructions I followed had me open VS code inside my ubuntu WLS2 instance. Note: my app is just a generic python app, not django.
If I click this and change it to open as a windows folder, then fun debug, everything suddenly works for me. (It spins up the docker and connects to it with debug, does breakpoints etc.)
I think what is happening for me is that "sometimes" docker is starting the container/app on its own WSL instance and my ubuntu instance cannot route to it for the debug.
I say sometimes, because sometimes it works. I think it might be related to which application (docker, ubuntu, vscode) I start first when I boot my machine.
I've messed with the docker, resources, WSL integration settings, the windows firewall, and restarted various things.
I'm sure a proper fix is not that complicated, however running VS code in native windows is enough of a fix for me. I don't see why the added complexity of starting the VS code session inside WSL is actually necessary.

VS code Python attach remote error 'connect ECONNREFUSED'

So I have this Django app inside of Docker running and I'm trying to attach VS code to it so I can debug here is my launch file
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Remote Attach",
"type": "python",
"request": "attach",
"port": 8800,
"host": "192.168.99.100",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
]
}
]
}
Here's my docker file
FROM registry.gitlab.com/datadrivendiscovery/images/primitives:ubuntu-bionic-python36-v2020.1.9
ENV PYTHONUNBUFFERED 1
RUN mkdir /bbml
WORKDIR /bbml
COPY requirements.txt /bbml/
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
RUN pip install ptvsd
ADD . /bbml/
CMD python -m ptvsd --host 0.0.0.0 --port 3500 --wait --multiprocess -m ./manage.py runserver 0.0.0.0:8800
# CMD [ "python", "./manage.py runserver 0.0.0.0:8800" ]
here's my docker-compose
version: '3'
services:
web:
build: .
command: "python3 manage.py runserver 0.0.0.0:8800"
container_name: bbml
volumes:
- .:/bbml
ports:
- "8800:8800"
- "3500:3500"
As you can see I'm running ptvsd on port 3500, but everytime I push the green run button on VScode I get "connect ECONNREFUSE 192.168.99.100:3500". Any suggestions?
I was following this guide:
https://www.youtube.com/watch?v=b78Tg-YmJZI
I also had this problem. I found the solution here
basically, you have to configure the debugger with debugpy.listen(("0.0.0.0", 5678))
This happens because by default debugpy is listening on localhost. if you have your docker container on another host you have to add 0.0.0.0
For me it was that the port I tried to use wasn't open on the remote machine:
sudo ufw allow <portNumber>

Python Docker Remote Debugging VS Code

trying to get remote debugging for my python flask API I have. I'm able to docker-compose up and have postman successfully call the running container, but when I try to attach the debugger, it never compiles. Below is my yml, dockerfile and vscode launch settings... the following error I get is:
There was an error in starting the debug server. Error = {"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect","address":"127.0.0.1","port":5050}
version: '2'
services:
website:
build: .
command: >
python ./nomz/app.py
environment:
PYTHONUNBUFFERED: 'true'
volumes:
- '.:/nomz'
ports:
- '5000:5000'
- '5050'
DockerFile
FROM python:3.6-slim
ENV INSTALL_PATH /nomz
RUN mkdir -p $INSTALL_PATH
WORKDIR $INSTALL_PATH
COPY requirements.txt requirements.txt
RUN pip3 install -r requirements.txt
COPY . .
EXPOSE 5000 5050
VSCode Launch Settings
{
"name": "Python: Attach",
"type": "python",
"request": "attach",
"localRoot": "${workspaceFolder}/nomz/app.py",
"remoteRoot": "/nomz/",
"port": 5050,
"host": "localhost"
}
I finally got it working with remote debugging. I had to pip3 install ptvsd==3.0.0 on my local, and make sure that the requirements.txt for my docker container had the same version. (note: the latest version 3.2.1 didn't work)
#BrettCannon had the right link for a good tutorial
https://code.visualstudio.com/docs/python/debugging#_remote-debugging
What I had to do was add some code to the app.py of the flask app. I originally was getting address already in use error when starting the container, so I added the socket code and after the first successful attach of debugger I didn't seem to need it anymore (strange I know, but that's why I left it in in case someone else gets that error)
try:
import ptvsd
# import socket
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# sock.close()
ptvsd.enable_attach(secret=None,address=('0.0.0.0',5050))
ptvsd.wait_for_attach()
except Exception as ex:
print('Not working: ')
also i took the debug kwarg off the app.run() in app.py for the flask app.
This all gave me the ability to connect the debugger, but the breakpoints where "Unverified", so the last thing that had to happen was a path to the app.py in the launch.json for the remoteRoot. I will say I created a small test api to get this working, and it only need the first level of pathing (ie. /app and not /app/app/app.py)Here is a github of the test api I made (https://github.com/tomParty/docker_python). So if the debugger is attaching, but your breakpoints are unverified, play around with the path of the remoteRoot
"remoteRoot": "/nomz/nomz/app.py"

Unable to debug Django process from vs code

Im trying to debug my Django process from vs code. But I am not able to get it to work. In my manage.py:
import ptvsd
try:
ptvsd.enable_attach("my_secret", address=('localhost', 3000))
except:
pass
In my docker-compose:
version: '3'
services:
db:
image: postgres
web:
build: .
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- "8000:8000"
- "3000:3000"
depends_on:
- db
And my debug info in launch.json:
{
"name": "Attach (Remote Debug)",
"type": "python",
"request": "attach",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/code",
"port": 3000,
"secret": "my_secret",
"host": "localhost"
},
Dockerfile:
FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
EXPOSE 3000
When starting the debug session I get a message saying: "debug adapter process has terminated unexpectedly". Does anyone have any tips on how to get this working? Im running ptvsd 3.0.0 both on my computer and in the docker container.
Three points to check to debug Django in a Docker environment with VSCode:
VSCode remote debugging works only with ptvsd==3.0.0 for now (cf. VSCode documentation)
With docker-compose, ptvsd needs to be attached to the default route 0.0.0.0 in order to be reached from the host machine (like the Django development server)
ptvsd rely on sockets (which can be attached only once to a port) and Django development server reloads the manage.py file after each code changes in the project. So after each code modification, the debug server will fail to attach. To work around this problem, the best solution is to attach the ptvsd debugger in the wsgi.py file, which is only loaded once.
In order to enable remote debugging for Django apps in VS Code (e.g. when debugging docker containers), do the following:
Add ptvsd to your requirements.txt file
ptvsd == 4.3.2
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).
To your manage.py, add this:
if __name__ == "__main__": # This already exists
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "your_project.settings") # This already exists
from django.core.management import execute_from_command_line # This already exists
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', 3000))
print "Attached remote debugger"
execute_from_command_line(sys.argv) # This already exists
Note: The third if statement here ensures the debugger does not get attached again after a live reload.
Be sure to open port 3000 in your docker command or docker-compose.yml
Run your app:
python manage.py runserver 0.0.0.0:8000
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"
Sources
Source 1
Source 2
Your problem is likely that the webserver is reloading your file and killing your connection. Put a print or log statemet in the start of your settings.py code and see if it is being loaded twice. Then run it with a no-reload flag. ptvsd==3.0.0 does work for as long as it is installed both on host and remote machine.

How to remote debug python code in a Docker Container with VS Code

I've just registered for this question. It's about if it's possible to remote debug python code in a Docker Container with VS Code.
I am having a completely configured Docker Container here. I got a little bit of help with it, and I'm pretty new to docker anyways. In it runs Odoo v10. But I cant get the remote debug in VS Code to work. I have tried this explanation, but I don't really get it.
Is it even possible? And if yes, how can I get it to work?
I'm running Kubuntu 16.04 with VS Code 1.6.1 and the Python Extension from Don Jayamanne.
Ah yeah and I hope I am at the right location with this question and it's not against any rules.
UPDATE:
Just tried the way of Elton Stoneman. With it I'm getting this error:
There was an error in starting the debug server.
Error = {"code":"ECONNREFUSED","errno":"ECONNREFUSED","syscall":"connect",
"address":"172.21.0.4","port":3000}
My Dockerfile looks like this:
FROM **cut_out**
USER root
# debug/dev settings
RUN pip install \
watchdog
COPY workspace/pysrc /pysrc
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
python-dev \
&& /usr/bin/python /pysrc/setup_cython.py build_ext --inplace \
&& rm -rf /var/lib/apt/lists/*
EXPOSE 3000
USER odoo
The pysrc in my Dockerfile is there because this was intended for working with PyDev (Eclipse) before.
This is the run command I've used:
docker-compose run -d -p 3000:3000 odoo
And this is the important part of my launch.json:
{
"name": "Attach (Remote Debug)",
"type": "python",
"request": "attach",
"localRoot": "${workspaceRoot}",
"remoteRoot": "${workspaceRoot}",
"port": 3000,
"secret": "my_secret",
"host": "172.21.0.4"
}
I hope that's enough information for now.
UPDATE 2:
Alright I found the solution. I totally misunderstood how Docker works and tried it completeley wrong. I already had a completeley configured Docker-compose. So everything I needed to do was to adapt my VS Code configs to the docker-compose.yml. This means that I just had to change the launch.json to the port 8069 (default Odoo port) and just need to use docker-compose up, then the debugging works in VS Code.
Unfortunately the use of ptvsd kinda destroys my Odoo environment, but at least I'm able to debug now. Thanks!
Yes, this is possible - when the Python app is running in a Docker container, you can treat it like a remote machine.
In your Docker image, you'll need to make the remote debugging port available (e.g. EXPOSE 3000 in the Dockerfile), include the ptvsd setup in your Python app, and then publish the port when you run the container, something like:
docker run -d -p 3000:3000 my-image
Then use docker inspect to get the IP address of the running container, and that's what you use for the host in the launch file.
works with vscode 1.45.0 & later. for reference files https://gist.github.com/kerbrose/e646aaf9daece42b46091e2ca0eb55d0
1- Edit your docker.dev file & insert RUN pip3 install -U debugpy. this will install a python package debugpy instead of the deprecated one ptvsd because your vscode (local) will be communicating to debugpy (remote) server of your docker image using it.
2- Start your containers. however you will be starting the python package that you just installed debugpy. it could be as next command from your shell.
docker-compose run --rm -p 8888:3001 -p 8879:8069 {DOCKER IMAGE[:TAG|#DIGEST]} /usr/bin/python3 -m debugpy --listen 0.0.0.0:3001 /usr/bin/odoo --db_user=odoo --db_host=db --db_password=odoo
3- Prepare your launcher file as following. please note that port will be related to odoo server. debugServer will be the port for the debug server
{
"name": "Odoo: Attach",
"type": "python",
"request": "attach",
"port": 8879,
"debugServer": 8888,
"host": "localhost",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/mnt/extra-addons",
}
],
"logToFile": true
}
If you want a nice step by step walkthrough of how to attach a remote debugger for VS code in a container you could check out the youtube video "Debugging Python in Docker using VSCode".
He also talks about how to configure the Docker file such that the container does not includes the debugger when run in production mode.

Categories