writing-skills
writing-skills
Use when creating new skills, editing existing skills, or verifying skills work before deployment
uvicornDeploy Python ASGI apps with Uvicorn. Use when a user asks to run FastAPI in production, configure an ASGI server, set up Gunicorn with Uvicorn workers, or optimize Python web server performance.
Independent GitHub snapshot · Automated classification · Original documentation governs
Uvicorn is a fast ASGI server for Python. It is the usual way to run FastAPI, Starlette, and Django ASGI apps. For multiple cores you can use Uvicorn's own --workers option, or Gunicorn as the process manager with the uvicorn-worker package (Uvicorn 0.54, checked October 2026, requires Python 3.10+).
pip install "uvicorn[standard]"
# Run with auto-reload (single process; --reload and --workers cannot be combined)
uvicorn app.main:app --reload --port 8000
Simplest option, Uvicorn's own supervisor:
uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4 --proxy-headers --forwarded-allow-ips 10.0.0.5
With Gunicorn (restarts workers that die, graceful reloads on SIGHUP). uvicorn.workers.UvicornWorker is deprecated; install the separate uvicorn-worker package and use uvicorn_worker.UvicornWorker:
pip install gunicorn uvicorn-worker
gunicorn app.main:app \
--workers 4 \
--worker-class uvicorn_worker.UvicornWorker \
--bind 0.0.0.0:8000 \
--timeout 120 \
--graceful-timeout 30 \
--access-logfile - \
--error-logfile -
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt # includes gunicorn and uvicorn-worker
COPY . .
# Non-root user
RUN adduser --system --uid 1001 app
USER app
# Production command
CMD ["gunicorn", "app.main:app", \
"--workers", "4", \
"--worker-class", "uvicorn_worker.UvicornWorker", \
"--bind", "0.0.0.0:8000", \
"--timeout", "120"]
# run.py — Uvicorn with programmatic config
import uvicorn
if __name__ == "__main__":
uvicorn.run(
"app.main:app",
host="0.0.0.0",
port=8000,
workers=4,
log_level="info",
access_log=True,
proxy_headers=True, # honour X-Forwarded-* (on by default)
forwarded_allow_ips="10.0.0.5", # only your proxy; default is 127.0.0.1
)
User request: "Run my FastAPI app from app/main.py in production on a 4-core box behind nginx."
uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 4 --proxy-headers --forwarded-allow-ips 127.0.0.1
curl -s http://127.0.0.1:8000/docs -o /dev/null -w "%{http_code}\n"
Expect 200. Four worker processes appear under one parent in ps.
User request: "Gunicorn warns that uvicorn.workers is deprecated, fix it."
pip install uvicorn-worker
gunicorn app.main:app -k uvicorn_worker.UvicornWorker -w 4 -b 127.0.0.1:8000
The deprecation warning is gone and requests are served as before.
uvicorn --reload (single process, auto-reload on file changes). Never use --reload in production.2 x cores + 1, which is advice for sync Gunicorn workers); measure, and mind the memory of each copy of your app.--forwarded-allow-ips to your proxy's address, not *: any trusted client can spoof X-Forwarded-For and the scheme.CMD so SIGTERM reaches it and shutdown is graceful.uvicorn[standard] for uvloop, httptools and websockets; plain uvicorn falls back to slower pure-Python parts.--workers with --reload.