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 optionalbase_path. They do not readLABEL huggingface.co/*. Default port is7860. The Space loads/unlessbase_pathis set. (Hugging Face) - FastAPI serves docs at
/docsby 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
uvicorncommand. 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://huggingface.co/proxy/petsage-petsage-brain-v30.hf.space/→ Swagger UI if you setbase_pathor added the redirect. FastAPI serves/docsby default. (FastAPI) - Health endpoint OK:
GET /api/v1/healthreturns 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_portis used only whensdk: dockeris set there. Community threads and commits confirm that settingapp_portin README fixes routing. (Hugging Face Forums) - Expecting Docker
LABEL huggingface.co/portorhuggingface.co/entrypointto 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_portandbase_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.