【Ubuntu(ラズパイ)】Django+Nginx+uWSGI構成のWebアプリケーション開発

2021.12.11 /

【Ubuntu(ラズパイ)】Django+Nginx+uWSGI構成のWebアプリケーション開発

本記事ではRaspberry Pi(OSとしてUbuntu)でDjangoを使ったWebアプリケーション構築方法について解説していきます。

構成はWebサーバーにNginx、アプリケーションサーバーにuWSGI、WebアプリケーションにDjangoを利用しています。

ここで使用するUbuntuはUbuntu Server 20.04.3 LTSです。

Raspberry Pi(通称ラズパイ)にUbuntuをインストールする方法は以下記事をご参照ください。

私は社内WebアプリケーションサーバーとしてDjangoをインストールしたラズパイを使うことが多いです。

ここでは私がUbuntuでDjangoを動かすときの構築方法を詳しく解説していきます。Webサーバーを起動し、初期画面を表示させるところまで解説します。

Webアプリケーションの構成

私はWebサーバーにNginx、アプリケーションサーバーにuWSGI、WebアプリケーションにDjangoを利用しています。

この構成ではブラウザがサーバーにリクエストを送り、レスポンスが返ってくるまでの流れは次のようになります。

ブラウザ <―> Webサーバー(Nginx)<―> Unixソケット <―> アプリケーションサーバー(uWSGI)<―> Webアプリケーション(Djangoなど)

Webアプリケーション(DjangoやFlask)+Nginx+uWSGI構成

ブラウザからのリクエストはNginxで受け取り、Nginxはsocketを通してuWSGIに渡します。

Nginx

NginxとはOSS(Open Source Software)のWebサーバーソフトウェアです。

近年WebサーバーとしてNginxを利用する人が急増しており、現在ではApacheに次いで2位のシェアを誇ります。
*2020年8月にNetcraftという会社が出した調査によるとNginxがApacheを抜きシェア1位になったみたいです。

Nginxの詳しい設定ファイルについては以下記事をご参照ください。

uWSGI

DjangoやFlaskといったWebアプリケーションフレームワークを利用する際、WebサーバーとWebアプリケーションフレームワークを繋ぐインターフェースが必要となります。

このインターフェースの定義をWSGI(Web Server Gateway Interface)といいます。

そしてWSGIをサポートするサーバーの一つがuWSGIです。

uWSGIは通信方法として、UNIXドメインソケットまたはHTTPでの通信をサポートしています。

Django

DjangoはPythonによるWebフレームワークの一つです。Webアプリケーション開発を簡単にする様々な機能を有します。

PythonWebフレームワークの中では人気・知名度が最も高いです。Djangoについてより詳しい説明は以下記事をご参照ください。

パッケージのインストール

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をインストールする方法は以下記事で詳しく解説しております。

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

仮想環境については以下記事をご参照ください。

仮想環境の生成には対象のディレクトリに移動後、次のコマンドを実行します。ここでは仮想環境の名前を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について詳しく知りたい方は以下記事をご参照ください。

開発用サーバーとして立ち上がるか確認するために、ポート8000番を開放します。

$ sudo ufw allow 8000

次にDjangoを開発サーバーで起動します。

(venv)$ python manage.py runserver 0.0.0.0:8000

同じネットワーク内の端末からラズパイのIPアドレス:8000にアクセスし、ブラウザからWebアプリにアクセスできるか確認します。

IPアドレス:8000/

きちんと起動していれば次の画像が表示されます。

django初期画面

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アプリと通信ができたことを意味します。

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が起動されています。

Nginx:Welcome to 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アプリケーションを構築してみてください。