
Last Updated: July 5, 2026
We are happy to announce first-class support for Python web applications on Probo.CI. Whether you are running Django, Flask, FastAPI, or a hand-rolled WSGI app, you can now spin up a full, ephemeral environment for every pull request - database and all - with a handful of lines in your .probo.yaml.
If you have used our PHP builds, you know we ship a separate image per PHP version. Python takes a different approach. Rather than maintaining a matrix of images, a single Python image can build any version of Python on demand using pyenv - exactly the way our Node.js image uses nvm.
Ask for "3.12" and Probo installs the latest 3.12.x. Need to reproduce a specific issue? Pin "3.12.7" and you will get precisely that. If the requested interpreter is not already baked into the image, pyenv compiles it for you at build time. No image juggling, no waiting on us to publish a new tag.
Here is everything you need to get a Python application building and serving:
1 2 3 4 5 6 7 8 9 10 11 12 13 | type: python python: "3.12" database: postgres:18 steps: - name: Setup Python Web Site plugin: PythonApp subDirectory: app environment: DB_DATABASE: my_database DB_USERNAME: my_user DB_PASSWORD: my_password DB_HOSTNAME: my_hostname |
At build time Probo installs the requested Python, creates a virtual environment, installs your dependencies from requirements.txt, and starts your application. nginx reverse-proxies the public build hostname to your app on 127.0.0.1:8000, so your application only needs to listen on that address. The default configuration already does this for you.
The PythonApp plugin is opinionated where it can be and configurable where it counts. Out of the box it will:
app subdirectory (override with subDirectory).python -m venv .venv && .venv/bin/pip install -r requirements.txt..venv/bin/gunicorn --daemon --bind 127.0.0.1:8000 app:app.Every one of those defaults is a knob you can turn. Using poetry or uv instead of pip? Override buildCommand. Running an async framework like FastAPI or Starlette? Point runCommand at an ASGI server such as uvicorn:
1 2 3 4 5 | steps: - name: Setup Python Web Site plugin: PythonApp buildCommand: python -m venv .venv && .venv/bin/pip install -r requirements/production.txt runCommand: .venv/bin/uvicorn main:app --host 127.0.0.1 --port 8000 |
The only hard rule is that your runCommand must listen on 127.0.0.1:8000 so nginx can proxy to it.
A web app is rarely just code. Python builds can use any of our available databases to store their data, and if you do not specify one, Probo provisions PostgreSQL by default - the natural fit for most Python stacks. You can also attach Solr for search.
Here is a Python build pinned to a version, backed by MySQL, and wired up to a Solr core:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | type: python python: "3.12" database: mysql:8.4 assets: - solr8.zip solr: name: solr version: 8 core_archive: solr8.zip core_folder: MyApp8 compression: zip steps: - name: Setup Python Web Site plugin: PythonApp subDirectory: app |
The only things you cannot bundle into a Python build are php and dotnet - everything else in the Probo toolbox is fair game.
Full documentation, including every plugin option and its defaults, lives on the Python Usage & Configuration page. Drop a type: python block into your .probo.yaml, push a branch, and watch a live environment come up for your next pull request.

When you sign up for a Probo.CI registration code, you will get a two week trial of the plan of your choosing. For more information on how to get started, click here .
LEARN MORE ABOUT PROBO.CI'S PRICING