uwsgi-nginx-flask-docker: deprecated, and the Python ceiling is fixed at 3.12
Docker image with uWSGI and Nginx for Flask applications in Python running in a single container.
At a glance
- What is it?
- This image bundles a Flask application, an application server and a web server in one container, and the first line of its readme says it is deprecated. The rest of the page is unusually honest about why: if you run a container scheduler you are replicating twice, the application server is in maintenance mode, and new interpreter versions will not be added. The useful parts left are the replacement it hands you and a warning about old tags.
- Who is it for?
- Keep this image if you have an existing Flask deployment on it and want a stable thing to run while you migrate, and do not start anything new on it, because the newest interpreter it will ever ship is the current one and the application server inside it is in maintenance mode. Three things to do.
- Can I use it commercially?
- Yes. Apache-2.0 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 12 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 October 4, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The first thing on the page is an instruction not to use it
A deprecation banner opens the readme, above the badges and above the tag list, and it is not a footnote. The image runs a Flask application behind a process manager and a web server inside a single container, and the warning says that if you are running a container orchestrator or something similar you probably do not need this image, or any comparable base image, and that you are better off building your own from scratch. The reasoning given is specific rather than fashionable. This image starts several worker processes inside each container, and if your scheduler already replicates containers across machines, you are doing the same job twice and the two layers will fight over your connection limits. Two further facts sit directly underneath. The application server it runs is stated to be in maintenance mode, with a pointer to its own documentation. And the author says, in the first person, that they have not used this image in years and have little bandwidth to keep it current, with most of their time going to a different framework.
Three maintained interpreters, and a promise that no fourth will arrive
The tag table lists three maintained interpreters, each with a link to its own Dockerfile in a directory in the repository, and the newest of the three is also the one aliased to latest. Below that, six deprecated tags are named, the oldest of them a Python 2.7 image. Then comes the sentence that closes the roadmap: the author will not be adding, and maintaining, support for new versions of Python. So the useful life of this image is bounded by the newest interpreter it already ships, and that boundary is stated rather than implied. The framing offered alongside it is that you can probably keep using the image as-is while you migrate to a different tool, which makes this a freeze rather than a shutdown. In practice that means two different decisions for two different people. Somebody with an image in production is choosing when to migrate. Somebody starting fresh is choosing a fixed interpreter target, and there is a better-documented path for them sitting on the same page.
Withdrawn tags are gone from the repository and still pullable from the registry
This is the sharpest operational sentence in the whole page, and it is easy to skim. The deprecated tags are described as no longer supported or maintained, and as removed from the GitHub repository, with the explicit qualification that the last versions pushed might still be available in the registry if anyone has been pulling them. Removing a tag from source control and removing an image from a container registry are two different operations, and only the first has happened here. Each withdrawn version also has a final dated tag recorded on the page, so you can see exactly how old each one is, with the Python 2 and Python 3.6 entries both dated to the same day in late 2022. Nothing about this is unusual for a public registry, and nobody is claiming it is a mistake. It is simply the fact that determines what you are running when you pull an old tag, and it belongs in the head of anyone auditing a deployment that has been up for years.
Releases and image builds are on two different clocks
Put two dates side by side. The newest release on the repository is from early 2024. The final dated tag for the newest withdrawn interpreter is from late 2025. So images were still being built and pushed for a Python version whose tag had already been retired, roughly eleven months after the last release was cut. That tells you the registry, not the release page, is where this project ships. The page confirms it: there is a tag for every build date, and if you want to pin the image you pick one of those, with an example given from 2019. So the artefact you deploy is chosen in a registry interface, while the version history a reader expects to consult lives on a release page that stopped moving earlier. There is a third place as well, a hand-written release notes file in the repository root. Three changelogs, and the one that determines what you actually run is none of them.
The replacement it recommends is two files you can paste
The page does not merely tell you to migrate, it hands you the destination. First a configuration file for a mainstream application server, which sets the log level, sends error output to standard error and access logs to standard output, points worker temporary files at shared memory, sets the graceful timeout and the hard timeout to the same value, and sets a keep-alive and a thread count. Second, a file that builds from a plain interpreter image:
FROM python:3.12
WORKDIR /code
COPY ./requirements.txt /code/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
COPY ./app /code/app
CMD ["gunicorn", "--conf", "app/gunicorn_conf.py", "--bind", "0.0.0.0:80", "app.main:app"]The shared-memory line is the one worth keeping whatever you do, because it is the standard fix for a container whose temporary filesystem is too small for worker scratch files, and you only learn to need it by hitting it. The single-process command is the other half of the argument: one process per container, replication handled above it, which is exactly what the deprecation notice asked for.
Everything below the notice is labelled historical
A heading announces that the remainder of the readme is preserved mainly for historical reasons, and then several hundred words of instructions follow: how to use the image as a base for another image, a quick start, a section for single page applications, and further material that is cut off here. The quick start is still worth reading, because it shows the two constraints the image imposes on you. The application object has to be given a particular name, because the server looks for it, and the development server call in the example enables the debugger, binds to all interfaces and listens on port 80, carrying a comment that says it is only for debugging while developing. The build and run commands are then two lines each, and the page describes the result as an optimized server, which is worth holding lightly in mind when the image itself is deprecated. The example also assumes a file layout of exactly one application directory and one file, which is the simplest thing that works and the only thing this image supports well.
Seven files at the root and no application code among them
The repository holds a licence file, the readme, a directory of per-version Dockerfiles, a tests directory, a release notes file and the usual metadata. There is no Python source in it, no web server configuration and no application server configuration, because the image is assembled on top of a separate base image that already contains both of those, and this repository's contribution is the layer that adds an interpreter and your application on top. That is also why the instructions open by telling you that you do not have to clone the repository at all: you consume the published image and write one small file of your own. It has one uncomfortable consequence for a deprecated image. The behaviour you are trusting is not here to read. You can see the file for each interpreter, and you can see the replacement it recommends, but the running configuration lives in an image you would have to pull and inspect, which for something you are being advised to migrate off is a poor place to be auditing from.
Editorial conclusion
Keep this image if you have an existing Flask deployment on it and want a stable thing to run while you migrate, and do not start anything new on it, because the newest interpreter it will ever ship is the current one and the application server inside it is in maintenance mode. Three things to do. Plan the migration path now, because the page hands you a complete replacement in a configuration file and a from-scratch file rather than asking you to invent one. Pin by build-date tag rather than by version, since the registry carries a tag for every build and that is the channel the page tells you to use. And audit what you are pulling by tag, because the withdrawn tags are stated to be gone from source control while the last images pushed may still be sitting in the registry. The default branch was last pushed on 2026-09-22, so the deprecation notice itself is being maintained even though nothing new is being added to the image.
Frequently asked questions
Can I use Flask on Docker?
Yes, and this image existed for exactly that. Its current advice, though, is that if you use any container orchestrator you should build a plain image from an official interpreter, install your requirements, copy your application and run a single process, with a from-scratch example provided. The page describes that arrangement as an optimized server and the bundled arrangement as deprecated.
What is the use of nginx in Docker?
The page does not generalise about it. In this image a web server and an application server sit in the same container, which is described as a common way to deploy Python web applications, and that arrangement is what the deprecation notice tells you to stop using when a scheduler is available, on the grounds that the container already runs several worker processes and the scheduler is already replicating containers.
Is flask asgi or WSGI?
The page never discusses the interface, so it is not a source for that. What it does show is how the application is started: a configuration file for an application server plus a command naming a module and an object, which is the convention for the framework this image serves, in both the deprecated image and the from-scratch replacement the page recommends.
Is Flask a backend or frontend?
Not a question this repository addresses; it treats the framework as the server-side web application the image is built to serve, alongside an application server and a web server in one container. The page's one piece of architecture guidance is about deployment shape, not about which side of a request the framework sits on: use one process per container and let a scheduler replicate, or use this image and let the process manager do it.
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-uwsgi-nginx-flask-docker)