Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vscode debug FastAPI in container on MacOS

I am setting up debugging of FastAPI running in a container with VS Code. When I launch the debugger, the FastAPI app runs in the container. But when I access the webpage from host, there is no response from server as the following: enter image description here

However, if I start the container from command line with the following command, I can access the webpage from host.

docker run -p 8001:80/tcp with-batch:v2 uvicorn main:app --host 0.0.0.0 --port 80

Here is the tasks.json file:

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
    {
        "type": "docker-run",
        "label": "docker-run: debug",
        "dockerRun": {
            "image": "with-batch:v2",                
            "volumes": [
                {
                    "containerPath": "/app",
                    "localPath": "${workspaceFolder}/app"
                }
            ],
            "ports": [
                {
                    "containerPort": 80,
                    "hostPort": 8001,
                    "protocol": "tcp"
                }
            ]
        },
        "python": {
            "args": [
                "main:app",
                "--port",
                "80"
            ],
            "module": "uvicorn"
        }
    },
    {
        "type": "docker-build",
        "label": "docker-build",
        "platform": "python",
        "dockerBuild": {
            "tag": "with-batch:v2"
        }
    }
]

}

here is the launch.json 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": "Debug Flask App",
        "type": "docker",
        "request": "launch",
  
        "preLaunchTask": "docker-run: debug",
        "python": {
          "pathMappings": [
            {
              "localRoot": "${workspaceFolder}/app",
              "remoteRoot": "/app"
            }
          ],
          "projectType": "fastapi"
        }
      }
]

}

here is the debug console output: enter image description here

here is the docker-run: debug terminal output: enter image description here

here is the Python Debug Console terminal output: enter image description here

like image 596
Charles Ju Avatar asked May 04 '26 21:05

Charles Ju


1 Answers

Explanation

The reason you are not able to access your container at that port, is because VSCode builds your image with a random, unique localhost port mapped to the running container.

You can see this by running docker container inspect {container_name} which should print out a JSON representation of the running container. In your case you would write docker container inspect withbatch-dev

The JSON is an array of objects, in this case just the one object, with a key of "NetworkSettings" and a key in that object of "Ports" which would look similar to:

"Ports": {
    "80/tcp": [
        {
            "HostIp": "0.0.0.0",
            "HostPort": "55016"
        }
    ]
}

That port 55016 would be the port you can connect to at localhost:55016

Solution

With some tinkering and documentation it seems the "projectType": "fastapi" should be launching your browser for you at that specific port. Additionally, your debug console output shows Uvicorn running on http://127.0.0.1:80. 127.0.0.1 is localhost (also known as the loopback interface), which means your process in the docker container is only listening to internal connections. Think of docker containers being in their own subnetwork relative to your computer (there are exceptions to this, but that's not important). If they want to listen to outside connections (your computer or other containers), they would need to tell the container's virtual network interface to do so. In the context of a server, you would use the address 0.0.0.0 to indicate you want to listen on all ipv4 addresses referencing this interface.

That got a little deep, but suffice it to say, you should be able to add --host 0.0.0.0 to your run arguments and you would be able to connect. You would add this to tasks.json, in the docker-run object, where your other python args are specified:

    {
        "type": "docker-run",
        "label": "docker-run: debug",
        "dockerRun": {
            "image": "with-batch:v2",                
            "volumes": [
                {
                    "containerPath": "/app",
                    "localPath": "${workspaceFolder}/app"
                }
            ],
            "ports": [
                {
                    "containerPort": 80,
                    "hostPort": 8001,
                    "protocol": "tcp"
                }
            ]
        },
        "python": {
            "args": [
                "main:app",
                "--host",
                "0.0.0.0",
                "--port",
                "80"
            ],
            "module": "uvicorn"
        }
    },
like image 164
mgray88 Avatar answered May 06 '26 11:05

mgray88



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!