#Pythonを使う案件が増えてきた!
プログラミング系の雑誌ではPythonがよく取り上げられていましたが、実案件でもPythonを使うことが増えてきました。
Pythonを使う大きな理由は、AI(機械学習)ライブラリが充実していることです。
今回もAIを使うのでPythonを使います。
WEBのアプリケーション・サーバー(中継?)としてはDjangoを使います。
また、インフラ側のクラウドはAWS(Amazon Web Service)です。
AWSを使う理由は。。。流行でしょうか。。。
他のクラウドでもいいと思うのですが、皆使っているという理由が多いような気が。。。
#EC2サーバーの準備
AWSのEC2インスタンス(仮想サーバー)を作成します。
あらかじめアプリケーションに特化したAMI(マシンイメージ)を選ぶこともでき、PythonやDjangoに特化したBitnami等のイメージも用意されているのですが、今回は一般的な、Amazon Linux2 (64bit版)を使い、Djangoをインストールします。
Amazon Linux2はCentOS7ベースに近いので、この記事はCentOS7での構築にも参考になると思います。
サーバーの構築からログインまで準備ができたという前提で進めます。
#サーバーの環境構築
まずはログインして環境設定です。
rootログインをしている状態での説明ですので、sudoを使う場合は適宜読み替えてください。
実行コマンドを羅列していますが、実行結果(表示出力されるテキスト)はカットしています。
Amazon Linuxの初期状態ではスワップファイルが無い状態ですので、スワップファイルを有効にします。
# fallocate -l 4096m /swapfile
# mkswap /swapfile
# swapon /swapfile
# chmod 600 /swapfile
起動時にスワップファイルが有効になるように、/etc/fstab の最終行に下記の行を追記します。
/swapfile none swap sw 0 0
タイムゾーンを日本標準時に設定します。
# timedatectl set-timezone Asia/Tokyo
念の為既存モジュールのアップデートと、epelレポジトリ、開発環境をインストールしておきます。
# yum -y update
# amazon-linux-extras install epel
# yum -y groupinstall "Development Tools"
Python3のインストール
Pythonはver2系とver3系がありますが、今回のプロジェクトで使用するのはver3系です。
単純にver2系のPythonを削除やアップデートすればいいのでは~と思えますが、ver2系はOS標準のコマンドやスクリプトで多数使用されているため、削除したりアップデートしたりできません。
面倒でトラブルも多いのですが、今回はPython2(ver2系)とPython3(ver3系)を共存させて環境を構築します。
pyenvでPython環境を切り替える方法もあるのですが、Djangoで動作する時のみPython3が使えればいいので、今回はpyenvは使用しません。
それでは、Python3をインストールします。
# amazon-linux-extras install python3
# yum -y install python3-devel
これでPython3がインストールされました。
現時点でインストールされたバージョンはPython3.7.4でした。
これ以降、Python3を使う場合は、
# python3
Python3のパッケージのインストールをする場合は、
# pip3
を必ず使い、Python2とPython3を使い分けなくてはなりません。
Python3用にpymysqlモジュールをインストールします。
#pip3 install pymysql
エラーが出なければ問題ありません。
Djangoのインストール
次にPythonをWEBサーバーで使用するために、アプリケーションフレームワークのDjangoをインストールします。
pymysqlモジュールが、最新のDjangoに対応していないということなので、バージョン2.1指定でインストールします。
# pip3 install django==2.1
正常にインストールされているのかと、Djangoのバージョンを確認するには
# python3 -m django --version
で確認できます。
#Djangoの動作テスト
任意の場所(今回は/var/www/cgi-bin)にDjangoのプロジェクトmyprojectを作成して動作テストを行います。
# cd /var/www/cgi-bin
# django-admin startproject mysite
# cd mysite
カレントディレクトリ(例では/var/www/cgi-bin)以下に、mysiteというプロジェクトディレクトリが作成されます。
プロジェクトディレクトリのmysiteディレクトリ以下にある、setting.pyの1行を修正("*"の追加)してデフォルトのアクセス制限を外します。
ALLOWED_HOSTS = ["*"]
プロジェクトディレクトリ内で、以下のコマンドを実行し、Djangoの内部WEBサーバーを起動します。
# python3 manage.py runserver 0.0.0.0:8000
データベースの設定をしていないので、migrateしていないとかの警告が出ますが、Djangoのインストールと動作確認だけ進めていますので、後回しにして無視します。
それではPCのブラウザのアドレス欄に下記を入力します。
以下のようにブラウザでDjangoの画面が出れば正常です。
タイムアウトなどが起こる場合、ファイアーウォール(AWSではセキュリティグループのインバウンド)でポート8000を通すようにして下さい。
8000の部分を80に変更すれば、ポート80のhttpに変更できますが、Apacheなどが先に起動していると衝突してエラーになります。
Webサーバーを停止するには、CONTROLキーとCを同時に押します。
ここまででDjangoがインストールして正常に動作しているのを確認できました。
Apacheとの連携 mod_wsgi
Djangoの内部Webサーバーでの動作は確認できましたが、実際にサービスとして使う場合はApacheやnginx等のWebサーバーを使用します。
今回はApacheを使いますが、WebサーバーとDjangoの橋渡しをするのが、mod_wsgiモジュールです。
Apache(httpd)とmod_wsgiをインストールします。
# yum install -y httpd httpd-devel
# pip3 install mod_wsgi
# pip3 install mod_wsgi-httpd
wsgiのApacheモジュールが作成されましたが、どこにモジュールが生成されたのか表示されないので探します。
find /usr -name "mod_wsgi*.so"
モジュールを見つけたら、新規に作成する /etc/httpd/conf.d/wsgi.conf ファイルの1行目で読み込みの指定をします。
LoadModule wsgi_module /usr/local/lib64/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so
WSGIPythonHome /usr
WSGIScriptAlias / /var/www/cgi-bin/mysite/misite/wsgi.py
WSGIPythonPath /var/www/cgi-bin/mysite:/var/www/cgi-bin/mysite/mysite:/usr/lib/python3.7/site-packages:/usr/lib64/python3.7/site-packages:/usr/local/lib/python3.7/site-packages:/usr/local/lib64/python3.7/site-packages
<Directory /var/www/cgi-bin/mysite/mysite>
Options ExecCGI MultiViews Indexes
MultiViewsMatch Handlers
AddHandler wsgi-script .py
AddHandler wsgi-script .wsgi
DirectoryIndex index.py app.wsgi index.html
Order allow,deny
Allow from all
<Files wsgi.py>
Require all granted
</Files>
</Directory>
このファイルを作成したら、反映させるためにApacheを再起動します。
自動起動設定にしていなければ、ここでApacheの自動起動設定をします。
# systemctl restart httpd
# systemctl enable httpd.service
PCのブラウザのアドレス欄に下記を入力します。今回はポート80なのでポート指定はしません。
Djangoのページが表示されれば正常です。
タイムアウトになる場合はポート80のファイアーウォールの確認、Internal Server Errorの表示場合は、Apacheのエラーログを確認して下さい。
Pythonプログラムファイルやモジュールのパスに注意
ここまでのインストールの道のりは簡単そうですが、実はかなり試行錯誤しています。
ともかく、Pythonはパスが重要だと再認識しました。ファイルを置いてあるパスやモジュールのパスです。
当記事では、毎度sudoを使って説明するのが面倒なので、rootユーザーで記述説明しています。
実際のインストールや開発には管理者でない一般ユーザーでログインし、sudoを使いインストールや、インストール後にライブラリモジュール等の
インストールをしています。
このモジュールのパスがApache/wsgiから認識されない、あるいはApacheの読み取り権限が無い等に気づかずはまりました。
Apacheのプロセスはapacheユーザー権限にて起動しているので、コマンドライン環境とも異なります。
結果として、wsgi.confファイルの、WSGIPythonPath に、この後多数のパスを追加することになりました。