tiangolo's Uvicorn Gunicorn FastAPI Docker image is deprecated, and the README says why
Docker image with Uvicorn managed by Gunicorn for high-performance FastAPI web applications in Python with performance auto-tuning.
At a glance
- What is it?
- The image that auto-tuned Gunicorn workers around Uvicorn is now a historical document. Its author points readers at a plain Uvicorn command line and a hand-written Dockerfile instead.
- Who is it for?
- This repository is worth reading as a record of a design decision that has since been folded into Uvicorn, not as something to deploy. Gunicorn was doing two jobs, supervising worker processes and restarting dead ones, and the README says Uvicorn now handles subprocesses including restarts, which removes the reason the image existed.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 26 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A deprecation notice that opens the README
The first thing the README says is that the Docker image is deprecated and that there is no need to use it, because Uvicorn can be used with `--workers` directly. That is the entire current recommendation. Everything after it, including a section labelled Legacy Docs that the README says is kept for historical reasons, is archaeology.
There is a small tension in the repository worth naming rather than smoothing over. GitHub reports the last push on 2026-09-11, so commits are still landing, and the project description still advertises a Docker image for high-performance FastAPI applications with performance auto-tuning. The README describes a project that has decided to stop being that. Both statements are in the repository at once, and the README is the one written in the first person by the author, so it is the one to plan around. The last release, 0.8.0, was published on 2024-03-18, which is a more reliable signal of where the software line ended than the description is.
What auto-tuning actually meant
The mechanism the image added was a start-up script that chose a number of worker processes based on the CPU cores available on the machine it landed on. The README describes it as setting a sensible configuration based on the server it is running on without making sacrifices, with sensible defaults that could be overridden by environment variables or by replacing the configuration files.
Release 0.6.0 from 2020 is where that surface is documented in most detail, and it lists the variables the image exposes: `WORKER_CLASS`, `TIMEOUT`, `KEEP_ALIVE`, `GRACEFUL_TIMEOUT`, `ACCESS_LOG`, `ERROR_LOG`, `GUNICORN_CMD_ARGS` and `MAX_WORKERS`. A later release added a documented `PRE_START_PATH` hook. Two things follow from that list. The first is that the tuning surface was real, which is why the image was popular: a team deploying to an unknown container size did not have to decide worker counts. The second is that most of those variables were Gunicorn concerns, not FastAPI concerns, which is the thread the deprecation pulls.
The two jobs Gunicorn was doing, and which one disappeared
The Technical Details section is the real explanation, and it is short. Uvicorn did not have support for managing worker processes, including restarting dead workers. Gunicorn could be used as a process manager running Uvicorn workers, and that added complexity which is no longer necessary.
That is the whole argument. Split it in two and the decision follows. FastAPI is an ASGI application, so it needs an ASGI server, and Uvicorn supplies one. Multi-process supervision is orthogonal to that, and Gunicorn supplied it. Once Uvicorn grew its own subprocess handling with restart of dead workers, the second reason to run Gunicorn disappeared, and an image whose entire value proposition was tuning that second layer had nothing left to tune. The image was also layered on another image, `tiangolo/uvicorn-gunicorn`, which the README says is what actually does all the work. The FastAPI image just installed FastAPI and the documentation.
What the README tells you to write instead
The replacement is a Dockerfile with one command in it. The README gives it in full, and it is a reasonable starting point for any FastAPI service rather than a trick:
FROM python:3.11
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80"]The advice attached to it is about cluster replication rather than about the Dockerfile itself. If you run Kubernetes, Docker Swarm Mode or Nomad, the README says you probably do not want a process manager inside each container at all, because replication is better handled at the cluster level. Handling scaling twice, once with a process manager and once with the scheduler, is the situation the author is warning against.
When you do want several workers in one container, the change is a single flag on the same command:
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "80", "--workers", "4"]The CPU core counting that the image used to do is not reproduced here. Nothing in the replacement runs a start-up script to guess a number, which means the responsibility moves to whoever writes the Dockerfile or sets the orchestrator's replica count.
Supported tags, dropped tags and the pinning story
The tag table is still maintained and is more informative than the deprecation notice, because it draws a line between what exists and what is frozen. Supported at the end of the README's list are `python3.11` as `latest`, `python3.10`, `python3.11-slim` and `python3.10-slim`, each with a Dockerfile link in the `docker-images/` directory.
Everything else is on a separate list of deprecated tags that the README says are no longer supported or maintained and have been removed from the GitHub repository, though the last pushed versions may still be in Docker Hub: `python3.9`, `python3.8`, `python3.7`, `python3.6` and the Alpine variants of each. For those, the README publishes final date tags, which is unusually helpful if you are auditing what a running deployment is actually pinned to. `python3.9` stopped at `python3.9-2025-11-09`, `python3.8` at `python3.8-2024-11-02`, and `python3.6` back at `python3.6-2022-11-25`.
Pinning by build date is the practice the README recommends for anyone who needs a fixed version, using the form `tiangolo/uvicorn-gunicorn-fastapi:python3.11-2024-11-02`. One caveat is implied rather than stated: the repository description promises auto-tuning and current pushes suggest ongoing commits, but a deprecation notice at the top of the README means new tags should not be expected. Build a tag yourself if you need one.
A performance argument built on third-party benchmarks
The Description section makes the case for FastAPI itself rather than for the image, resting on TechEmpower benchmark results that the README links to and describes as third-party measurements showing FastAPI among the best performing Python web frameworks, thanks to being built on Starlette. It goes on to claim performance on par with, and in many cases superior to, Go and Node.js frameworks.
Those are claims about the framework, and they are the kind of claim worth handling carefully: benchmark numbers depend on the test, the run and the hardware behind the linked run ID, and the README itself points outward for the methodology rather than presenting it. Nothing in the repository contains a benchmark harness of its own, and the `tests/` directory in the tree is described in the README's badge as a workflow test rather than a performance suite.
So the honest reading is that the image's performance story was inherited from FastAPI and Starlette rather than created by the image. What the image contributed was process management, and process management is exactly the part that has been absorbed upstream. That is a fair reason for a project like this to end, and it is a more interesting artifact as a worked example of container process supervision than as a base image.
Editorial conclusion
This repository is worth reading as a record of a design decision that has since been folded into Uvicorn, not as something to deploy. Gunicorn was doing two jobs, supervising worker processes and restarting dead ones, and the README says Uvicorn now handles subprocesses including restarts, which removes the reason the image existed. For a new FastAPI container, the Dockerfile in the README is the artifact to copy and the only variable worth tuning is the worker count. If you are still pinned to an older release where Uvicorn had no process supervision, the deprecated tags in Docker Hub are documented with their final date stamps, and `python3.11` is the newest tag the project maintained.
Frequently asked questions
Can I use Gunicorn with FastAPI?
Yes, and the README explains why the project's own image did exactly that. Gunicorn acted as a process manager running Uvicorn workers, because Uvicorn used to lack support for managing worker processes and restarting dead ones. The README states that this added complexity is no longer necessary, since Uvicorn now handles subprocesses itself.
Should I use Uvicorn with FastAPI?
For this project's own recommendation, yes. The README deprecates the Docker image and points at Uvicorn with the `--workers` option instead, and suggests building an image from scratch if you need multiple workers in a single container. If you already run a scheduler such as Kubernetes, it suggests running a single Uvicorn process and letting the cluster handle replication.
Can I run FastAPI on Uvicorn?
Yes. FastAPI is an ASGI application and Uvicorn is an ASGI server, so the launch command in the README's replacement Dockerfile is a plain `uvicorn app.main:app` invocation with `--host` and `--port` arguments. Adding `"--workers", "4"` to that command gives multiple workers in one container.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/tiangolo-uvicorn-gunicorn-fastapi-docker)