CalcSnippets Search
Python 3 min read

`uvicorn --host 0.0.0.0` Is the Flag You Need When Your FastAPI App Works Locally and Is Still Invisible From Everything Else

A practical guide to Uvicorn host binding for developers whose app works in the browser on the same machine but cannot be reached from Docker, phones, reverse proxies, or other hosts.

Why this flag matters: one of the most common fake backend bugs is a perfectly healthy app listening only where nobody else can reach it.

This problem shows up everywhere: Docker, local LAN testing, remote servers, VM-based development, reverse proxies, and mobile testing. The developer says, "The app works on my machine." That part is true. The missing detail is that it only works from the same machine because the process is bound to loopback.

The usual mistake

A developer launches the app like this:

uvicorn app.main:app --reload

Then visits it locally and sees everything working.

By default, that process commonly listens on 127.0.0.1, which means:

  1. the same host can reach it
  2. another machine on the network cannot
  3. a container or proxy may not be able to
  4. the service appears "up" while still being unreachable from the place that matters

The fix

Bind to all interfaces:

uvicorn app.main:app --host 0.0.0.0 --port 8000

Now the process listens on all network interfaces available to that machine.

This does not magically override firewalls, security groups, or Docker networking, but it removes one extremely common blocker.

Situations where this matters most

This flag is especially relevant when:

  1. your API is running inside Docker
  2. you want to test from your phone on the same Wi-Fi
  3. nginx or Caddy should proxy to the app
  4. another container needs to call the service
  5. the app lives on a remote VM

In all of those cases, binding only to 127.0.0.1 is often the reason outside clients see nothing.

How to verify what is actually listening

On Linux, you can confirm the bind address with:

ss -ltnp | grep 8000

If you see 127.0.0.1:8000, that explains the invisibility problem. If you see 0.0.0.0:8000, the app is listening broadly enough and you can move on to the next network layer.

That next layer might be:

  1. Docker port publishing
  2. host firewall rules
  3. cloud firewall or security group settings
  4. reverse-proxy configuration

But the important thing is that you stop blaming CORS or FastAPI routing before checking whether the server is reachable at all.

A common Docker example

If you run FastAPI in Docker, the host flag and published port usually go together:

docker run -p 8000:8000 my-fastapi-image

Inside the container, your app still needs:

uvicorn app.main:app --host 0.0.0.0 --port 8000

Publishing the port without changing the bind address often creates a container that looks mapped correctly and still cannot serve traffic from outside itself.

Final recommendation

If your FastAPI app works only on the same machine and nowhere else, check the bind address before you start chasing fancier explanations. uvicorn --host 0.0.0.0 is often the missing line between "the app runs" and "the app is actually reachable."

Sources

Keep reading

Related guides