【Ubuntu(ラズパイ)】Django+Nginx+uWSGI構成のWebアプリケーション開発
2021.12.11 /
本記事ではRaspberry Pi(OSとしてUbuntu)でDjangoを使ったWebアプリケーション構築方法について解説していきます。
構成はWebサーバーにNginx、アプリケーションサーバーにuWSGI、WebアプリケーションにDjangoを利用しています。
ここで使用するUbuntuはUbuntu Server 20.04.3 LTSです。
Raspberry Pi(通称ラズパイ)にUbuntuをインストールする方法は以下記事をご参照ください。
【ラズパイ】Webアプリケーション用にUbuntuをインストールする(Raspberry Pi Imager)
私は社内WebアプリケーションサーバーとしてDjangoをインストールしたラズパイを使うことが多いです。
ここでは私がUbuntuでDjangoを動かすときの構築方法を詳しく解説していきます。Webサーバーを起動し、初期画面を表示させるところまで解説します。
Webアプリケーションの構成
私はWebサーバーにNginx、アプリケーションサーバーにuWSGI、WebアプリケーションにDjangoを利用しています。
この構成ではブラウザがサーバーにリクエストを送り、レスポンスが返ってくるまでの流れは次のようになります。
ブラウザ <―> Webサーバー(Nginx)<―> Unixソケット <―> アプリケーションサーバー(uWSGI)<―> Webアプリケーション(Djangoなど)
ブラウザからのリクエストはNginxで受け取り、Nginxはsocketを通してuWSGIに渡します。
Nginx
NginxとはOSS(Open Source Software)のWebサーバーソフトウェアです。
近年WebサーバーとしてNginxを利用する人が急増しており、現在ではApacheに次いで2位のシェアを誇ります。
*2020年8月にNetcraftという会社が出した調査によるとNginxがApacheを抜きシェア1位になったみたいです。
Nginxの詳しい設定ファイルについては以下記事をご参照ください。
【Nginx】設定ファイルとは(nginx.conf、conf.d、sites-available、uwsgi_paramsなど)
uWSGI
DjangoやFlaskといったWebアプリケーションフレームワークを利用する際、WebサーバーとWebアプリケーションフレームワークを繋ぐインターフェースが必要となります。
このインターフェースの定義をWSGI(Web Server Gateway Interface)といいます。
そしてWSGIをサポートするサーバーの一つがuWSGIです。
uWSGIは通信方法として、UNIXドメインソケットまたはHTTPでの通信をサポートしています。
Django
DjangoはPythonによるWebフレームワークの一つです。Webアプリケーション開発を簡単にする様々な機能を有します。
PythonWebフレームワークの中では人気・知名度が最も高いです。Djangoについてより詳しい説明は以下記事をご参照ください。
【django】Webサイト・アプリを作成するまでの一連の流れ
パッケージのインストール
Ubuntuでパッケージをインストールするにはaptコマンドを使用します。
aptコマンドはubuntuなどのDevian系ディストリビューションで利用される、パッケージの操作や管理を行うコマンドです。
aptコマンドは「apt-get」と「apt-chache」を統合したコマンドです。
パッケージのインストールでapt installコマンド、apt-get installコマンドどちらを利用しても大丈夫です。
パッケージのインストールを行う前にアップデートを実施します。
$ sudo apt update
パッケージのアップデートが完了しましたら、次にNginxとPythonのパッケージをインストールしていきましょう。
Nginxのインストール
Nginxは2004年にリリースされたWebサーバーであり、Apacheと共に非常に人気があります。NginxはApacheよりも高速であり、大量の処理が得意です。
本記事ではWebサーバーにNginx(エンジンエックス)をubuntuにインストールします。
$ sudo apt install nginx
UbuntuにNginxをインストールする方法は以下記事で詳しく解説しております。
【Ubuntu】Nginxをインストールする方法(特徴と利用用途)
Pythonのインストール
Ubuntu Server 20.04.3 LTSには最初からPython3.8.10がインストールされています。
$ Python3 -V
Python 3.8.10
そのためPythonを別途インストールする必要がありませんが、Pythonライブラリをインストールするためのpip3を以下コマンドを実行してインストールしましょう。
$ sudo apt install python3-pip
インストールしたpip3を以下コマンドを実行してアップグレードします。
$ pip3 install –-upgrade pip
Python(Django)の設定
NginxとPythonのパッケージをインストールできましたら、次にPython(Django)の設定を行います。
ここでは仮想環境を作成し、開発用Webサーバーの起動およびuWSGIを利用したアプリへのアクセスを行います。
pyvenvのインストール
仮想環境を作成するためのpyvenvをインストールします。
$ sudo apt install python3-venv
仮想環境については以下記事をご参照ください。
【Python】仮想環境の構築と有効化の方法
仮想環境の生成には対象のディレクトリに移動後、次のコマンドを実行します。ここでは仮想環境の名前をvenvとします。
$ python3 -m venv venv
仮想環境を生成したら、仮想環境を有効化するために以下コマンドを実行します。
$ source venv/bin/activate
ターミナルの先頭に(venv)が付けば、仮想環境が有効になっていることを意味します。
Djangoのインストールと設定
仮想環境内にdjangoパッケージをインストールします。以下コマンドは仮想環境を有効化した状態で実行してください。
(venv) $ pip3 install django
次にプロジェクトを作成します。ここではmyprojectというプロジェクトを作成します。現在のディレクトリ位置に注意してください。
(venv)$ pwd
/home/ubuntu
ここでは上記のディレクトリで以下コマンドを実行してプロジェクトを作成します。
(venv) $ django-admin startproject myproject .
次にmyprojectディレクトリに移動して、settings.pyを編集します。
(venv) $ cd myproject
(venv) $ sudo vim settings.py
# settings.py
# すべてのホストを許可
ALLOWED_HOSTS = ['*']
settings.pyのALLOWED_HOSTSにすべてのホストを許可する「*」(アスタリスク)を指定しました。
ALLOWED_HOSTSについて詳しく知りたい方は以下記事をご参照ください。
【Django】settings.py:ALLOWED_HOSTSとは(開発・本番環境)
開発用サーバーとして立ち上がるか確認するために、ポート8000番を開放します。
$ sudo ufw allow 8000
次にDjangoを開発サーバーで起動します。
(venv)$ python manage.py runserver 0.0.0.0:8000
同じネットワーク内の端末からラズパイのIPアドレス:8000にアクセスし、ブラウザからWebアプリにアクセスできるか確認します。
IPアドレス:8000/
きちんと起動していれば次の画像が表示されます。
uWSGIのインストール
次にuWSGIをインストールします。
uWSGIをインストールする前にwheelをpipでインストールします。wheelはuWSGIに必要なパッケージです。
(venv) $ pip install wheel
次にuWSGIをpipでインストールします。
(venv)$ pip install uwsgi
uWSGIを起動してuWSGI経由でDjangoプロジェクトを呼び出してみます。この際にプロジェクト内のwsgi.py(wsgiモジュール)を使用します。
(venv)$ uwsgi --http :8000 --module myproject.wsgi
上記コマンドはhttpプロトコルで通信を行い8000番ポートを使用、モジュールのmyproject配下のwsgiモジュールを使用、という意味です。
これで再度IPアドレス:8000にブラウザから接続して、先ほどと同じ画面が表示すればuWSGI経由でDjangoアプリと通信ができたことを意味します。
今の構成としては、以下のようにブラウザとWebアプリケーション(Django)はアプリケーションサーバ(uWSGI)を通して通信を行っています。
ブラウザ <―> アプリケーションサーバ(uWSGI)<―> Webアプリケーション(Django)
次にブラウザとuWSGIの間にNginx(Webサーバー)を上記構成に組み込みます。
Nginxの設定
Nginxの起動
現在仮想環境に入ったままなので、一旦deactivateコマンドで仮想環境から抜けます。
(venv)$ deactivate
NginxはすでにUbuntuにインストールしていますので、Nginxを起動してみましょう。
$ sudo /etc/init.d/nginx start
Nginxが起動できたらIPアドレス:80にアクセスしてください。「Welcome to nginx!」のページが表示されれば無事Nginxが起動されています。
uwsgi_paramsのコピー
/etc/nginxディレクトリにuwsgi_paramsというファイルがあります。これはuWSGI用のパラメータ定義ファイルです。
中身は次のようになっています。
uwsgi_param QUERY_STRING $query_string;
uwsgi_param REQUEST_METHOD $request_method;
uwsgi_param CONTENT_TYPE $content_type;
uwsgi_param CONTENT_LENGTH $content_length;
uwsgi_param REQUEST_URI $request_uri;
uwsgi_param PATH_INFO $document_uri;
uwsgi_param DOCUMENT_ROOT $document_root;
uwsgi_param SERVER_PROTOCOL $server_protocol;
uwsgi_param REQUEST_SCHEME $scheme;
uwsgi_param HTTPS $https if_not_empty;
uwsgi_param REMOTE_ADDR $remote_addr;
uwsgi_param REMOTE_PORT $remote_port;
uwsgi_param SERVER_PORT $server_port;
uwsgi_param SERVER_NAME $server_name;
それをプロジェクトディレクトリ(ここでは/home/ubuntu/myproject)にコピーします。
cp /etc/nginx/uwsgi_params /home/ubuntu/myproject/
設定ファイルの作成(confファイル)
次にmyproject用の設定ファイルmyproject_nginx.confを作成します。conf設定ファイルはNginx起動時に読み込まれます。
/etc/nginxディレクトリ配下のsites-availableディレクトリにconf設定ファイルを作成します。
sites-availableディレクトリとは、独自の設定ファイルを置くディレクトリです。
myproject_nginx.confは以下のように作成します。
$ cd /etc/nginx/sites-available
$ sudo vim myproject_nginx.conf
# myproject_nginx.conf
upstream django {
server 192.168.0.54:8001;
}
server {
listen 8000;
location / {
uwsgi_pass django;
include /home/ubuntu/myproject/uwsgi_params;
}
}
上記設定はご自身の設定に応じて適宜書き換えてください。ここではラズパイのipアドレスが192.168.0.54と想定して作成しています。
この設定によりポート番号8000に対してアクセスがきた際に、192.168.0.54:8001に通信を渡します。この後の設定で8001番ポートではuWSGIを動かします。
つまりnginxはuWSGIとの通信に8001番ポートを使うということです。
次に作成したconfファイルはプロジェクト内に複製します。
cp /etc/nginx/sites-available/myproject_nginx.conf /home/ubuntu/myproject
この複製したconf設定ファイルのシンボリックリンクを/etc/nginx/sites-enabledに作成します。sites-enabledディレクトリとは、独自設定ファイルのシンボリックリンクを格納するディレクトリです。
$ sudo ln -s /home/ubuntu/myproject/myproject_nginx.conf /etc/nginx/sites-enabled/
シンボリックリンクをsites-enabledディレクトリに格納することにより、Nginxが起動した際に作成した独自設定ファイルが読み込まれるようになります。
ここで一旦Nginxを再起動しておきましょう。
$ sudo /etc/init.d/nginx restart
uWSGIでDjangoアプリを呼び出す
最後にNginxとWebアプリケーションをつなぐ役割をするuWSGIを起動します。
次のようにuWSGIを起動してください。
$ cd /home/ubuntu
$ source venv/bin/activate
(venv)$ uwsgi --socket :8001 --module myproject.wsgi
これによりNginxからuWSGIを通してDjangoと通信を行えるようになりました。
これでipアドレス:8000にアクセスしてDjangoアプリが表示されれば問題なくWebサーバーの構築が完成したことを意味します。
Unixソケットでアクセス
ここまでの設定ではTCPポートソケットによる通信を行っています。TCPポートソケットではUnixソケットに比べてオーバーヘッドが多く、サーバーに負荷がかかってしまいます。
そこでUnixソケットで通信を行うように設定を変更します。conf設定ファイルのmyproject_nginx.confのupstream djangoを次のように変更します。
$ sudo vim /home/ubuntu/myproject/myproject_nginx.conf
# myproject_nginx.conf
upstream django {
server unix:///home/ubuntu/myproject/myproject.sock;
# server 172.254.99.57:8001;
}
conf設定ファイルを編集保存しましたら、再度Nginxを再起動します。
$ sudo /etc/init.d/nginx restart
次にuWSGIは以下のように起動します。
$ pwd
/home/ubuntu
$ source venv/bin/activate
(venv)$ uwsgi --socket /home/ubuntu/myproject/myproject.sock --module myproject.wsgi --chmod-socket=666
ipアドレス:8000にアクセスしてDjangoアプリが表示されれば、Unixソケットで通信が問題なく行われています。
もしうまくいかなかった場合はエラーログを確認してみてください。
$ sudo cat /var/log/nginx/error.log
iniファイルの作成
uWSGIの起動コマンドは長く、毎回記述するのが面倒くさいですよね。そこでコマンドを簡略化するためにiniファイルを作成します。
$ cd /home/ubuntu
$ sudo vim myproject_uwsgi.ini
ここではiniファイルは次のように記述しています。
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /home/ubuntu
# Django's wsgi file
module = myproject.wsgi
# the virtualenv (full path)
home = /home/ubuntu/venv
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = /home/ubuntu/myproject/myproject.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
# clear environment on exit
vacuum = true
あとは以下のコマンドを実行することでWebサーバーが起動します。
$ uwsgi --ini myproject_uwsgi.ini
もしバックグラウンドで起動したい場合は以下のように末尾に「&」を付けて実行します。
$ uwsgi --ini myproject_uwsgi.ini &
バックグラウンドで起動したプロセスを停止したい場合は、以下のようにコマンドを実行します。
$ ps -aux | grep uwsgi
$ kill -QUIT 上記コマンドで表示された一番上のプロセスのPID
静的ファイルの設定
現在の設定ではCSSといった静的ファイルを作成してもWebアプリケーションに適用されません。
静的ファイルを適用させるためにconf設定ファイルに静的ファイルの格納先を設定します。作成した独自設定ファイルのserverに以下を追加してください。
# myproject_nginx.conf
location /static {
alias /home/ubuntu/static;
}
次にsettings.pyにSTATIC_ROOTを設定します。
STATIC_ROOT = '/home/ubuntu/static'
manage.py collectstaticコマンドを実行して静的ファイルを/home/ubuntu/staticに集めます。
$ source venv/bin/activate
(venv)$ python manage.py collectstatic
あとはNginxを再起動することで静的ファイルが適応されるようになります。
manage.py collectstaticは静的ファイルを変更する度に実行するようにしてください。
まとめ
本記事「【Ubuntu(ラズパイ)】Django+Nginx+uWSGI構成のWebアプリケーション開発」はいかがでしたか。
ラズパイは社内用Webアプリケーションサーバーとして利用する分には、スペック的にも問題なく使うことができます。
ぜひ本記事を参考にしてラズパイでDjangoによるWebアプリケーションを構築してみてください。