こんにちは。
444株式会社エンジニアの河端です。
本記事ではローカル環境で動作するアプリケーションを、
GCEにデプロイする方法をなるべく簡単に説明します。
- 本記事について
- 手順1. ローカル環境で動くアプリケーションを作成
- 手順2. サーバーを準備
- 手順3. ローカル環境で動作した環境を試す
- 手順4. 外部IPアドレスへのアクセスで動作するようにする
- 終わりに
本記事について
目的
- ローカル環境で動作するアプリケーションを、GCEのIPアドレスにアクセスすることで動作するようにする
本記事の対象者
- プログラムは書けるが、サーバーにデプロイする方法がわからない人
- ローカル環境で動作したプログラムを、実際のサーバーにデプロイしたい人
事前準備
- GCPのアカウント登録
注意
- 最低限の仕組み説明のため、開発用サーバーを実サーバー上でそのまま立てる等、実開発としては適切ではない手順があります
手順1. ローカル環境で動くアプリケーションを作成
まずは、ローカル環境 (自身のPC) 上で動くコードを書いてみましょう。 今回は以下の構成で環境作成します。
- 仮想環境: virtualenv
- 言語: Python3系
- フレームワーク: Flask
早速ターミナルを開き、ローカル環境を作成しましょう。
# virtualenv をインストール ~/test_app $ sudo pip install virtualenv # virtualenvで、myvenvという仮想環境を作成 ~/test_app $ virtualenv myvenv # 作成した仮想環境に入ります ~/test_app $ source myvenv/bin/activate # flask を仮想環境にインストール ~/test_app $ (myvenv) pip install flask # パッケージをコードベースで管理できるようにrequirements.txtに書き出す ~/test_app $ (myvenv) pip freeze > requirements.txt
作成した環境に、flaskで作成したアプリケーションを置きます。
from flask import Flask app = Flask(__name__) @app.route('/') def hello_world(): return 'Hello, world!' if __name__ == "__main__": app.run(host="127.0.0.1", port=5000)
ターミナルに戻り、上記アプリケーションを開発用サーバーで起動します。
$ (myvenv) python main.py * Serving Flask app 'main' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
http://127.0.0.1:5000/ にアクセスすると、Hello world! と表示されました!
ここまでできたら、gitにコードをcommitしておきましょう。 GitHub や GitLab 等のリモートリポジトリにpushするとよいでしょう。
手順2. サーバーを準備
次に、サーバーを準備します。 GCPにログインし、GCEのインスタンスを作成します。 (以降はサーバー => インスタンス と表現します)
作成されたインスタンスの外部IPをメモしておきましょう。
この外部IPは、世界でこのインスタンスだけが保持しているIPアドレスです。
最終的にここにアクセスすることで、"Hello, world!" と表示されるようにします。
インスタンスにログインできましたか?
ログインできたら準備は完了です。
手順3. ローカル環境で動作した環境を試す
さてここからが本番です。
いよいよ先程作成したアプリケーションをサーバー上にデプロイしていきましょう。
# お作法。update & upgrade root@blog-instance:/home/user# sudo apt update root@blog-instance:/home/user# sudo apt upgrade # pipがないため、インストール root@blog-instance:/home/user# apt install python3-pip # 手順1で作成したアプリケーションをインスタンス内に持ってくる root@blog-instance:/home/user# git pull [自分のリポジトリ] # 手順1と同様に環境をactivate root@blog-instance:/home/user# cd test_app root@blog-instance:/home/user/test_app# source myvenv/bin/activate # 環境にパッケージをインストール root@blog-instance:/home/user/test_app# pip install -r requirements.txt # 開発用サーバーを起動 (myvenv) root@blog-instance:/home/user/test_app# python main.py * Serving Flask app 'main' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
これでローカル環境と同じ環境を作成し、開発用サーバーを起動できました!
早速、先程メモした外部IPアドレスにアクセスしましょう!!
....あれ?
手順4. 外部IPアドレスへのアクセスで動作するようにする
なぜ動作しないのでしょうか。 それは、"インスタンス(サーバー)が、受けとったリクエストをどこで処理をすればよいか分かっていないため" です。
簡単に説明画像を作ってみました。
今は画像のように、リクエストに対しどのような処理を行うかが定義されていない状態になっています。
そのため、そのリクエストをちゃんと処理できないよ~ というエラーが帰ってきているわけですね。
では、リクエストに対しどの処理を行えばよいかを紐付けてあげましょう。
今回は nginx を導入し、リクエストの紐付けを行います。
(myvenv) root@blog-instance:/home/user/test_app# sudo apt update (myvenv) root@blog-instance:/home/user/test_app# sudo apt install nginx (myvenv) root@blog-instance:/home/user/test_app# sudo systemctl status nginx ● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2021-08-06 01:54:58 UTC; 2min 12s ago Docs: man:nginx(8) Process: 31618 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 31619 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 31620 (nginx) Tasks: 3 (limit: 1164) Memory: 10.0M CGroup: /system.slice/nginx.service ├─31620 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; ├─31621 nginx: worker process └─31622 nginx: worker process
nginxが起動しているのを確認できたら、httpで先程の外部IPアドレスにアクセスしましょう。
"Welcome to nginx!" と表示されていたら成功です。
これは、外部IPアドレスにhttpリクエストをした際に、
"Welcome to nginx!" と表示されるアプリケーションが動作した と捉えてください。
この動作するアプリケーションを、先程開発したものに差し替えます。
~ (略) ~ include /etc/nginx/conf.d/*.conf; # include /etc/nginx/sites-enabled/*; # ここをコメントアウト or 削除する ~ (略) ~
/etc/nginx/conf.d/ ディレクトリに、test_app.conf というファイルを作成し、以下のように記載します。 リクエストが80ポート (http) に来たとき、http://127.0.0.1:5000で処理を行う、という設定をしています。
server { listen 80; location / { proxy_pass http://127.0.0.1:5000; proxy_redirect default; } }
ここまでできたら、設定を反映するためにnginxを再起動します。 そして、アプリケーションを起動しましょう。
(myvenv) root@blog-instance:/home/user/test_app# systemctl restart nginx (myvenv) root@blog-instance:/home/user/test_app# python main.py * Serving Flask app 'main' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
アプリケーションを起動できたら、外部IPアドレスにhttpリクエストでアクセスしましょう。
Hello, world! と表示されました! 成功です。
httpリクエスト (80番ポート) に来たリクエストを、インスタンス内部で正常に処理することができました。
終わりに
Web API をGCE上のインスタンスにデプロイし、動作させる方法をざっくり説明しました。
この記事を読んで、実際のサーバー上へのデプロイの大筋の流れを把握してもらえていたら嬉しいです。