Ubuntu14.04でuWSGIとNginxを使用してDjangoアプリケーションを提供する方法
序章
Djangoは、PythonアプリケーションまたはWebサイトを立ち上げるのに役立つ強力なWebフレームワークです。 Djangoには、コードをローカルでテストするための簡略化された開発サーバーが含まれていますが、本番環境に少しでも関連する場合は、より安全で強力なWebサーバーが必要です。
このガイドでは、Djangoアプリケーションをサポートおよび提供するためにUbuntu14.04にいくつかのコンポーネントをインストールして構成する方法を示します。 アプリケーションとインターフェイスするようにuWSGIアプリケーションコンテナサーバーを構成します。 次に、uWSGIにリバースプロキシするようにNginxを設定し、アプリを提供するためのセキュリティ機能とパフォーマンス機能にアクセスできるようにします。
前提条件と目標
このガイドを完了するには、sudo
権限が設定されたroot以外のユーザーがいる新しいUbuntu14.04サーバーインスタンスが必要です。 初期サーバーセットアップガイドを実行すると、これをセットアップする方法を学ぶことができます。
Djangoを2つの異なる仮想環境にインストールします。 これにより、プロジェクトとその要件を個別に処理できるようになります。 マルチプロジェクト環境で手順を実行できるように、2つのサンプルプロジェクトを作成します。
アプリケーションを入手したら、uWSGIアプリケーションサーバーをインストールして構成します。 これは、アプリケーションへのインターフェイスとして機能し、HTTPを使用してクライアントリクエストをアプリケーションが処理できるPython呼び出しに変換します。 次に、uWSGIの前にNginxをセットアップして、その高性能接続処理メカニズムと実装が容易なセキュリティ機能を利用します。
始めましょう。
VirtualEnvとVirtualEnvWrapperをインストールして構成します
Djangoプロジェクトを独自の仮想環境にインストールして、それぞれの要件を分離します。 これを行うために、Python仮想環境を作成できるvirtualenv
と、virtualenv
ワークフローにいくつかの使いやすさを追加するvirtualenvwrapper
をインストールします。
Pythonパッケージマネージャーであるpip
を使用して、これらのコンポーネントの両方をインストールします。 これは、Ubuntuリポジトリから取得できます。
sudo apt-get update
sudo apt-get install python-pip
このガイドでは、Pythonバージョン2を使用しています。 コードでPython3を使用している場合は、python3-pip
パッケージをインストールできます。 仮想環境の外部で操作する場合は、このガイドのpip
コマンドをpip3
コマンドに置き換える必要があります。
pip
がインストールされたので、次のように入力してvirtualenv
とvirtualenvwrapper
をグローバルにインストールできます。
sudo pip install virtualenv virtualenvwrapper
これらのコンポーネントがインストールされたら、virtualenvwrapper
スクリプトで動作するために必要な情報を使用してシェルを構成できます。 仮想環境はすべて、簡単にアクセスできるように、Env
というホームフォルダ内のディレクトリに配置されます。 これは、WORKON_HOME
と呼ばれる環境変数を介して構成されます。 これをシェル初期化スクリプトに追加して、仮想環境ラッパースクリプトを入手できます。
Python3とpip3
コマンドを使用している場合は、シェル初期化スクリプトにも次の行を追加する必要があります。
echo "export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3" >> ~/.bashrc
使用しているPythonのバージョンに関係なく、次のコマンドを実行する必要があります。
echo "export WORKON_HOME=~/Env" >> ~/.bashrc
echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.bashrc
次に、シェル初期化スクリプトを入手して、現在のセッションでこの機能を使用できるようにします。
source ~/.bashrc
これで、仮想環境情報を保持するEnv
というディレクトリがホームフォルダに作成されます。
Djangoプロジェクトを作成する
仮想環境ツールができたので、2つの仮想環境を作成し、それぞれにDjangoをインストールして、2つのプロジェクトを開始します。
最初のプロジェクトを作成する
virtualenvwrapper
スクリプトで使用できるコマンドを使用すると、仮想環境を簡単に作成できます。
次のように入力して、最初のサイトまたはプロジェクトの名前で最初の仮想環境を作成します。
mkvirtualenv firstsite
これにより、仮想環境が作成され、その中にPythonとpip
がインストールされ、環境がアクティブ化されます。 プロンプトが変わり、新しい仮想環境内で操作していることを示します。 (firstsite)user@hostname:~$
のようになります。 括弧内の値は、仮想環境の名前です。 pip
を介してインストールされたソフトウェアはすべて、グローバルシステムではなく、仮想環境にインストールされるようになります。 これにより、プロジェクトごとにパッケージを分離できます。
最初のステップは、Django自体をインストールすることです。 これは仮想環境にローカルにインストールするため、sudo
なしでpip
を使用できます。
pip install django
Djangoをインストールしたら、次のように入力して最初のサンプルプロジェクトを作成できます。
cd ~
django-admin.py startproject firstsite
これにより、ホームディレクトリ内にfirstsite
というディレクトリが作成されます。 この中には、プロジェクトのさまざまな側面を処理するために使用される管理スクリプトと、実際のプロジェクトコードを格納するために使用される同じ名前の別のディレクトリがあります。
サンプルプロジェクトの最小要件の設定を開始できるように、第1レベルのディレクトリに移動します。
cd ~/firstsite
データベースを移行して、プロジェクトで使用するSQLiteデータベースを初期化することから始めます。 必要に応じて、アプリケーションの代替データベースを設定できますが、これはこのガイドの範囲外です。
./manage.py migrate
これで、プロジェクトディレクトリにdb.sqlite3
というデータベースファイルが作成されます。 これで、次のように入力して管理ユーザーを作成できます。
./manage.py createsuperuser
ユーザー名を選択し、連絡先の電子メールアドレスを指定してから、パスワードを選択して確認する必要があります。
次に、テキストエディタでプロジェクトの設定ファイルを開きます。
nano firstsite/settings.py
サイトにサービスを提供するようにNginxを設定するため、サイトの静的アセットを保持するディレクトリを構成する必要があります。 これにより、Nginxがこれらを直接提供できるようになり、パフォーマンスにプラスの影響があります。 これらをプロジェクトのベースディレクトリのstatic
というディレクトリに配置するようにDjangoに指示します。 この動作を構成するには、ファイルの最後に次の行を追加します。
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
終了したら、ファイルを保存して閉じます。 次に、サイトの静的要素を収集し、次のように入力してそのディレクトリ内に配置します。
./manage.py collectstatic
「yes」と入力して、アクションを確認し、静的コンテンツを収集できます。 プロジェクトディレクトリにstatic
という新しいディレクトリが作成されます。
これらすべてが終わったら、開発サーバーを一時的に起動してプロジェクトをテストできます。 タイプ:
./manage.py runserver 0.0.0.0:8080
これにより、ポート8080
で開発サーバーが起動します。 サーバーのドメイン名またはIPアドレスにアクセスし、続いてブラウザで8080
にアクセスします。
http://server_domain_or_IP:8080
次のようなページが表示されます。
ブラウザのアドレスバーのURLの末尾に/admin
を追加すると、管理者ログインページに移動します。
createsuperuser
コマンドで選択した管理ログイン資格情報を使用して、サーバーにログインします。 これで、管理インターフェースにアクセスできるようになります。
この機能をテストした後、ターミナルでCTRL-Cを入力して、開発サーバーを停止します。 これで、2番目のプロジェクトに進むことができます。
2番目のプロジェクトを作成する
2番目のプロジェクトは、最初のプロジェクトとまったく同じ方法で作成されます。 このセクションの説明は、あなたがすでにこれをどのように完了したかを見て、簡略化します。
ホームディレクトリに戻り、新しいプロジェクト用の2番目の仮想環境を作成します。 アクティベートされたら、この新しい環境内にDjangoをインストールします。
cd ~
mkvirtualenv secondsite
pip install django
新しい環境が作成され、とがに変更され、以前の仮想環境が残ります。 このDjangoインスタンスは、構成した他のインスタンスとは完全に分離されています。 これにより、それらを個別に管理し、必要に応じてカスタマイズできます。
2番目のプロジェクトを作成し、プロジェクトディレクトリに移動します。
django-admin.py startproject secondsite
cd ~/secondsite
データベースを初期化し、管理ユーザーを作成します。
./manage.py migrate
./manage.py createsuperuser
設定ファイルを開きます。
nano secondsite/settings.py
前のプロジェクトで行ったように、静的ファイルの場所を追加します。
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
ファイルを保存して閉じます。 次に、次のように入力して、静的要素をそのディレクトリに収集します。
./manage.py collectstatic
最後に、開発サーバーを起動してサイトをテストします。
./manage.py runserver 0.0.0.0:8080
次の通常のサイトを確認する必要があります。
http://server_domain_or_IP:8080
また、管理サイトにログインします。
http://server_domain_or_IP:8080/admin
すべてが期待どおりに機能していることを確認したら、ターミナルでCTRL-Cを入力して、開発サーバーを停止します。
仮想環境からのバックアウト
これでガイドのDjangoの部分が終了したので、2番目の仮想環境を非アクティブ化できます。
deactivate
いずれかのDjangoサイトで再度作業する必要がある場合は、それぞれの環境を再アクティブ化する必要があります。 workon
コマンドを使用してこれを行うことができます。
workon firstsite
または:
workon secondsite
繰り返しますが、サイトでの作業が終了したら非アクティブ化します。
deactivate
uWSGIアプリケーションサーバーのセットアップ
2つのDjangoプロジェクトをセットアップして準備ができたので、uWSGIを構成できます。 uWSGIは、WSGIと呼ばれる標準インターフェイスを介してアプリケーションと通信できるアプリケーションサーバーです。 これについて詳しくは、Ubuntu14.04でのuWSGIとNginxのセットアップに関するガイドのこのセクションをお読みください。
uWSGIのインストール
上記のリンク先のガイドとは異なり、このチュートリアルでは、uWSGIをグローバルにインストールします。 これにより、複数のDjangoプロジェクトを処理する際の摩擦が少なくなります。 uWSGIをインストールする前に、ソフトウェアが依存するPython開発ファイルが必要です。 これはUbuntuのリポジトリから直接インストールできます。
sudo apt-get install python-dev
開発ファイルが利用可能になったので、次のように入力して、pip
を介してuWSGIをグローバルにインストールできます。
sudo pip install uwsgi
このアプリケーションサーバーは、いずれかのサイトの情報を渡すことですばやくテストできます。 たとえば、次のように入力することで、最初のプロジェクトを提供するように指示できます。
uwsgi --http :8080 --home /home/user/Env/firstsite --chdir /home/user/firstsite -w firstsite.wsgi
ここでは、~/Env
ディレクトリにある仮想環境を使用し、プロジェクトのディレクトリに移動し、内部のfirstsite
内に保存されているwsgi.py
ファイルを使用するようにuWSGIに指示しました。 ]ファイルを提供するディレクトリ。 デモンストレーションでは、ポート8080
でHTTPを提供するように指示しました。 ブラウザでサーバーのドメイン名またはIPアドレスに移動し、続いて:8080
に移動すると、サイトが再び表示されます(/admin
インターフェイスの静的要素はまだ機能しません)。 この機能のテストが終了したら、ターミナルにCTRL-Cと入力します。
構成ファイルの作成
コマンドラインからuWSGIを実行することはテストには役立ちますが、実際の展開には特に役立ちません。 代わりに、uWSGIを「エンペラーモード」で実行します。これにより、マスタープロセスは、構成ファイルのセットを指定して、個別のアプリケーションを自動的に管理できます。
構成ファイルを保持するディレクトリを作成します。 これはグローバルプロセスであるため、構成ファイルを保存するために/etc/uwsgi/sites
というディレクトリを作成します。 作成後、ディレクトリに移動します。
sudo mkdir -p /etc/uwsgi/sites
cd /etc/uwsgi/sites
このディレクトリに、構成ファイルを配置します。 提供しているプロジェクトごとに構成ファイルが必要です。 uWSGIプロセスは、さまざまな形式の構成ファイルを受け取ることができますが、単純さのために.ini
ファイルを使用します。
最初のプロジェクトのファイルを作成し、テキストエディタで開きます。
sudo nano firstsite.ini
内部では、[uwsgi]
セクションヘッダーから始める必要があります。 すべての情報はこのヘッダーの下に表示されます。 また、変数を使用して、構成ファイルをより再利用しやすくします。 ヘッダーの後に、最初のプロジェクトの名前を使用してproject
という変数を設定します。 base
という変数を、ユーザーのホームディレクトリへのパスとともに追加します。
[uwsgi]
project = firstsite
base = /home/user
次に、プロジェクトを正しく処理するようにuWSGIを構成する必要があります。 chdir
オプションを設定して、ルートプロジェクトディレクトリに変更する必要があります。 %(variable_name)
構文を使用して、前に設定したホームディレクトリとプロジェクト名の設定を組み合わせることができます。 これは、構成が読み取られるときに変数の値に置き換えられます。
同様の方法で、プロジェクトの仮想環境を示します。 モジュールを設定することで、プロジェクトとのインターフェース方法を正確に示すことができます(プロジェクトディレクトリ内のwsgi.py
ファイルから呼び出し可能な「アプリケーション」をインポートすることにより)。 これらのアイテムの構成は次のようになります。
[uwsgi]
project = firstsite
base = /home/user
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
5人のワーカーでマスタープロセスを作成したいと思います。 これを追加することでこれを行うことができます:
[uwsgi]
project = firstsite
base = /home/user
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
次に、uWSGIが接続をリッスンする方法を指定する必要があります。 uWSGIのテストでは、HTTPとネットワークポートを使用しました。 ただし、リバースプロキシとしてNginxを使用するため、より適切なオプションがあります。
ネットワークポートを使用する代わりに、すべてのコンポーネントが単一のサーバーで動作しているため、Unixソケットを使用できます。 これはより安全で、より良いパフォーマンスを提供します。 このソケットはHTTPを使用しませんが、代わりにuWSGIのuwsgi
プロトコルを実装します。これは、他のサーバーと通信するために設計された高速バイナリプロトコルです。 Nginxはuwsgi
プロトコルを使用してネイティブにプロキシできるため、これが最善の選択です。
また、Webサーバーに書き込みアクセスを許可するため、ソケットのアクセス許可も変更します。 vacuum
オプションを設定して、サービスが停止したときにソケットファイルが自動的にクリーンアップされるようにします。
[uwsgi]
project = firstsite
base = /home/user
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
socket = %(base)/%(project)/%(project).sock
chmod-socket = 664
vacuum = true
これで、最初のプロジェクトのuWSGI構成が完了しました。 ファイルを保存して閉じます。
変数を使用してファイルを設定する利点は、再利用が非常に簡単になることです。 最初のプロジェクトの構成ファイルをコピーして、2番目の構成ファイルのベースとして使用します。
sudo cp /etc/uwsgi/sites/firstsite.ini /etc/uwsgi/sites/secondsite.ini
テキストエディタで2番目の構成ファイルを開きます。
sudo nano /etc/uwsgi/sites/secondsite.ini
2番目のプロジェクトで機能させるには、このファイルの1つの値を変更するだけで済みます。 project
変数を、2番目のプロジェクトで使用した名前に変更します。
[uwsgi]
project = secondsite
base = /home/user
chdir = %(base)/%(project)
home = %(base)/Env/%(project)
module = %(project).wsgi:application
master = true
processes = 5
socket = %(base)/%(project)/%(project).sock
chmod-socket = 664
vacuum = true
終了したら、ファイルを保存して閉じます。 2番目のプロジェクトは今すぐ準備ができているはずです。
uWSGIのアップスタートスクリプトを作成する
これで、Djangoプロジェクトを提供するために必要な構成ファイルができましたが、プロセスはまだ自動化されていません。 次に、起動時にuWSGIを自動的に起動するUpstartスクリプトを作成します。
/etc/init
ディレクトリにUpstartスクリプトを作成します。ここで、これらのファイルがチェックされます。
sudo nano /etc/init/uwsgi.conf
まず、uWSGIサービスの説明を設定し、自動的に実行するランレベルを指定します。 従来のマルチユーザーランレベルであるランレベル2、3、4、および5で実行するように設定します。
description "uWSGI application server in Emperor mode"
start on runlevel [2345]
stop on runlevel [!2345]
次に、プロセスを実行するユーザー名とグループを設定する必要があります。 すべてのファイルを所有しているため、独自のユーザー名でプロセスを実行します。 グループについては、Nginxが実行されるwww-data
グループに設定する必要があります。 uWSGI構成ファイルのソケット設定により、Webサーバーがソケットに書き込むことができるようになります。 サーバー上のユーザー名と一致するように、以下のユーザー名を変更します。
description "uWSGI application server in Emperor mode"
start on runlevel [2345]
stop on runlevel [!2345]
setuid user
setgid www-data
最後に、実行する実際のコマンドを指定する必要があります。 uWSGIをEmperorモードで起動し、構成ファイルを保存したディレクトリに渡す必要があります。 uWSGIはファイルを読み取り、各プロジェクトにサービスを提供します。
description "uWSGI application server in Emperor mode"
start on runlevel [2345]
stop on runlevel [!2345]
setuid user
setgid www-data
exec /usr/local/bin/uwsgi --emperor /etc/uwsgi/sites
終了したら、ファイルを保存して閉じます。 Nginxをインストールするまでwww-data
グループを利用できないため、uWSGIはまだ起動しません。
Nginxをリバースプロキシとしてインストールおよび構成する
uWSGIを構成して準備ができたら、Nginxをリバースプロキシとしてインストールして構成できます。 これは、Ubuntuのデフォルトのリポジトリからダウンロードできます。
sudo apt-get install nginx
Nginxをインストールしたら、プロジェクトごとにサーバーブロック構成ファイルを作成できます。 サーバーブロック構成ファイルを作成して、最初のプロジェクトから開始します。
sudo nano /etc/nginx/sites-available/firstsite
内部では、最初のプロジェクトにアクセスできるポート番号とドメイン名を指定することで、サーバーブロックを開始できます。 それぞれにドメイン名があると想定します。
server {
listen 80;
server_name firstsite.com www.firstsite.com;
}
次に、ファビコンが見つからなくても心配しないようにNginxに指示できます。 また、サイトの静的要素を収集した静的ファイルディレクトリの場所も示します。
server {
listen 80;
server_name firstsite.com www.firstsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/firstsite;
}
}
その後、uwsgi_pass
ディレクティブを使用して、トラフィックをソケットファイルに渡すことができます。 構成したソケットファイルはfirstproject.sock
と呼ばれ、プロジェクトディレクトリにありました。 include
ディレクティブを使用して、接続を処理するために必要なuwsgi
パラメーターを含めます。
server {
listen 80;
server_name firstsite.com www.firstsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/firstsite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/firstsite/firstsite.sock;
}
}
実際に必要な構成はこれですべてです。 終了したら、ファイルを保存して閉じます。
これを2番目のプロジェクトのNginx構成ファイルの基礎として使用します。 今すぐコピーしてください:
sudo cp /etc/nginx/sites-available/firstsite /etc/nginx/sites-available/secondsite
テキストエディタで新しいファイルを開きます。
sudo nano /etc/nginx/sites-available/secondsite
ここでは、firstsite
への参照をsecondsite
への参照に変更する必要があります。 また、server_name
を変更して、2番目のプロジェクトが別のドメイン名に応答するようにする必要があります。 終了すると、次のようになります。
server {
listen 80;
server_name secondsite.com www.secondsite.com;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user/secondsite;
}
location / {
include uwsgi_params;
uwsgi_pass unix:/home/user/secondsite/secondsite.sock;
}
}
終了したら、ファイルを保存して閉じます。
次に、両方の新しい構成ファイルをNginxのsites-enabled
ディレクトリにリンクして、次の機能を有効にします。
sudo ln -s /etc/nginx/sites-available/firstsite /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/secondsite /etc/nginx/sites-enabled
次のように入力して、構成構文を確認します。
sudo service nginx configtest
構文エラーが検出されない場合は、Nginxサービスを再起動して、新しい構成をロードできます。
sudo service nginx restart
以前から覚えていると思いますが、実際にuWSGIサーバーを起動したことはありません。 次のように入力して、今すぐ実行してください。
sudo service uwsgi start
これで、それぞれのドメイン名に移動して、2つのプロジェクトにアクセスできるようになります。 パブリックインターフェイスと管理インターフェイスの両方が期待どおりに機能するはずです。
結論
このガイドでは、それぞれ独自の仮想環境に2つのDjangoプロジェクトを設定しました。 それぞれに構成された仮想環境を使用して、各プロジェクトに個別にサービスを提供するようにuWSGIを構成しました。 その後、クライアント接続を処理し、クライアントの要求に応じて正しいプロジェクトを提供するリバースプロキシとして機能するようにNginxを設定します。
Djangoは、多くの一般的な要素を提供することでプロジェクトとアプリケーションの作成を簡単にし、独自の要素に集中できるようにします。 この記事で説明する一般的なツールチェーンを活用することで、単一のサーバーから作成したアプリケーションを簡単に提供できます。