Flaskとgunicornをつかった自動化処理

Python学習【365日チャレンジ!】255日目のマスターU(@Udemy11)です。

流石にしっかり寝ないと頭痛がひどくなってくるので、昨晩はおとなしくPython学習の復習をしていました。

と言いつつ、メルカリでエギやギャフを物色したりしちゃうんですよね。

抜き上げるにはちょっと大きかったアオリイカも釣れたので、コンパクトなギャフも必要になるかと思って、第一精工のオートギャフを手に入れてしまいました。

準備が整って「さあ釣りまくるぞ〜」ってなったら釣れなくなっちゃうのがいつものパターンなんですけどね。。。

それでは今日もPython学習を始めましょう。

昨日の復習

昨日は、Fabricでサーバーにアプリケーションをインストールするコードが上手くいかなかったので、gunicornについて調べてみました。

gunicornの詳細については、昨日の記事を参考にしてみてください。

今日は、Fabricでサーバーにアプリケーションファイルと初期設定ファイルを作って、自動でサーバーにアプリケーションをインストールしますよ。

Q&Aで解決

私が現在学習しているのは、酒井さんの「現役シリコンバレーエンジニアが教えるPython 3 入門 + 応用 +アメリカのシリコンバレー流コードスタイル」という講座です。

Udemy講師 酒井さん プログラミング Python

現在の進捗状況は、約75%まで学習しましたが、最近グッとレベルが上って理解するのが大変な状況になっています。

そんなときに活躍するのが講師に直接質問ができるQ&Aなのですが、これまたどのように質問すれば問題の解決につながるかを考える必要がありますし、ネットでいろいろと調べる必要もあります。

大抵のことは自分でネットを使って調べることで解決につながるのですが、今回のFlaskのインストールエラーについては、ちょっとどう質問したら良いかがわかりませんでした。

そんな状態だったので、過去の質問を見直していると、解決につながるQ&Aがあったので、試してみると無事最後までコードが実行されました。

自己学習の場合は、ハマってしまったときに解決する方法が見つからず、なかなか前に進まなくて挫折してしまうなんてことがありますが、Udemyの場合は、直接講師に質問ができてしまうので、超おすすめなんですよね。

ぜひ、Udemyで魅力的な講座を受講してみてください。

↓公式サイトはこちら↓
UdemyセールUdemyセール

ということで、昨日は残念していたサーバーの構築とアプリケーションのインストールの自動化をやっていきましょう。

ファイル構成

今回のコードは自動化のウォームアップで書いたfabfile.pyにコードを加えて、新しくhello.pyapp.confを追加します。

Python Flaskとgunicornを使って自動化

fab_projectの中にrolesフォルダ、その中にwebフォルダを作成して、その中にhello.pyapp.confを作成します。

順番にコードを書いていきます。

hello.py

下記のhello.pyがWebサーバーに乗っけるアプリケーションになります。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello world'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Flaskをインポートして、3行目でファイル名であるhelloという名前のFlaskアプリの箱をつくり、5行目から7行目でHello worldと返す関数をアプリに入れています。

9行目はお決まりのコードで、10行目は、0.0.0.0:5000でアプリを実行します。

まずは、このhello.pyがきちんと動作するかローカル上で実行してみます。

Python Flaskとgunicornを使って自動化

ターミナルでfab_project > roles > webに移動して、hello.pyを実行します。

すると、Flaskhelloというアプリを立ち上げたので、http://0.0.0.0:5000/でアクセスできると表示されるので、ブラウザーからアクセスしてみます。

Python Flaskとgunicornを使って自動化

localhostのポート番号5000番でアクセスすると、きちんとHello worldと表示されました。

app.conf

次は、Flaskで作成したアプリケーションをgunicornで使えるようにするファイルを作成します。

[program:hello]
command = gunicorn --bind 0.0.0.0:5000 hello:app
directory = /root/work/

gunicornというサーバーを使ってflaskで作ったhelloというアプリケーションを実行するコードと、ファイルを収めているディレクトリを/root/work/に指定するコードを記述しています。

これでサーバーとアプリケーションの準備は完了で、自動化のウォームアップで書いたコードに少しコードを付け加えます。

fabfile.py

前回ハマったコードを修正してFlaskをインストールできるようにしたうえで、server1にディレクトリを作って、ローカルのファイル(hello.pyapp.confputします。

from fabric.api import *
from fabric.colors import *
from fabric.contrib.files import *
import io
import sys

sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

env.hosts = ['root@172.16.200.101:22']
env.passwords = {'root@172.16.200.101:22': 'root'}
env.roledefs = {
    'common': ['root@172.16.200.101:22'],
    'web': ['root@172.16.200.101:22'],
}

@task
@roles('common')
def install_packages():
    run('apt-get install -y software-properties-common')
    run('add-apt-repository universe')
    run('apt-get update')
    run('apt-get install -y python-setuptools')
    run('easy_install pip')

@task
@roles('web')
def deploy_web():
    run('apt-get install -y supervisor')
    run('apt-get install -y gunicorn')
    run('pip install Flask==0.12.2')
    if not exists('/root/work'):
        run('mkdir /root/work')

    put('roles/web/hello.py', '/root/work/hello.py')
    put('roles/web/app.conf', '/etc/supervisor/conf.d/app.conf')
    run('service supervisor restart')

@task
def deploy_dev_server():
    install_packages()
    deploy_web()
    print(green('success'))

追加したコードには色付けをしていますが、インポートするライブラリが2つ増えて、30行目でFlaskをインストールしています。

その後、31行目、32行目で/root/workフォルダが無ければ作成するコードを付け足しています。

さらに、ローカルで作ったhello.pyapp.confをクライアント・サーバーにコピーして、supervisorでログインします。

自動化を実行

これでこのfabfile.pyfabricで実行すれば、sever1helloというFlaskアプリが起動して、localhost:8001でアクセスできるようになります。

Python Flaskとgunicornを使って自動化

ポートを8001にしてアクセスできるのは、Vagrantfileで、server1にポートフォーワーディングを定義して、ローカルの5000番をserver18001につなげているからです。

まとめ

今回はかなりつまづきました。
構築はきちんとできているはずなのに、localhost:8001でアクセスできない事象がおこり、どのコードが間違っているのかを考えてもなかなか原因はわからず、ここでかなり時間を食ってしまいました。

改めて、レクチャーのQ&Aをみてみると、同じような症状の人がいて、うまく質問されていたので、そのとおり考えてサクッとコードを実行し、サーバーにアクセスできるようになりました。

ほんと、初歩的なミスもありましたよ。

例えばpip install Flask=0.12.2と記述しないといけないこところをpip install Fabricと書いてしまうような勘違いから、単純なスペルミスやらがたくさん見つかりました。

慎重にコードを書いているつもりでも間違ったタイピングをしてしまっているということがわかりました。

それでは明日もGood Python!