Help us understand the problem. What is going on with this article?

Amazon Linux2にPython3 -Django - mod_wsgi をインストール

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行を修正("*"の追加)してデフォルトのアクセス制限を外します。

mysite/settings.py
ALLOWED_HOSTS = ["*"]

プロジェクトディレクトリ内で、以下のコマンドを実行し、Djangoの内部WEBサーバーを起動します。

# python3 manage.py runserver 0.0.0.0:8000

データベースの設定をしていないので、migrateしていないとかの警告が出ますが、Djangoのインストールと動作確認だけ進めていますので、後回しにして無視します。

それではPCのブラウザのアドレス欄に下記を入力します。

http://サーバーのIPアドレス:8000

以下のようにブラウザでDjangoの画面が出れば正常です。

Image1.jpg

タイムアウトなどが起こる場合、ファイアーウォール(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行目で読み込みの指定をします。

/etc/httpd/conf.d/wsgi.conf
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なのでポート指定はしません。

http://サーバーのIPアドレス

Image1.jpg

Djangoのページが表示されれば正常です。

タイムアウトになる場合はポート80のファイアーウォールの確認、Internal Server Errorの表示場合は、Apacheのエラーログを確認して下さい。

Pythonプログラムファイルやモジュールのパスに注意

ここまでのインストールの道のりは簡単そうですが、実はかなり試行錯誤しています。
ともかく、Pythonはパスが重要だと再認識しました。ファイルを置いてあるパスやモジュールのパスです。

当記事では、毎度sudoを使って説明するのが面倒なので、rootユーザーで記述説明しています。

実際のインストールや開発には管理者でない一般ユーザーでログインし、sudoを使いインストールや、インストール後にライブラリモジュール等の
インストールをしています。

このモジュールのパスがApache/wsgiから認識されない、あるいはApacheの読み取り権限が無い等に気づかずはまりました。
Apacheのプロセスはapacheユーザー権限にて起動しているので、コマンドライン環境とも異なります。

結果として、wsgi.confファイルの、WSGIPythonPath に、この後多数のパスを追加することになりました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした