DEV Community

Cover image for Python app hosting: deploy Django, Flask and FastAPI
Yura Oak
Yura Oak

Posted on Originally published at lizard.build

Python app hosting: deploy Django, Flask and FastAPI

Python app hosting starts with the process your application needs to run. Django and Flask commonly use a WSGI server; FastAPI uses an ASGI server. A Celery worker or a scheduled script has another lifecycle. Choose a host that supports those processes, the database and the storage your app needs.

Lizard (lizard.build) publishes this guide. We checked the linked framework and provider documentation on 9 September 2026. The examples use explicit module names that you must adapt to your project.

Choose the runtime before the host

Application Production process Other requirements to check
Django with WSGI Gunicorn or another supported WSGI server Database, migrations, static files and uploads
Django with async features A supported ASGI server Connection handling and compatibility of the app's dependencies
Flask A production WSGI server App import path or factory, secrets and database
FastAPI Uvicorn or another ASGI server Startup tasks, concurrency and database connections
Celery worker A separate queue consumer Broker, result backend if used, retries and shutdown
Script or batch job A process that runs and exits Schedule, timeout, exit status and durable output

The development server is for development. See the official Django deployment guide, Flask production guide and FastAPI worker guidance.

Python hosting options by need

Host Why to consider it Check before choosing
Lizard Web services and workers with managed data services and CLI operations Runtime settings, database wiring and measured resource use
Railway Several services in a project All service consumption and plan credit
Render Published web and worker instance plans Separate database cost and free-service restrictions
PythonAnywhere A Python-focused hosting workflow WSGI/ASGI support, outbound access and task limits on your plan
Cloud Run HTTP services, jobs or worker pools Resource type, billing mode, concurrency and cold starts
Fly.io Machines in selected regions Machine sizing, storage and network charges
DigitalOcean App Platform Managed source or image deployment Build support, app components and database pricing
Heroku A familiar Python deployment workflow Current plan, add-ons and product direction
A VPS Direct server control Updates, process management, TLS, backups and recovery

Use the PaaS comparison for the wider hosting decision. A Python badge in a feature table is not enough to confirm worker or database support.

Free Python hosting needs a workload limit

A free plan may restrict outbound requests, sleep an inactive web process, limit task execution or include only a trial credit. Those terms can be fine for a demonstration and unsuitable for a webhook receiver or queue worker.

Check Render's free-service rules and PythonAnywhere's free-account features. For Cloud Run, the pricing page describes free usage alongside billable resources. A database, image registry or network usage may remain outside the allowance you are looking at.

Test the first request after a quiet period and confirm whether scheduled or background work still runs. Describe the free option in terms of those limits, not as unlimited hosting.

Build and start commands

For a project that uses requirements.txt, install its pinned dependencies with:

python -m pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Use the package manager and lockfile already in your repository if it uses uv, Poetry or another tool. Include the production server in the dependencies. Do not rely on a package installed only on your laptop.

For Django, where myproject/wsgi.py defines the application:

gunicorn myproject.wsgi:application --bind "0.0.0.0:${PORT:-3000}"
Enter fullscreen mode Exit fullscreen mode

For Flask, where app.py exports app:

gunicorn app:app --bind "0.0.0.0:${PORT:-3000}"
Enter fullscreen mode Exit fullscreen mode

For FastAPI, where main.py exports app:

uvicorn main:app --host 0.0.0.0 --port "${PORT:-3000}"
Enter fullscreen mode Exit fullscreen mode

These commands expect a shell to expand the port variable. A JSON-array Docker CMD does not expand it automatically. Either use the runtime's documented variable support, a shell wrapper, or a small program that reads the environment.

Set worker counts from measurements and available memory. More processes can use more memory and database connections; adding workers is not a substitute for checking a slow query or blocking task.

A minimal FastAPI container

For an application with main.py and a locked requirements.txt containing FastAPI and Uvicorn, this Dockerfile starts one server process:

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN useradd --create-home appuser
USER appuser
EXPOSE 3000
CMD ["sh", "-c", "exec uvicorn main:app --host 0.0.0.0 --port ${PORT:-3000}"]
Enter fullscreen mode Exit fullscreen mode

Choose a Python version compatible with your project. Put .env, local virtual environments, caches and Git data in .dockerignore. This example does not install extra operating-system packages; add only those your dependencies need.

On Lizard, you can bring a Dockerfile or use the source-build path. The deployment guide explains the options. Your app should expose a small health endpoint, and you should also test an endpoint that exercises its real dependencies.

A FastAPI deployment checked on Lizard

Our public FastAPI example has a dated deployment record from 9 September 2026. The test used commit df522c1, built from GitHub in eu-west-lim-a, with port 8000 and a Uvicorn start command in the Procfile. It used Python 3.13 with FastAPI 0.141.1 and Uvicorn 0.52.4. No manual build or start override was set.

The published check record reports six passing checks through the public HTTPS URL:

Request Observed result
GET /health HTTP 200 with {"status":"ok"}
GET /docs HTTP 200; API interface uses /openapi.json
GET /openapi.json HTTP 200; schema contains health and echo routes
POST /echo with a JSON object HTTP 200 with the same object
POST /echo with a JSON array HTTP 422 for the invalid body type
GET /no-such-route HTTP 404

Open the live health endpoint, try the API interface, or follow the FastAPI deployment guide.

These results cover deployment and HTTP behaviour for a small app without a database. They do not measure uptime, load capacity or end-to-end deployment time. The same record gives a CLI reading at 11:48 UTC of about 0.034 GB of memory and about $0.00051/hour in resource cost. That is a reading at one moment, not a monthly invoice; the quoted reading used the rates in effect at the time. Current Lizard hosting uses pay as you go with no monthly subscription; storage, traffic and payment fees can add to the total. The Dockerfile above is a separate example and does not reproduce that deployment's exact configuration.

Django, Postgres and Celery need separate checks

Connect Managed Postgres through the variable your Django settings read. Run migrations as a controlled release step, not independently in every web worker. Configure static-file handling and give uploaded files durable storage.

Run Celery as a separate service with the same relevant application code and its own start command. Configure the broker explicitly, for example with Managed Redis if your application uses Redis. Check retries, duplicate-task handling and shutdown before accepting production work.

For a server you operate yourself, use the Django VPS walkthrough. For a managed worker, see the worker deployment reference.

Estimate the whole Python application

Include web processes, workers, database, stored files, backups, transfer and the plan your team needs. Railway meters consumption and applies its paid plan toward usage. Render publishes instance plans. PythonAnywhere currently lists Developer at $10/month; check its included features against your app. Sources: Railway, Render, PythonAnywhere.

Lizard has no monthly subscription or per-service plan fee. For a small app averaging 0.01 vCPU and 0.1 GB of memory over 720 hours, with 10 GB of egress, resource charges total about $1.53 before payment fees and tax. Add the database, worker and storage your Python app needs. See the worked example and current rates. Purchased credits do not expire, so a quiet month does not require buying another plan.

FAQ

Can I host FastAPI on the same services as Django? Often, but FastAPI needs an ASGI server. Confirm the host supports your start command and any long-lived connections or workers the app uses.

Should I use runserver in production? No. Use a production WSGI or ASGI server and check the framework's deployment guidance.

Why does the host say my app is unhealthy? Check the build logs, process exit status, import path, bound interface and expected port. Then check missing variables and dependency connections.

Do I need a Dockerfile? Not on every host. A source builder can create the image, but you still need correct dependencies and a production start command.

What is the best host for a Python worker? One that supports the worker's lifecycle and dependencies. Test queue consumption, retries and restart behaviour; an HTTP-only deployment is not enough.


Originally published at Lizard (lizard.build).

Top comments (0)