DEV Community

Shun Yamada
Shun Yamada

Posted on

Deploy Flask app to Heroku

Flask is a customized-free framework.
I have the Flask application deployed to Heroku.

Development

  • Python 3.7.5
  • Flask 1.1.1
  • SQL Alchemy
  • Flask Migrate

When it comes to something tutorials, db.create_all() is useful. But this is not available to record when db migrated. So, you should use Flask Migrate if you run the application on production.

Initial commit

Set up requires folders/files. You may see a lot of patterns for Flask application on references.

app/
├── manage.py
├── main
│   ├── __init__.py
│   ├── views.py
│   ├── config.py
│   ├── models.py
│   ├── app.db
│   ├── static/
│   ├── templates/
│   └── instance
│       └──application.cfg
├── Procfile
├── requirements.txt
├── migrations/
└── venv/
Enter fullscreen mode Exit fullscreen mode

Create a project

$ cd APP
$ mkdir -p main/{static,templates,instance}
$ cd main
$ touch manage.py requirements.txt Procfile
$ touch main/{__init__,views,models,config}.py
Enter fullscreen mode Exit fullscreen mode

Add stylesheet or HTML if you wanted. This time, I want to focus on waking through it by focusing on backend stuff.

manage.py

from main import app
app.run()
Enter fullscreen mode Exit fullscreen mode

main/init.py

from flask import Flask

app = Flask(__name__)

import main.views
Enter fullscreen mode Exit fullscreen mode

main/views.py

from flask import render_template
from main import app, db

@app.route('/')
def home():
    return render_template('home/index.html')
Enter fullscreen mode Exit fullscreen mode

Set up configuration

main/config.py

import os

class BaseConfig(object):
    SQLALCHEMY_TRACK_MODIFICATIONS = False  

class DevelopmentConfig(BaseConfig):
    DEBUG = True
    TESTING = True
    SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'

class ProductionConfig(BaseConfig):
    DEBUG = True
    TESTING = True
    SQLALCHEMY_DATABASE_URI=os.environ.get('DATABASE_URL')

config = {
    "default": "main.config.BaseConfig",
    "development": "main.config.DevelopmentConfig",
    "production": "main.config.ProductionConfig",
}

def configure_app(app):
    config_name= os.getenv('FLASK_ENV')
    app.config.from_object(config[config_name])
    app.config.from_pyfile('application.cfg', silent=True)
Enter fullscreen mode Exit fullscreen mode

You can set up FLASK_ENV like export FLASK_ENV=development. I have just divided development and production. on.environ.get('DATABASE_URL') is just for connecting with a database in Heroku.

instance/application.cfg

SECRET_KEY='XXXXXXXXXXXXXXXXXXX'
Enter fullscreen mode Exit fullscreen mode

Caution: instances folders should be added on .gitignore.

Initialized configuration

Add to __init__.py.

from main.config import configure_app

app = Flask(__name__, instance_relative_config=True)
configure_app(app)
Enter fullscreen mode Exit fullscreen mode

Deploy to Heroku

Install gunicorn and psycpg2

$ pip install gunicorm
$ pip install psycopg2
Enter fullscreen mode Exit fullscreen mode

Add Procfile

web: gunicorn main:app --log-file -
Enter fullscreen mode Exit fullscreen mode

Add libraries info to requirements

$ pip freeze > requirements.txt
Enter fullscreen mode Exit fullscreen mode

Deploy!

$ heroku create flask-app
$ git push heroku master
$ heroku config:set FLASK_APP=main
$ heroku config:set FLASK_ENV=production
Enter fullscreen mode Exit fullscreen mode

Set up Database

Create User model

from main import db

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)
    email = db.Column(db.String, unique=True)

    def __repr__(self):
        return '<User %r>' % self.name
Enter fullscreen mode Exit fullscreen mode

Install flask_migrate and SQL Alchemy

$ pip install flask_migrate
$ pip install flask_sqlalchemy
Enter fullscreen mode Exit fullscreen mode

Initialize model

Add to __init__.py.

from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

db = SQLAlchemy(app)
migrate = Migrate(app, db)
db.init_app(app)

import main.models
Enter fullscreen mode Exit fullscreen mode

Migrate

$ flask db init
$ flask db migrate
$ flask db upgrade
Enter fullscreen mode Exit fullscreen mode

Migrate in Heroku

Add libraries to requirements

$ pip freeze > requirements.txt
Enter fullscreen mode Exit fullscreen mode

Migration!

$ heroku run flask db upgrade
Enter fullscreen mode Exit fullscreen mode

You don't need to db init or db migrate. But you have to deploy files including migrations.

Top comments (0)