How to deploy python WebApp (Django/Flask/FastAPI) on Heroku?

Steps to deploy your Python web app on Heroku effortlessly with the comprehensive guide including examples for seamless deployment.

How to deploy python WebApp (Django/Flask/FastAPI) on Heroku?

Heroku

 Heroku is a cloud based PaaS service, now owned by Salesforce. A platform for building, deployment, managing, scaling the web app architecture. Heroku been one the first platform to use containerized web app architecture approach. It also provide data management using an product called DataClip. Heroku supports a broad range of applications and their web frameworks including Javascript, Ruby, Python, Java, GoLang and Rust are the name of few.

1. Dyno

Create a dyno (not free now) on Heroku.

Connect your local python WebApp with Heroku app.

Types of Dyno.

  1. Web
    To receive HTTP traffic on your dyno, we need to set the dyno as web in Procfile.
  2. Worker
    Background workers, Queued Jobs from Web Dyno and CronJobs (Timed-processes) are managed by worker dyno. The worker dyno can a long-running ⌛ one or for rapid response to the dyno.

2. Procfile

Create a file named Procfile
(Please make sure the file name is exactly the same without any extension)

Procfile
web: gunicorn main:app
Procfile with gunicorn for Flask
  • web is the name of the dyno process.
  • gunicorn is the gunicorn is the python web server. it might be uvicorn if you are using ASGI server.
  • main is the name of the file as main.py
  • app is the name of the web-server variable in the file main.py
pip3 install gunicorn

2.1 For Django with WSGI Server, the Procfile would look like this

Procfile
web: gunicorn project.wsgi
Procfile for Django

2.2 For FastAPI with uvicorn server the Procfile would be like this
Make sure that you have mentioned uvicron in requirement.txt file

Procfile
web: uvicorn main:app --host 0.0.0.0 --port 80
Procfile for FastAPI

3. requirements.txt file

The requirements.txt is used to specify all of the dependencies of our python project with their exact versions for the app's current usage.

pip3 freeze will show a list of all of the packages installed in your current environment for that app.

Command:

pip3 freeze > requirements.txt
Before doing pip3 freeze, please make sure that you have enabled the app's virtual environment

4. runtime.txt (Optional)

 By default, the Heroku python apps uses latest python version available for the app. But, if our app is configured for the previous versions, we can specify that runtime.
Create a file named runtime.txt and paste the python version in that file.

runtime.txt
python-3.8.13

Supported runtime are:

  • python-3.10.4
  • python-3.9.13
  • python-3.8.13
  • python-3.7.13

5. APTFile (Optional)

In there are some third party debian package that are required for the python project, we can add them in a file named Aptfile. Those packages will be added in the buildpack by Heroku on deployment.

Third party package can be ImageMagick, FFmpeg, Tesseract etc.

Example

Aptfile
imagemagick

tesseract-ocr
tesseract-ocr-eng
Elements Marketplace: heroku-buildpack-apt
Buildpack for Heroku

Deploy

Once all of the steps mentioned above are completed. It's time to deploy the app. Make sure you have connected your app using the command.

heroku git:remote -a [your-app-name-here]
git push heroku master

We can also see the deployment logs in realtime on Heroku dashboard or cli both

Conclusion

Once our web app is deployed. Heroku will share a custom url to access the app like https://[custom-alias].herokuapps.com. You can also add a custom domain on your web-app hosted on Heroku for free. but, for https:// SSL will only enabled for paid dyno's

If there is any problem after deployment of the app you can access the logs of the from Heroku Dashboard.

Heroku Application Logs (Web)

We can also access the logs using Heroku cli in the folder of python web app project.

heroku logs
2022-09-16T15:13:46.677020+00:00 app[web.1]: Processing PostController#list (for 208.39.138.12 at 2010-09-16 15:13:46) [GET]
2022-09-16T15:13:46.677023+00:00 app[web.1]: Rendering template within layouts/application
2022-09-16T15:13:46.677902+00:00 app[web.1]: Rendering post/list
2022-09-16T15:13:46.678990+00:00 app[web.1]: Rendered includes/_header (0.1ms)
2022-09-16T15:13:46.698234+00:00 app[web.1]: Completed in 74ms (View: 31, DB: 40) | 200 OK [http://myapp.heroku.com/]
2022-09-16T15:13:46.723498+00:00 heroku[router]: at=info method=GET path="/posts" host=myapp.herokuapp.com" fwd="204.204.204.204" dyno=web.1 connect=1ms service=18ms status=200 bytes=975
2022-09-16T15:13:47.893472+00:00 app[worker.1]: 2 jobs processed at 16.6761 j/s, 0 failed ...

or

heroku logs --tail