• トップ
  • ブログ一覧
  • FirebaseをデータベースとしてFlaskアプリをHerokuへとデプロイしてみた
  • FirebaseをデータベースとしてFlaskアプリをHerokuへとデプロイしてみた

    広告メディア事業部広告メディア事業部
    2019.07.04

    IT技術

    FlaskアプリをHerokuへとデプロイするまでの手順

    Pythonによって動かすことができるFlaskですが、Djangoほど大規模なアプリを開発する必要はなく、簡単なAPI処理などを考えれば一つのアプリ開発の選択肢として考えられると思います。

    この記事では、話題のFirebaseをデータベースとしてFlaskアプリをHerokuへとデプロイするまでの手順を紹介します。

    モダンな技術を使っているので、今風の実装方法といって良いでしょう。

    本題に入る前に、「Firebase」「Heroku」について軽くご説明したいと思います。

    Firebase(ファイアーベース)とは

    Firebaseとは、アプリケーションを運用する土台となるソフトウェアとなります。

    データベース作成から何かエラーが起きたときのレポート作成までさまざまな機能が搭載されており、バックエンドエンジニアの役割を担っているといって良いでしょう。

    「ウェブ」「IOS」「アンドロイド」「Unity」のバックエンドに対応しています。

    Heroku(ヘロク)とは

    Herokuは、2007年から開発が始まった Could platform です。

    最初は「Ruby」のみの対応でしたが、現在では「Java」「Node.js」「Scala」「Python」「PHP」など様々な言語に対応しており、アプリのデプロイ先として幅広く使われています。

    Githubでの管理となるので扱いやすいという点もあります。

    Firebaseの設定

    それでは、Firebaseの設定から始めていくとしましょう!

    ログイン

    Googleアカウントでログインすると、設定画面が下記の画像のように表示されます。

    ちなみに、マルチデータベースGoogle Cloud Platformとの連結は有料となります。

    プロジェクトの作成

    「Add project」をクリックすると以下のようにProjectnameLocationを指定することができます。

    ロケーションは、「デフォルト」で良いと思います。

    名前とストレージのロケーションを指定して、「Create project」をクリックし、プロジェクトを作成します。

    データベースの作成

    次に、データベースの設定をします。

    プロジェクトのメイン画面に移動し、「Database」をクリックします。

    リアルタイムデータベースに移動し、「Create database」をクリックします。

    「Start in test node」「Enable」にしてデータベースへのアクセスに関するセキュリティルールを設定します。

    これでデータベースへのアクセスが可能になります。

    アプリケーションと統合

    その後、「Project settings」をクリックして、アプリケーションと統合させます。

    今回は、ウェブなので左から3番目のスクリプトボタンをクリックします。

    アプリの名前を入力します。

    無事、スクリプトを得ることができました。

    このスクリプトが認証キーとなりデータベースにアクセスすることが可能になります。

    基本的には、これをHTMLに貼り付けることで、データベースを操作できます(CRUD)。

    非常に簡単ですよね。

    今回はテストなので、全てのIPからアクセスできるようになっていますが、アクセス制限をするなどのカスタマイズももちろん可能です。

    ローカルコンピュータの設定

    次に、自分のローカルコンピュータにいきます。

    今回は、Macbook Airを使用しているため、ターミナル(ウィンドウズだとコマンドプロンプト)で以下のようなディレクトリを構成します。

    この通りにディレクトリを構成しないと、Herokuへのアップロードの際にエラーがでるので気をつけてください。

    Todoリスト作成

    今回作るアプリは、先ほどを作ったデータベースを使ったTodoリスト作成です。

    今回の記事は、「モダンな技術を使ったアプリ開発とデプロイまで」というテーマなので、Flaskについては詳細に解説はしませんが、各スクリプトにコメントしていきたいと思います。

    Procfile

    まず、Procfileですが、以下のような設定がされています。

    gunicorn とは、 Python WSGI HTTP Server for UNIXと定義されており、Webサーバーとアプリケーションを接続させるためのインターフェースです。

    -b でバインドするソケットの指定をします。

    今回は、どのIPからもアクセスできるように0.0.0.0 (任意のIPv4アドレス)でデフォルトのポート番号5000をしています。

    appは、メインファイル名を指定します。

    1web: gunicorn -b 0.0.0.0:$PORT app:app

    README.md

    README.mdは、プロジェクトの詳細が書かれています。

    app.py

    app.py がメインのコードとなります

    まず、Firebaseで作成したデータベースのConfigをコピー&ペーストします。

    1import pyrebase
    2from flask import *
    3
    4config = {
    5  "apiKey": "*************",
    6  "authDomain": "*************",
    7  "databaseURL": "*************",
    8  "projectId": "*************",
    9  "storageBucket": "*************",
    10  "messagingSenderId": "*************",
    11  "appId": "*************"
    12}

    次に、Configのデータを引数としてfirebase変数で初期化し、dbに接続します。

    db.child…  の箇所は、簡単にデータベースに書き込める例として表示しました。

    1firebase = pyrebase.initialize_app(config)
    2
    3db = firebase.database()
    4# db.child("names").push({"name":"kota"})
    5# db.child("names").push({"name":"take"})

    コメントを外して実行すると、firebase側では以下のように書き込まれます。

    実行処理

    次に、Flaskの実行処理に移ります。

    基本的にはコメントで記載した通りの処理を実行します。

    Firebase上で、CreateDeleteを使ったことになります。

    処理自体は非常にシンプルですが、応用すれば基本的なアプリは作れるのではないでしょうか。

    1# ルートを指定、メソッドはGETPOST
    2@app.route('/', methods=['GET', 'POST'])
    3
    4# basic関数を定義
    5def basic():
    6    # POSTでリクエストされたら
    7    if request.method == 'POST':
    8        # form['submit']のvalueが'add'であれば
    9        if request.form['submit'] == 'add':
    10            # formから値を取得
    11            name = request.form['name']
    12            # 値をfirebase上のtodoに書き込む
    13            db.child("todo").push(name)
    14            # firebaseから値を取得
    15            todo = db.child("todo").get()
    16            # toに値を代入
    17            to = todo.val()
    18            # index.htmlに 値toを返す
    19            return render_template('index.html', t=to.values())
    20        # form['submit']のvalueが'delete'であれば
    21        elif request.form['submit'] == 'delete':
    22            # firebaseのdbであるtodoを削除
    23            db.child("todo").remove()
    24            # 元のindex.htmlを返す
    25            return render_template('index.html',)
    26    # それ以外は、index.htmlを返す
    27    return render_template('index.html')
    28
    29if __name__ == '__main__':
    30    #処理の実行
    31    app.run(debug=True)

    requirements.txt

    次のファイルは、requirements.txtです。

    ここには、必要なライブラリを置いておきます。

    herokuでも使われるので、重要です。

    runtime.txt

    runtime.txtは、Pythonのバージョンを指定しています。

    これも、Herokuで読み取られるファイルで置く必要があります。

    templatesフォルダ

    templatesフォルダには、index.htmlが置いてあります。

    見た目は、BootstrapのCDNを使っています。

    以下の箇所で値を表示させています。

    1<div class="container-fluid">
    2        # firebaseからもらった値をfor文に入れ込む
    3        {% for l in t %}
    4        <ul class="list-group">
    5            <li class="list-group-item">
    6            # 値を表示
    7                {{l}}
    8            </li>
    9        </ul>
    10        {% endfor%}
    11</div>

    これでファイルは全てとなります。

    実行

    実際に実行すると、firebaseと連携してプログラムが動きます。

    Herokuへのデプロイ準備として、Githubにコードをあげます。

    レポジトリはプライベートでもパブリックでも構いません。

    注意すべき点として、パブリックであげる場合は、Firebaseの認証キーを削除するようにしてください。

    Herokuへのデプロイ

    最後にHerokuへとデプロイします。

    基本的には、ファイルを同様に構成してチュートリアルにある通りにやれば問題なくデプロイできます。

    流れ

    1. Herokuへのログイン
    2. スクリプトをユーザー:herokuへとpushする

    これで終了となります。

    さいごに

    FirebaseとHerokuを使うことによってかなりのリソースが節約されることがよくわかります。

    これまでデータベースの環境構築・設定などに使っていた時間を減らし、アプリの開発により注力できるようになると思います。

    ウェブだけでなく、モバイルやUnityにも対応しているのも良いですね。

    【編集部補足】
    最近は「Firestore」を使うのが主流になってます。

    こちらの記事もオススメ!

    featureImg2020.07.30Python 特集実装編※最新記事順Responder + Firestore でモダンかつサーバーレスなブログシステムを作ってみた!P...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    広告メディア事業部

    広告メディア事業部

    おすすめ記事