2020年4月17日金曜日

GCEに「NGINX Unit」入れて、WEB(アプリケーション)サーバとして使う

久しぶりにGCE(Google Compute Engine)を使うことになり、改めて最新のトレンドをチェックしてみました。

[GCEの無料枠]
これは健在でした。
と言うか、「無料枠で試しに使って貰い、他社との優位性を知らしめる」戦略なのでしょう。
技術力に自信があるからこその戦略だと思います。
個人で趣味的に使うには、この無料枠で充分。

無料枠の条件
・リージョン(地域): us-central(米中央), us-west(西海岸), us-east(東海岸)
・マシンタイプ: f1-micro
要は、「アメリカのデータセンターで、一番スペックの低いCPU」と言うことですが、サーバ用途であれば十分です。

[OS]
Ubuntuしか使わないので、その他のことは分かりません...
とりあえず、それなりに新しいものを使います。
OS: Ubuntu18.04 LTS

OSの選択で、「Minimal Ubuntu」と言う見慣れないものがあったので、ちょっと調べてみました。
これ、クラウド用のOSなんですね。
とりあえず、HDDは十分(20GB)あるので、通常バージョンで良いかと。

[Nginx]
Web(アプリケーション)サーバとして、単にFlaskを動かしたいだけなのに、これまでだと、uWSGI入れて、設定をあれやって、これやって... と、非常に煩雑で、はっきり言って面倒くさい!!!!

で、調べてみると「NGINX Unit」なるものが有りました。
これ、凄いかも。

本家はこちら。
http://unit.nginx.org/

aptでインストールして、jsonで設定するだけ。ほんと簡単です。ビックリ!!!!!
もう、Apacheは、過去の遺物ですね。(言い過ぎ!!!)


-- 以下は、自分用のメモです。--

[GCE/VM]
コンソール
https://console.cloud.google.com/home/dashboard

新規プロジェクトの作成
 ※省略

課金の上限設定
 お支払 → 予算とアラート
 予算額: 100円
  Budget type: 指定額
  Target amount: ¥100

Compute Engine
VMインスタンス
インスタンスの作成
 ゾーン      us-west1-b
 シリーズ     N1
 マシンタイプ   f1-micro
 ブートディスク  Ubuntu18.04 LTS 20GB ※残り10GBは将来用
 ファイアウォール HTTP

接続 SSH → ブラウザウィンドゥで開く
 ※初回のみ標準ポート(22)で接続

SSHのポートを変更 (OS側) ※セキュリティリスク対策
$ sudo sed -i".bak" -e 's/#Port 22/Port 3843/g' /etc/ssh/sshd_config
$ sudo reboot

VPCネットワーク
外部IPアドレス
 種類: エフェメラル → 静的
  新しい静的IPアドレスの予約: static-ip

ファイヤーウォール
 *SSHのポートを変更 (FW側)
 default-allow-ssh
 SSH port: 22 -> xxxx *任意のポート

接続 SSH → ブラウザウィンドゥでカスタムポートを開く
 ※SSHdの Port変更後は、カスタムポート(xxxx)で接続

スワップの作成
How to Create a Swap File on Google Compute Engine Virtual Machines

$ sudo -i   *rootで作業
-- shell command
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
swapon -s
echo "/swapfile none swap sw 0 0" >> /etc/fstab
--
# reboot

接続 SSH → ブラウザウィンドゥでカスタムポートを開く

[apt]
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install python3-venv python-pip

[Flask]
https://flask.palletsprojects.com/en/1.0.x/installation/#installation

構成
~/
└ project1/
  ├ venv/
  │ └ Flask
  └ main.py

仮想環境 & Flaskインストール
$ cd
$ mkdir project1 && cd project1
$ python3 -m venv venv
$ source ./venv/bin/activate
V pip install Flask

アプリケーション
V nano main.py
--
from flask import Flask
application = Flask(__name__)
@application.route("/")
def index():
  return "Hello Project1!"
if __name__ == "__main__":
  application.run()
--

動作確認
V python3 main.py
 →コンソールをもう1つ開いて動作確認
  $ curl http://127.0.0.1:5000/

V deactivate

[Nginx]
http://unit.nginx.org/installation/#ubuntu

(インストール準備)
キー取得
$ sudo -i   *rootで作業
# curl -sL https://nginx.org/keys/nginx_signing.key | apt-key add -

リポジトリ追加 *Ubuntu18.04 = bionic
# nano /etc/apt/sources.list.d/unit.list
--
deb https://packages.nginx.org/unit/ubuntu/ bionic unit
deb-src https://packages.nginx.org/unit/ubuntu/ bionic unit
--

インストール
# apt update
# apt install unit unit-dev unit-python3.6

コンフィグ
https://unit.nginx.org/howto/flask/

ソケットの場所を調べる
# unitd --help
 --control ADDRESS
  set address of control API socket
  default: "unix:/var/run/control.unit.sock"

現在の設定をファイルに出力
# curl --unix-socket /var/run/control.unit.sock http://localhost/config/ > config.json

Flask用の設定
# nano config.json
--
{
 "listeners": {
  "*:80": {
   "pass": "applications/flask_app"
  }
 },
 "applications": {
  "flask_app": {
   "type": "python",
   "path": "/home/yamayoshiakira/project1/",
   "home": "/home/yamayoshiakira/project1/venv/",
   "module": "main"
  }
 }
}
--
*説明
 listeners: ポート *80(HTTP)
 type: 言語
 path: プログラムの場所
 home: 仮想環境の場所
 module: プログラム本体(ファイル拡張子を除く)

設定を上書き
# curl -X PUT --data-binary @config.json --unix-socket /var/run/control.unit.sock http://localhost/config

再起動
# service unit restart

ブラウザから動作確認。
おつかれさまでした。

参考サイト
http://yamayoshi.blogspot.com/2017/06/gce.html
http://unit.nginx.org/configuration/
https://thr3a.hatenablog.com/entry/20170909/1504925172
https://qiita.com/happou/items/23be1615927be6376dec

----
UNIT のサンプルアプリを調べてみる
# apt install unit unit-dev unit-python3.6

こんなメッセージが出たの、調べてみます。
The Python 3.6 module for NGINX Unit has been installed.
To check out the sample app, run these commands:
 sudo service unit restart
 cd /usr/share/doc/unit-python3.6/examples
 sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config
 curl http://localhost:8400/
Online documentation is available at https://unit.nginx.org

デフォルトの設定値
# curl --unix-socket /var/run/control.unit.sock http://localhost/config/ > config.json
--
{
 "listeners": {},
 "applications": {}
}
--

サンプルを見てみる
/usr/share/doc/unit-python3.6/examples
├ unit.config
└ python-app/
  └ wsgi.py

File: unit.config
--
{
 "applications": {
  "example_python": {
   "type": "python 3.6",
   "user": "nobody",
   "processes": 2,
   "path": "/usr/share/doc/unit-python3.6/examples/python-app",
   "module": "wsgi"
  }
 },
 "listeners": {
  "*:8400": {
   "pass": "applications/example_python"
  }
 }
}
--

File: wsgi.py
--
import os
import datetime
import sys
def application(environ, start_response):
 output = datetime.datetime.now().strftime("%Y-%m-%d %I:%M:%S %p")
 output += "\n\nPython: "
 output += sys.version
 output += "\n\nENV Variables:\n\n"
 for param in os.environ.keys():
  output += param
  output += "\t"
  output += os.environ[param]
  output += "\n"
 start_response('200 OK', [('Content-type', 'text/plain')])
 return [s.encode('utf8') for s in output]
--