Skip to main content

Flask: Deploying to Heroku

Flask: Deploying to Heroku

Deploying a Flask application to Heroku, a cloud Platform as a Service (PaaS), enables developers to host web applications with minimal infrastructure management. Built on Flask’s lightweight core with Jinja2 Templating and Werkzeug WSGI, Flask applications integrate seamlessly with Heroku’s deployment pipeline, leveraging Git, virtual environments, and configuration files. This tutorial provides a step-by-step guide to deploying a Flask app to Heroku, covering setup, configuration, and best practices for secure and scalable deployments. Note: Heroku’s free tier was deprecated in November 2022, so a paid plan (e.g., Eco or Basic dynos) is required.[](https://www.codecademy.com/article/deploying-a-flask-app)[](https://danblevins.medium.com/step-by-step-creating-a-flask-app-and-deploying-it-to-heroku-83350be5f8b)


01. Why Deploy to Heroku?

Heroku simplifies deployment by abstracting server management, allowing developers to focus on application logic. It supports Python applications through language-specific buildpacks, automatic scaling, and add-ons like PostgreSQL. Flask’s compatibility with Heroku’s Python buildpack, combined with its reliance on Werkzeug WSGI for request handling and Jinja2 Templating for rendering, makes it ideal for rapid deployment of web apps and APIs.[](https://blog.appsignal.com/2023/12/06/how-to-deploy-a-python-flask-app-with-heroku.html)[](https://blog.nextideatech.com/deploy-flask-on-aws-heroku/)

Example: Simple Flask App for Deployment

# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Hello, Heroku!'

if __name__ == '__main__':
    app.run()

Explanation:

  • A minimal Flask app to test deployment.
  • Serves as the base for Heroku setup.

02. Prerequisites

Before deploying, ensure the following are installed and set up:

  • Python 3.10 or newer: Install from python.org or use pyenv.
  • [](https://devcenter.heroku.com/articles/getting-started-with-python)
  • Git: Install from git-scm.com for version control and deployment.
  • [](https://blog.nextideatech.com/deploy-flask-on-aws-heroku/)
  • Heroku CLI: Install from Heroku Dev Center to manage apps.
  • [](https://devcenter.heroku.com/articles/getting-started-with-python)
  • Heroku Account: Sign up at heroku.com. A paid plan is required due to the free tier deprecation.
  • [](https://geekyhumans.com/how-to-deploy-flask-api-on-heroku/)[](https://www.codecademy.com/article/deploying-a-flask-app)

03. Step-by-Step Deployment Guide

Follow these steps to deploy a Flask application to Heroku, ensuring secure and efficient configuration.

3.1 Create and Set Up the Flask Application

Example: Project Setup

# Create project directory and virtual environment
mkdir flask-heroku-app
cd flask-heroku-app
python3 -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\activate  # Windows

# Install Flask and Gunicorn
pip install flask gunicorn
pip freeze > requirements.txt

requirements.txt (Generated):

Flask==3.0.3
gunicorn==22.0.0
Jinja2==3.1.4
Werkzeug==3.0.4
...

Explanation:

  • venv: Isolates dependencies.
  • [](https://devcenter.heroku.com/articles/getting-started-with-python)
  • gunicorn: A production WSGI server required by Heroku (Flask’s development server is unsuitable).
  • [](https://realpython.com/flask-by-example-part-1-project-setup/)[](https://medium.com/the-andela-way/deploying-your-flask-application-to-heroku-c99050bce8f9)
  • requirements.txt: Lists dependencies for Heroku’s Python buildpack.
  • [](https://devcenter.heroku.com/articles/getting-started-with-python)

3.2 Create a Procfile

Example: Procfile

# Procfile (no file extension)
web: gunicorn app:app

Explanation:

  • Procfile: Instructs Heroku to run the app using Gunicorn.
  • [](https://realpython.com/flask-by-example-part-1-project-setup/)
  • app:app: Refers to the module (app.py) and Flask app instance (app). Adjust if your file or instance name differs.
  • [](https://medium.com/the-andela-way/deploying-your-flask-application-to-heroku-c99050bce8f9)

3.3 Specify Python Runtime

Example: runtime.txt

# runtime.txt
python-3.12.7

Explanation:

  • Specifies the Python version (e.g., 3.12.7). Check supported versions at Heroku Dev Center.
  • [](https://www.geeksforgeeks.org/deploy-python-flask-app-on-heroku/)

3.4 Initialize Git Repository

Example: Git Setup

git init
git add .
git commit -m "Initial Flask app commit"

Explanation:

  • Heroku uses Git for deployment. Initialize a repository and commit files.
  • [](https://geekyhumans.com/how-to-deploy-flask-api-on-heroku/)

3.5 Create and Deploy to Heroku

Example: Heroku Deployment

# Login to Heroku
heroku login

# Create Heroku app
heroku create my-flask-app

# Push code to Heroku
git push heroku main

# Open app in browser
heroku open

Explanation:

  • heroku create: Creates an app with a unique URL (e.g., https://my-flask-app.herokuapp.com).
  • [](https://danblevins.medium.com/step-by-step-creating-a-flask-app-and-deploying-it-to-heroku-83350be5f8b)
  • git push heroku main: Deploys the code.
  • [](https://mattermost.com/blog/deploying-a-web-app-with-python-flask-and-heroku/)
  • heroku open: Opens the app in your browser.
  • [](https://mattermost.com/blog/deploying-a-web-app-with-python-flask-and-heroku/)

3.6 Configure Environment Variables

Example: Setting Environment Variables

# app.py (Updated)
from flask import Flask
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-secret')

@app.route('/')
def index():
    return f'Secret: {app.config["SECRET_KEY"]}'

if __name__ == '__main__':
    app.run()

Heroku CLI Command:

heroku config:set SECRET_KEY='my-secure-key'

Explanation:

  • heroku config:set: Sets environment variables on Heroku for sensitive data.
  • [](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xviii-deployment-on-heroku)
  • Access variables with os.environ.get to avoid hardcoding.
  • [](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xviii-deployment-on-heroku)

3.7 Add PostgreSQL Database (Optional)

Example: PostgreSQL Setup

# Add PostgreSQL add-on
heroku addons:create heroku-postgresql:mini

Updated app.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)

@app.route('/')
def index():
    return 'Database connected!'

if __name__ == '__main__':
    app.run()

Update requirements.txt:

pip install psycopg2-binary flask-sqlalchemy
pip freeze > requirements.txt

Explanation:

  • Heroku provides PostgreSQL via add-ons. DATABASE_URL is automatically set.
  • [](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xviii-deployment-on-heroku)
  • psycopg2-binary: Enables SQLAlchemy to connect to PostgreSQL.
  • [](https://medium.com/the-andela-way/deploying-your-flask-application-to-heroku-c99050bce8f9)

3.8 Common Deployment Issues

Example: Missing Procfile

remote: ! Warning: Your application is missing a Procfile.

Solution:

echo "web: gunicorn app:app" > Procfile
git add .
git commit -m "Add Procfile"
git push heroku main

Explanation:

  • Ensure Procfile exists and has no extension.
  • [](https://pybit.es/articles/deploy-flask-heroku/)
  • Check logs with heroku logs --tail for errors.
  • [](https://pybit.es/articles/deploy-flask-heroku/)

04. Best Practices for Heroku Deployment

  • Use Environment Variables: Store sensitive data (e.g., SECRET_KEY, API keys) with heroku config:set.
  • [](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xviii-deployment-on-heroku)
  • .gitignore: Exclude venv/, .env, and other local files.
  • # .gitignore
    venv/
    .env
    *.pyc
    
  • Eco Dynos: Use Eco dynos for low-cost deployment, but note they sleep after 30 minutes of inactivity, causing a delay on the first request. Upgrade to Basic or Standard for no sleep.
  • [](https://devcenter.heroku.com/articles/getting-started-with-python)
  • Automatic Deploys: Connect to GitHub for automatic deployments on code pushes.
  • [](https://blog.appsignal.com/2023/12/06/how-to-deploy-a-python-flask-app-with-heroku.html)
  • Logging: Monitor with heroku logs --tail for debugging.
  • [](https://pybit.es/articles/deploy-flask-heroku/)

4.1 Comprehensive Example

Example: Full Flask App with PostgreSQL

# app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-secret')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)

@app.route('/')
def index():
    users = User.query.all()
    return f'Users: {[user.username for user in users]}'

if __name__ == '__main__':
    app.run()

Procfile:

web: gunicorn app:app

runtime.txt:

python-3.12.7

Deployment Commands:

heroku login
heroku create my-flask-app
heroku addons:create heroku-postgresql:mini
heroku config:set SECRET_KEY='my-secure-key'
git add .
git commit -m "Deploy with PostgreSQL"
git push heroku main
heroku open

Explanation:

  • Combines environment variables, PostgreSQL, and Gunicorn for a production-ready app.
  • Deployed with a single git push.
  • [](https://mattermost.com/blog/deploying-a-web-app-with-python-flask-and-heroku/)

05. Common Use Cases

5.1 Deploying a Web Application

Example: Web App with Templates

# app.py
from flask import Flask, render_template
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-secret')

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run()

templates/index.html:

<!DOCTYPE html>
<html>
<head><title>Flask on Heroku</title></head>
<body><h1>Welcome to my Flask app!</h1></body>
</html>

Explanation:

  • Uses Jinja2 Templating for dynamic rendering.
  • Deployed following the same steps above.

5.2 Deploying an API

Example: Flask API

# app.py
from flask import Flask, jsonify
import os

app = Flask(__name__)
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'default-secret')

@app.route('/api/data')
def data():
    return jsonify({'message': 'Hello from Flask API!'})

if __name__ == '__main__':
    app.run()

Explanation:

  • Deploys a RESTful API with JSON responses.
  • [](https://jtemporal.com/deploy-flask-heroku-en/)
  • Follows the same deployment process.

Conclusion

Deploying Flask applications to Heroku, powered by Jinja2 Templating and Werkzeug WSGI, streamlines the process of making web apps and APIs publicly accessible. Key takeaways:

  • Use Procfile, requirements.txt, and runtime.txt for Heroku compatibility.
  • Leverage environment variables for secure configuration.
  • Integrate PostgreSQL for scalable database needs.
  • Monitor logs and use Eco dynos for cost-effective deployment.

By following these steps and best practices, developers can deploy robust Flask applications to Heroku efficiently, ensuring scalability and ease of maintenance.[](https://blog.appsignal.com/2023/12/06/how-to-deploy-a-python-flask-app-with-heroku.html)[](https://mattermost.com/blog/deploying-a-web-app-with-python-flask-and-heroku/)

Comments