Flask is a lightweight Python web framework that lets you spin up a functional web app with just a few lines of code. Pair it with Heroku—a cloud platform that abstracts away server management—and you have a powerful, beginner‑friendly deployment pipeline. In this guide we’ll walk through every step, from setting up your development environment to pushing a live Flask app to Heroku. By the end you’ll have a fully operational site and a solid understanding of the tools that make it happen.
What You'll Need
- Python 3.9+ installed locally
- Git version control
- A free Heroku account
- Heroku CLI installed on your machine
- Basic knowledge of the command line and virtual environments
Step 1: Set Up Your Local Development Environment
First, create a dedicated project folder and initialise a Git repository. Open a terminal and run:
mkdir flask-heroku-demo
cd flask-heroku-demo
git init
Next, set up a Python virtual environment to keep dependencies isolated:
python -m venv venv<brsource venv/bin/activate # On Windows use: venvScriptsactivate
With the environment active, install Flask:
pip install Flask
Verify the installation by checking the version:
python -c "import flask; print(flask.__version__)"
If you see a version number (e.g., 2.3.2) you’re ready to write code.
Step 2: Create a Minimal Flask Application
Create a file named app.py and paste the following code:
from flask import Flask, render_template<brapp = Flask(__name__)<br
@app.route('/')
def home():
return render_template('index.html')<br
if __name__ == '__main__':
app.run(debug=True)
Now create a templates folder and add index.html inside it:
mkdir templates
touch templates/index.html
Open templates/index.html and add a simple HTML page:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='UTF-8'>
<title>Flask on Heroku</title>
</head>
<body>
<h1>Hello, Heroku!</h1>
<p>Your Flask app is up and running.</p>
</body>
</html>
Run the app locally to make sure everything works:
python app.py
Visit http://127.0.0.1:5000 in your browser—you should see the greeting.
Step 3: Add a Requirements File and Procfile
Heroku needs two special files to know how to build and run your app.
requirements.txt lists every Python package your project depends on. Generate it with:
pip freeze > requirements.txt
Open requirements.txt and confirm it contains at least Flask and gunicorn. If gunicorn is missing, add it:
pip install gunicorn requirements.txt
Procfile tells Heroku which command starts your web server. Create it in the project root with a single line:
echo web: gunicorn app:app > Procfile
This tells Heroku to launch gunicorn and look for the Flask app object inside app.py.
Step 4: Configure the Application for Production
During local development you likely used debug=True. For production you should disable debug mode and let Heroku set the port dynamically. Update the bottom of app.py:
if __name__ == '__main__':
app.run(debug=False, host='0.0.0.0', port=int(os.getenv('PORT', 5000)))
Don’t forget to import os at the top:
import os
This change ensures the app respects the PORT environment variable that Heroku provides.
Step 5: Initialise a Git Repository and Commit Your Code
Heroku deploys directly from a Git repository, so make sure everything is committed:
git add .<brgit commit -m 'Initial Flask app with Heroku configuration'
If you see a warning about an empty commit, double‑check that .gitignore isn’t excluding essential files like requirements.txt or Procfile.
Step 6: Deploy to Heroku
First, log in to the Heroku CLI:
heroku login
This opens a browser window for authentication. After you’re logged in, create a new Heroku app:
heroku create flask-heroku-demo-$(date +%s)
The command returns a URL (e.g., https://flask-heroku-demo-1234567890.herokuapp.com/) and a Git remote named heroku. Push your code:
git push heroku main
If your default branch is master, replace main with master. Heroku will install dependencies, compile the slug, and start the web dyno using the Procfile command.
Once the push finishes, open the live site:
heroku open
You should see the same “Hello, Heroku!” page you tested locally, now served from the cloud.
Common Mistakes to Avoid
1. Forgetting gunicorn in requirements.txt:
Heroku uses gunicorn as the production WSGI server. If it’s missing, the dyno will crash with a ModuleNotFoundError.
2. Hard‑coding the port:
Heroku assigns a random port via the PORT env variable. Binding to 5000 will cause a “Application Error”. Use the os.getenv('PORT', 5000) pattern shown earlier.
3. Committing the virtual environment:
Never push the venv folder to Git. Add it to .gitignore to keep the repo clean and the slug size small.
4. Not setting a runtime.txt (optional):
If you need a specific Python version, create runtime.txt with a line like python-3.11.5. Without it, Heroku defaults to the latest stable version, which may differ from your local environment.
5. Ignoring build logs:
When git push heroku fails, the CLI prints error messages. Common culprits are missing dependencies or syntax errors. Review the logs rather than guessing.
Tips and Tricks
Use a .env file for local secrets: Store API keys or database URLs in a .env file and load them with python-dotenv. Remember to add .env to .gitignore and set the same variables in Heroku’s config via heroku config:set KEY=value.
Enable Heroku logging: Run heroku logs --tail to stream real‑time logs. This is invaluable for debugging runtime errors.
Scale dynos: By default you get one web dyno. If traffic grows, run heroku ps:scale web=2 to add another instance.
Free tier considerations: Free dynos sleep after 30 minutes of inactivity. The first request after sleep incurs a “cold start” delay. For low‑traffic demos this is fine; for production, consider a hobby or professional dyno.
Frequently Asked Questions
Can I use a database with this setup?
Yes. Heroku offers add‑ons like Heroku Postgres. After provisioning, set the DATABASE_URL config var and use a library such as SQLAlchemy to connect.
Why does my app crash on startup?
Typical reasons include missing gunicorn, a mismatched Python runtime, or an uncaught exception in app.py. Check the logs with heroku logs --tail and fix the reported error.
Do I need a Procfile if I use Flask’s built‑in server?
Heroku will still look for a Procfile. The built‑in development server is not suitable for production, so you should always specify gunicorn in the Procfile.
Conclusion
Deploying a Flask web app to Heroku is a straightforward process that teaches you core concepts of modern web development: virtual environments, dependency management, version control, and cloud deployment. By following the six steps above, handling the common pitfalls, and applying the tips, you’ll have a reliable, scalable app ready for further features—whether that’s a database, user authentication, or a full‑blown REST API. Happy coding, and enjoy the freedom of shipping Python apps with just a few commands!
Photo by Microsoft Copilot on Unsplash





