Port Binding Issue – Uvicorn app running but Space shows 404 (Docker / FastAPI)

Hi Hugging Face Support Team,

I’m running a custom FastAPI / Uvicorn backend in a Dockerized Space:
https://huggingface.co/spaces/PetSage/petsage-petsage-brain-v30

The container builds and starts successfully. The logs confirm:

PetSage v30 backend is live — semantic intelligence ready.
Uvicorn running on http://0.0.0.0:7860

Dockerfile config

EXPOSE 7860
LABEL huggingface.co/port=“7860”
LABEL huggingface.co/entrypoint=“uvicorn main:app --host 0.0.0.0 --port 7860”

However, the public URL still shows the default 404 HTML page:
:backhand_index_pointing_right: https://petsage-petsage-brain-v30.hf.space

Could you please check whether:

  1. The huggingface.co/port and huggingface.co/entrypoint labels were detected correctly, and

  2. The Space proxy mapping needs to be refreshed or reattached to port 7860?

Additional context:

  • This Space runs fine locally with docker run -p 7860:7860 petsage-v30http://localhost:7860 responds correctly.

  • There are no Python import or dependency errors in the logs.

  • The entrypoint (main:app) is valid and confirmed.

It looks like an internal routing mismatch on the Hugging Face proxy layer.
Could you please refresh the port mapping for this Space?

Thank you very much for your help!
Christian

1 Like

With just the minimal fix below, something somewhat GUI-like appeared.


Fix: set routing in the Space’s README and give / something to serve. Labels are ignored. No proxy “reattach” is required.

What’s happening

  • Docker Spaces read the runtime port and the initial URL from the README front-matter: sdk: docker, app_port, and optional base_path. They do not read LABEL huggingface.co/*. Default port is 7860. The Space loads / unless base_path is set. (Hugging Face)
  • FastAPI serves docs at /docs by default. If your app only exposes /api/v1/*, a request to / returns 404. The Space shows that 404. (FastAPI)

Minimal, reliable fix

A. Update README front-matter so the proxy targets 7860 and the iframe opens /docs instead of /:

---
sdk: docker
app_port: 7860
base_path: /docs
---

This is the supported configuration for Docker Spaces; base_path defines the initial URL the Space renders. Example Spaces set app_port and base_path the same way. (Hugging Face)

B. Optional FastAPI root handler if you prefer not to use base_path:

# FastAPI's Swagger UI lives at /docs by default
# docs: https://fastapi.tiangolo.com/tutorial/metadata/
from fastapi import FastAPI
from fastapi.responses import RedirectResponse

app = FastAPI()
@app.get("/", include_in_schema=False)
def root():
    return RedirectResponse("/docs")

This makes GET / return 302→/docs, eliminating the 404. (FastAPI)

Notes on your Dockerfile

  • Keep EXPOSE 7860.

  • Keep your uvicorn command. To be robust behind proxies you can add:

    --proxy-headers --forwarded-allow-ips="*"
    

    These flags make Uvicorn honor forwarded headers through the Space’s proxy. (Uvicorn)

  • Ignore the labels. Spaces routing is driven by the README (app_port, base_path) and your container’s CMD/ENTRYPOINT. (Hugging Face)

Verification checklist

  • Root now loads docs: GET https://petsage-petsage-brain-v30.hf.space/ → Swagger UI if you set base_path or added the redirect. FastAPI serves /docs by default. (FastAPI)
  • Health endpoint OK: GET /api/v1/health returns JSON 200.
  • Logs still show Uvicorn on 0.0.0.0:7860.
  • No change needed to Hugging Face proxy. The proxy already connects to app_port (default 7860). (Hugging Face)

Common pitfalls

  • Missing or wrong README front-matter. Docker Spaces require the YAML block; app_port is used only when sdk: docker is set there. Community threads and commits confirm that setting app_port in README fixes routing. (Hugging Face Forums)
  • Expecting Docker LABEL huggingface.co/port or huggingface.co/entrypoint to control routing. They don’t. Use README and your container’s CMD. (Hugging Face)

Quick template you can drop in

README.md

---
title: PetSage Brain v30
sdk: docker
app_port: 7860
base_path: /docs
---

Optional main.py addition

from fastapi.responses import RedirectResponse
@app.get("/", include_in_schema=False)
def root():
    return RedirectResponse("/docs")

Extra references

  • Docker Spaces guide and setup. (Hugging Face)
  • Spaces configuration reference for app_port and base_path. (Hugging Face)
  • FastAPI docs and OpenAPI endpoints (/docs, /openapi.json). (FastAPI)
  • Uvicorn proxy header handling. (Uvicorn)

Outcome: declare port and initial path in README or add a / route. Labels are ignored. After this, the Space root stops 404ing and your API is reachable at the public URL.