Published on · Updated on: · By Parth Kanpariya

- 7 min read

How to Deploy a Python App on Heroku in 2026 (Flask, Django, FastAPI)

img of How to Deploy a Python App on Heroku in 2026 (Flask, Django, FastAPI)

✨ Summarize this content with AI

Deploying a Python app on Heroku takes about 15 minutes if your project is structured correctly. This guide covers every step from installing the Heroku CLI to running your first production deployment, including Flask, Django, and FastAPI.

If you want to skip the manual config entirely, jump to the Kuberns section for a zero-config alternative.

What You Need Before You Start

  • A Python app (Flask, Django, FastAPI, or plain Python)
  • Git installed and your project in a repository
  • Heroku CLI installed
  • A Heroku account (paid plan required; no free tier)

Heroku runs on dynos. For a basic Python web app, you will need at minimum one Eco dyno ($5/month) and a database add-on if your app uses Postgres.

The Fastest Way to Deploy Python: Use Kuberns

Before the manual steps, here is a faster path.

Kuberns is an Agentic AI cloud platform that reads your Python project, detects whether you are running Flask, Django, or FastAPI automatically, installs your dependencies from requirements.txt, configures your WSGI server, and deploys your app with HTTPS and CI/CD enabled. No Procfile, no buildpack selection, no manual config vars to juggle.

Step 1: Connect Your GitHub Repo

Log in to dashboard.kuberns.com and click New Project. Connect your GitHub account and select the repository containing your Python app. Kuberns reads the codebase immediately.

Step 2: Let the AI Detect Your Stack

Kuberns automatically detects your Python framework from your project files. It identifies Flask from app.py and requirements.txt, Django from manage.py and settings.py, and FastAPI from your main module and uvicorn dependency. No buildpack selection, no Procfile required.

Step 3: Set Your Environment Variables

In the Kuberns dashboard, navigate to the Environment tab for your project. Add your environment variables one by one (for example, SECRET_KEY, DATABASE_URL, DEBUG). These are injected securely at runtime, exactly like Heroku Config Vars but without the CLI commands.

Step 4: Deploy

Click Deploy. Kuberns installs your dependencies, configures the WSGI or ASGI server based on your framework, builds the container, and pushes it live on AWS infrastructure. Your app is reachable at a live HTTPS URL in under five minutes.

Deploy Python with Kuberns

How to Deploy a Python App on Heroku

Step 1: Prepare Your Python Project

Your project needs four files before Heroku can run it.

requirements.txt lists every dependency:

   flask==3.0.3
gunicorn==22.0.0

For Django, add django, whitenoise, dj-database-url, and psycopg2-binary. For FastAPI, add fastapi, uvicorn[standard], and any other dependencies.

runtime.txt pins your Python version:

   python-3.12.9

Heroku supports Python 3.10, 3.11, 3.12, and 3.13 as of 2026. Omitting this file means Heroku picks the default, which may not match your local environment.

Procfile tells Heroku how to start your app. This file has no extension:

For Flask:

   web: gunicorn app:app

For Django:

   web: gunicorn yourproject.wsgi

For FastAPI:

   web: uvicorn main:app --host 0.0.0.0 --port $PORT

Replace app, yourproject, or main with the actual module name of your entry point.

.gitignore should at minimum exclude virtual environments and .env files:

   venv/
__pycache__/
*.pyc
.env

Step 2: Install and Log Into the Heroku CLI

Download the Heroku CLI and authenticate:

   heroku login

This opens a browser window for OAuth. Once complete, you are logged in for all CLI commands in that terminal session.

Step 3: Create a Heroku App and Push

   git init   # if not already a git repo
heroku create your-app-name
git add .
git commit -m "initial deploy"
git push heroku main

Heroku auto-detects the Python buildpack from your requirements.txt, installs dependencies, and boots your dyno. The output ends with a live URL like https://your-app-name.herokuapp.com.

If your default branch is master instead of main:

   git push heroku master

Step 4: Set Environment Variables

Never hard-code secrets or configuration in your source code. Use Heroku Config Vars instead:

   heroku config:set SECRET_KEY=your_secret_key_here
heroku config:set DEBUG=False
heroku config:set ALLOWED_HOSTS=your-app-name.herokuapp.com

You can also manage config vars from the Heroku dashboard under Settings > Config Vars. Config vars are injected as environment variables at runtime and accessible via os.environ.get('KEY').

Step 5: Add a Database (Heroku Postgres)

If your Python app needs PostgreSQL, provision the Heroku Postgres add-on:

   heroku addons:create heroku-postgresql:essential-0

This creates a Postgres database and sets a DATABASE_URL environment variable automatically. Essential-0 starts at $5/month with 1 GB storage.

For Django, read the database URL using dj-database-url:

   import dj_database_url
import os

DATABASES = {
    'default': dj_database_url.config(
        default=os.environ.get('DATABASE_URL'),
        conn_max_age=600,
        ssl_require=True
    )
}

Then run migrations:

   heroku run python manage.py migrate

For Flask with SQLAlchemy, read the connection string directly:

   import os
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL', '').replace('postgres://', 'postgresql://')

Heroku Postgres uses postgres:// in the URL, but SQLAlchemy requires postgresql://. The .replace() handles this automatically.

For a full breakdown of Heroku Postgres plans and costs, see the Heroku Postgres pricing and plans guide.

Step 6: Handle Static Files (Django)

Django does not serve static files through its development server in production. Add whitenoise to handle this on Heroku:

   pip install whitenoise

In settings.py:

   MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',  # add after SecurityMiddleware
    ...
]

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

Run heroku run python manage.py collectstatic after deployment to compile static files.

Step 7: View Logs and Debug

Check your app’s live logs:

   heroku logs --tail

If your app crashes on startup, this is the first place to look. Common errors:

  • H10 (App crashed): usually a bad Procfile or missing dependency in requirements.txt
  • R10 (Boot timeout): your app takes too long to start; Heroku kills it after 60 seconds
  • H14 (No web dynos running): scale up with heroku ps:scale web=1

Heroku Python Costs in 2026

A minimal production Python app on Heroku costs:

  • 1 Eco Dyno: $5/month (shared infrastructure, sleeps after 30 min inactivity)
  • 1 Basic Dyno: $7/month (always-on, no sleeping)
  • Heroku Postgres Essential-0: $5/month (1 GB)
  • Heroku Postgres Essential-1: $9/month (10 GB)

A real production setup (Basic dyno + Essential-1 Postgres) runs ~$16/month before any add-ons. For a detailed breakdown, see Heroku pricing explained.

Heroku vs Kuberns for Python Deployments

Heroku’s Python deployment works, but has real tradeoffs in 2026:

  • You write and maintain a Procfile for every project
  • Eco dynos sleep after 30 minutes of inactivity (cold starts)
  • No auto-scaling on lower-tier plans
  • Pricing adds up quickly with database and team add-ons
  • Python version management requires a separate runtime.txt

Kuberns removes these friction points:

  • Zero configuration: no Procfile, no buildpack selection. The AI reads your project and configures everything
  • Auto-detects your Python framework: Flask, Django, FastAPI, or plain WSGI
  • No cold starts: persistent containers on AWS infrastructure
  • Built-in CI/CD: push to GitHub and it deploys automatically
  • 40% lower cost on average compared to equivalent Heroku dyno configurations
  • Scales automatically based on traffic

Start a free Trial with Agentic AI Powered Deployment

Deploy on Kuberns

FAQ

Q: Can I deploy a Python app on Heroku for free?

Heroku removed its free tier in November 2022. The cheapest plan is an Eco dyno at $5/month plus a database add-on starting at $5/month. For free hosting, look at Railway or Render for limited hobby projects.

Q: What Python versions does Heroku support in 2026?

Heroku supports Python 3.10, 3.11, 3.12, and 3.13. Specify your version in runtime.txt (e.g., python-3.12.9). Older versions like 3.8 and 3.9 are no longer supported.

Q: What is a Procfile and is it required?

A Procfile is a plain text file in your project root that tells Heroku how to start your app. For most Python web apps it contains a web: line with your WSGI or ASGI server command. It is required for web processes on Heroku.

Q: How do I connect Heroku Postgres to a Python app?

Add the Heroku Postgres add-on: heroku addons:create heroku-postgresql:essential-0. Heroku sets a DATABASE_URL environment variable automatically. Read it in Python with os.environ.get('DATABASE_URL') or via dj-database-url for Django.

Q: How do I deploy a Django app to Heroku?

Install gunicorn and whitenoise, add a Procfile with web: gunicorn yourproject.wsgi, configure ALLOWED_HOSTS and STATIC_ROOT, set DEBUG=False via config vars, and push with git push heroku main. Run migrations with heroku run python manage.py migrate.

Q: How do I set environment variables on Heroku?

Use heroku config:set KEY=value from the CLI, or set them in the Heroku dashboard under Settings > Config Vars. Never commit .env files to your repository.

Q: What is the difference between Flask and Django deployment on Heroku?

Both use the same Git-based flow and Procfile. The main difference is the WSGI entrypoint: Flask uses web: gunicorn app:app, while Django uses web: gunicorn yourproject.wsgi. Django also needs whitenoise for static files and a database migration step.

Q: Is Heroku still a good choice for Python deployments in 2026?

Heroku is stable and reliable but more expensive than newer alternatives. If you want zero-config deployment with auto-detection of your Python stack, Kuberns is a strong alternative that skips the Procfile, buildpack, and dyno configuration entirely.