用VScode调试一个用docker构建的fastAPI项目,用postgresql数据库编写



我希望能够使用VScode使我的代码在断点上停止。我的项目是用docker compose构建的,在8000端口上不需要调试即可工作。

以下是我的配置文件:

docker compose:

version: '3.4'
services:
murmurside:
image: murmurside
build: ./murmur_side
command: ["sh", "-c", "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn app.main:app --host 0.0.0.0 --port 8000"]
volumes:
- ./murmur_side/:/murmur_side/
ports:
- 8000:8000
- 5678:5678
environment:
- DATABASE_URL=postgresql://USERNAME:PASSWORD@db/fastapi_db_2
db:
image: postgres:13-alpine
volumes:
- postgres_data2:/var/lib/postgresql/data/
expose:
- 5432
environment:
- POSTGRES_USER=USERNAME
- POSTGRES_PASSWORD=PASSWORD
- POSTGRES_DB=fastapi_db_2
volumes:
postgres_data2:

码头文件:

# For more information, please refer to https://aka.ms/vscode-docker-python
FROM python:3.10-slim
EXPOSE 8000
WORKDIR /murmur_side
# 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
COPY requirements.txt .
RUN python -m pip install -r requirements.txt
COPY . /murmur_side
# Creates a non-root user with an explicit UID and adds permission to access the /app folder
# For more info, please refer to https://aka.ms/vscode-docker-python-configure-containers
RUN adduser -u 5678 --disabled-password --gecos "" appuser && chown -R appuser /murmur_side
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", "-k", "uvicorn.workers.UvicornWorker", "app.main:app"]

launch.json:

我测试了一个"启动"配置,但调试器随后对数据库相关代码进行了调试。它似乎没有正确链接到数据库:在DATABASE_URL = os.getenv("DATABASE_URL")之后,database_URL保持为空。

{
"configurations": [
{
"name": "Docker: Python - Fastapi",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug",
"python": {
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app"
}
],
"projectType": "fastapi"
}
}
]
}

我还测试了"附加"配置。在这种情况下,我会在一个随机端口启动一个调试器容器,但当我浏览到127.0.0.1:randomPort 时,我什么都没有得到

{
"configurations": [
{
"name": "Python: Remote Attach",
"type": "python",
"request": "attach",
"connect": {
"host": "0.0.0.0",
"port": 8000     # I also tried with 5678
},
"preLaunchTask": "docker-run: debug",
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/murmur_side"
}
]
}
]
}

在这个项目中,我看到他们在tasks.json中添加了数据库凭据。但我在其他地方没有找到任何说明这一点的文档。我试过了,但除了用户名、密码和数据库名之外,我不确定其他选项,因为我不必在docker撰写中提及它们。也许我也弄错了港口,因为有几个港口。

tasks.json:

{
"version": "2.0.0",
"tasks": [
{
"type": "docker-build",
"label": "docker-build",
"platform": "python",
"dockerBuild": {
"tag": "sd4timapi_pip_debug:latest",
"dockerfile": "${workspaceFolder}/murmur_side/Dockerfile",
"context": "${workspaceFolder}/murmur_side/",
"pull": true
}
},
{
"type": "docker-run",
"label": "docker-run: debug",
"dependsOn": [
"docker-build"
],
"dockerRun": {      # I also tried without this section
"image": "sd4timapi_pip_debug:latest",   
"volumes": [
{
"containerPath": "/murmur_side/",
"localPath": "${workspaceFolder}/murmur_side/"
}
],
"ports": [
{
"containerPort": 8000,
"hostPort": 8001,  # because it doesn't allow me to put 8000 : "port is already allocated"
"protocol": "tcp"
}
],
"env": {
"APP_PORT": "8000",           #UNSURE
"DEBUG": "TRUE",
"ENVIRONMENT": "local",       #UNSURE
"POSTGRES_USER": "USERNAME",
"POSTGRES_PASS": "PASSWORD",
"POSTGRES_DBNAME": "fastapi_db_2",
"POSTGRES_HOST": "db_host",  #UNSURE
"POSTGRES_PORT": "5432",     #UNSURE
"POSTGRES_APPLICATION_NAME": "sd4timapi_pip_debug", #UNSURE
}
},
"python": {
"args": [
"app.main:app",
"--host",
"0.0.0.0",
"--port",
"8000"
],
"module": "uvicorn"
}
}
]
}

这对我很有用,可以在VS Code中调试我的FastAPI应用程序。

这是"。vscode/slaunch.json";文件:

{
// 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": [
// Debug with FastAPI
{
"name": "Python: FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"args": [
"app.main:app",
"--host",
"0.0.0.0",
"--port",
"81",
"--reload"
],
"jinja": true,
"justMyCode": false
},
]
}

我在VS Code终端日志中得到以下消息,然后我可以使用断点等进行调试。

转到http://localhost:81/docs自从我部署到81端口后,您的浏览器中就出现了。

INFO:     Will watch for changes in these directories: ['/workspace']
INFO:     Uvicorn running on http://0.0.0.0:81 (Press CTRL+C to quit)
INFO:     Started reloader process [13707] using WatchFiles
INFO:     Started server process [13801]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     127.0.0.1:36070 - "GET /docs HTTP/1.1" 200 OK

同样的问题,我能够解决。

docker-compose.debug.yaml:

services:
api:
build:
context: ./backend
dockerfile: dockerfile
container_name: api
command: sh -c "pip install debugpy -t /tmp && python /tmp/debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn main:api --host 0.0.0.0 --port 8080 --reload"
ports:
- 8080:8080
- 5678:5678
environment:
environment: dev
db_name: dev
db_host: http://localhost:8000
volumes:
- ./backend/:/app/
depends_on:
- surreal
surreal:
image: surrealdb/surrealdb:latest
container_name: surreal
ports:
- 8000:8000
command: start --log trace --user root --pass root --bind 0.0.0.0:8000

launch.json:

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

}

在main.py中,FastApi应用程序被命名为api:

from core import ValidationException, Db, routers
from api.settings import Settings
from fastapi import FastAPI

settings = Settings()
api = FastAPI(title='Api', version='1.0.0', openapi_url=settings.OPENAPI_URL)
api.add_exception_handler(ValidationException, validate)
db = Db(settings.DB_NAME, settings.DB_HOST)
@api.on_event('startup')
async def startup_event():
routers.register(api)
db.init()
if __name__ == '__main__':
import uvicorn
uvicorn.run('main:api', host="127.0.0.1", port=8080, reload=True, proxy_headers=True)

希望能有所帮助。

相关内容

  • 没有找到相关文章

最新更新