Deploy Flask app to Heroku
Tags: flask, heroku, python
Published: 2019-12-16 10:07:17

---
title: Deploy Flask app to Heroku
published: true
description: Flask is a customized-free framework. I have the Flask application deployed to Heroku.
tags: Flask, Heroku, Python
---

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/
```

## 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
```

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

### manage.py

```python
from main import app
app.run()
```

### main/init.py

```python
from flask import Flask

app = Flask(__name__)

import main.views
```

### main/views.py

```python
from flask import render_template
from main import app, db

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

## Set up configuration

### main/config.py

```python
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)
```

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

```python
SECRET_KEY='XXXXXXXXXXXXXXXXXXX'
```

Caution: `instances` folders should be added on `.gitignore`.

### Initialized configuration

Add to `__init__.py`.

```python
from main.config import configure_app

app = Flask(__name__, instance_relative_config=True)
configure_app(app)
```

## Deploy to Heroku

### Install gunicorn and psycpg2

```
$ pip install gunicorm
$ pip install psycopg2
```

### Add Procfile

```
web: gunicorn main:app --log-file -
```

### Add libraries info to requirements

```
$ pip freeze > requirements.txt
```

### Deploy!

```
$ heroku create flask-app
$ git push heroku master
$ heroku config:set FLASK_APP=main
$ heroku config:set FLASK_ENV=production
```

## Set up Database

### Create User model

```python
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
```

### Install flask_migrate and SQL Alchemy

```
$ pip install flask_migrate
$ pip install flask_sqlalchemy
```

### Initialize model

Add to `__init__.py`.

```python
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

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

import main.models
```

### Migrate

```
$ flask db init
$ flask db migrate
$ flask db upgrade
```

## Migrate in Heroku

### Add libraries to requirements

```
$ pip freeze > requirements.txt
```

### Migration!

```
$ heroku run flask db upgrade
```

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