如何使用 Heroku 部屬一個 Web App 網頁應用程式


Posted by KD Chang on 2020-03-08

前言

在雲端運算時代裡我們已經不用像過去一樣需要自建機房可以使用雲端服務進行部屬,若是你是一個希望專注在應用程式開發上,不太需要管基礎建設的維護的話可以考慮雲端的 PasS 服務,例如:Heroku 就是一個常用來當作部屬的工具(有提供一定的免費的額度)。接下來我們將使用 Heroku 把我們的 Python App 部屬上去並串接 Heroku ClearDB MySQL 資料庫(Heroku 上的MySQL)。

環境設定

  1. 註冊 Heroku 帳號
  2. 建立一個 Heroku App
  3. 根據不同作業系統安裝 Heroku CLI

建立一個簡單 Flask Web App

在這個範例中我們建立一個超簡易的 Flask Web App,主要功能為回傳 Hello, Heroku! 文字。

flask_app.py

from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def hello():
    return f'Hello, Heroku!'

if __name__ == 'main':
    app.run() #啟動伺服器

接著我們來準備部屬的相關檔案:

  1. Procfile:如何運行 Web App,在這邊我們使用 gunicorn 這個 WSGI Server。flask_app 為檔案模組名稱、app 為檔案中 Flask app 的實例變數。

     web: gunicorn flask_app:app –log-file -
    
  2. runtime.txt:使用的 Python 版本,這邊使用 python-3.6.2(版本號碼可能會更新,請參考 heroku 最新版本 Heroku Python Support

     python-3.6.2
    
  3. requirements.txt:Python 套件清單,告訴 Heroku 需要安裝哪些套件(主要有 gunicorn、flask 和 PyMySQL。我們也可以設定需要安裝的版本)

     gunicorn
     flask
     PyMySQL
    

部屬到 Heroku

$ heroku login

輸入自己的帳號密碼完成登入。

在工作資料夾下初始化 git:

$ git init

可以透過 heroku git -h 看到指令說明

$ heroku git -h
manage local git repository for app

USAGE
  $ heroku git:COMMAND

COMMANDS
  git:clone   clones a heroku app to your local machine at DIRECTORY (defaults to app name)
  git:remote  adds a git remote to an app repo

透過 $ heroku git 新增 app repo 為遠端程式庫

$ heroku git:remote -a python-flask-demo-app

commit 自己的更新並推送上去

# 將所有更動提交到 staging
$ git add .
# 將所有變動 commit 並加上訊息
$ git commit -a -m "make it better"
# 推送到遠端
$ git push heroku master

推送完後就會自動更新程式內容,若要查看 log 可以使用:

$ heroku logs --tail

若要更新程式碼則重複 git 操作即可:

# 將所有更動提交到 staging
$ git add .
# 將所有變動 commit 並加上訊息
$ git commit -a -m "make it better"
# 推送到遠端
$ git push heroku master

串接 ClearDB MySQL

在 Heroku 我們還可以透過 Heroku 提供的雲端 ClearDB MySQL 來將資料儲存到資料庫中。以下透過 PyMySQL 簡單範例說明使用方式。

建立 DB

我們點選右邊的安裝 ClearDB MySQL 並掛載到我們 heroku app 上:

在 heroku app 後台的 resources 就會看到 ClearDB MySQL,點進去後可以從 system info 看到帳號密碼:

使用 $ heroku config 可以看到已經有 CLEARDB_DATABASE_URL,我們可以拆解出來帳號密碼和資料庫 Host 及 DB 名稱,方便我們使用:

mysql://username:password@db_host/db_name

將 DB Config 資料設定到 Heroku app 後台 Settings 的 Config Vars 中,CLEARDB_DATABASE_HOSTCLEARDB_DATABASE_USERCLEARDB_DATABASE_PASSWORDCLEARDB_DATABASE_DB

創建 Table

我們可以使用 mysql workbench 或是 Sequel Pro 等 GUI Tool 連上資料庫後先建立資料表,方便後續使用。

CREATE TABLE `users` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `email` varchar(255) COLLATE utf8_bin NOT NULL,
    `password` varchar(255) COLLATE utf8_bin NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
AUTO_INCREMENT=1 ;

整合 PyMySQL

以下使用 PyMySQL 的簡單範例進行整合(注意我們 DB config 資料是從 heroku 設定的環境變數取得)。功能如下:

  1. 把資料新增到 users 資料表中
  2. 把資料取出來回傳到瀏覽器
from flask import Flask, request
import os

import pymysql
import pymysql.cursors


app = Flask(__name__)

# Connect to the database
connection = pymysql.connect(host=os.environ.get('CLEARDB_DATABASE_HOST'),
                             user=os.environ.get('CLEARDB_DATABASE_USER'),
                             password=os.environ.get('CLEARDB_DATABASE_PASSWORD'),
                             db=os.environ.get('CLEARDB_DATABASE_DB'),
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

with connection.cursor() as cursor:
    # Create a new record
    sql = "INSERT INTO `users` (`email`, `password`) VALUES (%s, %s)"
    cursor.execute(sql, ('webmaster@python.org', 'very-secret'))

connection.commit()


@app.route('/')
def hello():
    with connection.cursor() as cursor:
        # Read a single record
        sql = "SELECT `id`, `email` FROM `users` WHERE `email`=%s"
        cursor.execute(sql, ('webmaster@python.org',))
        result = cursor.fetchone()
        print(result)
    return f'Hello, Heroku {result["email"]}!'

if __name__ == 'main':

    app.run() #啟動伺服器

將修改 git commit 和推送到 heroku 上後,我們可以到 heroku app 的網址看到成果:

總結

以上我們透過一個簡單範例將使用 Heroku 把我們的 Python App 部屬上去並串接 Heroku ClearDB MySQL 資料庫(Heroku 上的 MySQL)。若你想使用雲端伺服器的優點又不想處理太底層 Server 問題和維護的話,或續下次就可以考慮雲端的 PasS 服務。

參考文件

  1. Connecting to ClearDB from Heroku using Python
  2. Heroku Postgres

#Heroku #tutorial #ClearDB #MySQL









Related Posts

第七天:API Server【一】

第七天:API Server【一】

git clone 了一個 Laravel 專案,然後咧?

git clone 了一個 Laravel 專案,然後咧?

MTR04_1031

MTR04_1031




Newsletter




Comments