使用docker-compose的VScode调试器

8

最近我开始使用Docker来运行我的项目,包括以下内容:

  • Django
  • Nginx
  • Gunicorn
  • Celery
  • Postgres
  • Redis

在使用docker-compose之前,设置调试器很容易,但现在我无法这样做。一旦我启动调试器,它会加载一段时间,然后自动停止,没有任何日志或错误,以下是相关的代码。

launch.json

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

docker-compose.yml

version: '3'

services:
 db:
     image: postgres:12
     env_file: .env
     environment:
        - POSTGRES_DB=${DB_NAME}
        - POSTGRES_USER=${DB_USER}
        - POSTGRES_PASSWORD=${DB_PASSWORD}
    ports:
        - "5431:5432"
    volumes:
        - dbdata:/var/lib/postgresql/data
nginx:
    image: nginx:1.14
    ports:
        - "443:443"
        - "80:80"
    volumes:
        - ./config/nginx/:/etc/nginx/conf.d
        - ./myapp/static:/var/www/myapp.me/static/
web:
    restart: always
    build: ./myapp
    command:  bash -c "
                python manage.py collectstatic --noinput 
                && python manage.py makemigrations
                && python manage.py migrate
                && gunicorn --certfile=/etc/certs/localhost.crt --keyfile=/etc/certs/localhost.key myapp.wsgi:application --bind 0.0.0.0:443 --reload"
    expose:
        - "443"
    depends_on:
        - db
        - nginx
    env_file:
        - .env
    volumes:
        - ./myapp:/opt/myapp
        - ./config/nginx/certs/:/etc/certs
        - ./myapp/static:/var/www/myapp.me/static/

broker:
    image: redis:alpine
    expose: 
        - "6379"

celery:
    build: ./myapp
    command: celery -A myapp worker -l info
    env_file:
        - .env
    volumes:
        - ./myapp:/opt/myapp
    depends_on:
        - broker
        - db

celery-beat:
    build: ./myapp
    command: celery -A myapp beat -l info
    env_file:
        - .env
    volumes:
        - ./myapp:/opt/myapp
    depends_on:
        - broker
        - db

volumes:
    dbdata:
2个回答

13

最终我自己解决了这个问题。 从这个问题中我得到了几点经验。

你需要使用debugpy并将其放置在你的manage.py文件中以开始监听一个端口。 我做了类似于这样的事情

import debugpy

debugpy.listen(('0.0.0.0', 5678))
debugpy.wait_for_client()
debugpy.breakpoint()

除此之外,我们需要将这个端口映射到主机内部的某个端口上。因此我们需要在docker-compose文件中的web服务中添加一行代码。

ports:
    - "5678:5678"

我的 launch.json 看起来是这样的

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

注意:确保您的requirements文件中包含debugpy,或手动安装。


@targhs 你能够调试 Celery 任务吗? - Reema Parakh
@targhs调试器在使用celery任务时无法正常工作。 - Reema Parakh
1
好像你需要以某种方式附加调试器到进程。这只会将其附加到在特定端口上运行的应用程序。如果不经过代码,我无法为你提供更多帮助。 - targhs
manage.py文件是专门用于Django项目的吗? - ricoms
1
@ricoms 在这种情况下,你可以将它导入到你的主应用程序文件中。 - targhs
显示剩余5条评论

3
如果将调试器制作为模块,则可以使用环境变量打开和关闭它。我只是以这篇文章为基础,创建了一个快速API / Gunicorn调试解决方案。
# debugger.py
from os import getenv

def initialize_flask_server_debugger_if_needed():
    if getenv("DEBUGGER") == "True":
        import multiprocessing

        if multiprocessing.current_process().pid > 1:
            import debugpy

            debugpy.listen(("0.0.0.0", 10001))
            print("⏳ VS Code debugger can now be attached, press F5 in VS Code ⏳", flush=True)
            debugpy.wait_for_client()
            print("� VS Code debugger attached, enjoy debugging �", flush=True)

请看Adrian撰写的文章:在VS Code中调试Flask应用


谢谢。看起来很有帮助。我会尝试在我的项目中使用它。 - targhs
@MrYutz,我现在也正在使用您的解决方案,感觉还不错。 只有两件事: 1)为什么要检查 pid > 1? 2)如果我在 manage.py 的 main() 中调用此函数,它将运行多次,重置调试服务器并等待新的连接。 - Lars Schellhas
@LarsSchellhas - “在调试模式下,Flask使用第一个进程(pid==1)来启动处理连接的子进程。如果以下代码由主进程执行,则会占用调试端口,随后的子进程无法使用相同的端口,并被分配一个随机端口以防止连接。” - MrYutz
好的,我明白了。我没有使用 Flask,而是 Django,所以我想用自己的方式进行适应就可以了 :) - Lars Schellhas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接