NGINX Conf 2018:本番アプリケーション向けNGINX Unitの設定—Djangoプロジェクトの配信

NGINX | 2018年11月28日

NGINX Unitは、複数の言語に加え、各言語の複数のバージョンにも対応できる、完全に動的なアプリケーションサーバーです。RESTful JSON APIを使用してメモリ内の構成を変更でき、サービスを中断したり構成を再読み込みしたりする必要がないという点で動的です。

10月のNGINX Conf 2018で行ったプレゼンテーションでは、既存の本番環境に新しいアプリケーションを構成する方法を紹介しました。具体的には、PHPでWordPressが稼働している環境に、Djangoフレームワークを使用するPythonアプリケーションをデプロイしました。また、ファイルから構成を読み込む方法と、API呼び出しの引数で指定して読み込む方法も紹介しました。

このブログには、独自の環境に合わせて容易に調整できるよう、デモで使用したすべてのコマンドと設定コードを掲載しています。

前提条件

NGINX Confでのデモに向けて、以下のソフトウェアをインストールしました。

  • Ubuntu 16.04
  • NGINX Plus。ただし、特に記載がない限り、NGINX Open Sourceも使用できます
  • NGINX Unit(すべての言語モジュールをインストール済み)
  • Python 3
  • Django(未設定。このデモとブログでは、その設定方法を取り上げます)
  • root権限、またはsudoによる同等のアクセス権(必要に応じて使用)

また、既存のアプリケーションとしてPHPとWordPressをインストールしていました。

Djangoプロジェクトの作成

  1. Djangoプロジェクトを作成するディレクトリに移動します:
$ cd /var/www/
  1. 新しいプロジェクトを初期化するには、django-adminのstartprojectコマンドを使用します。プロジェクト名は「djapp」とします。
$ sudo django-admin startproject djapp
  1. プロジェクトディレクトリに移動します:
$ cd djapp
  1. 新しく作成したプロジェクトに必要なデータベースの移行を行うには、manage.pyスクリプトを使用します。DjangoではデフォルトでSQLiteが使用され、このデモでもデフォルト設定を採用していますが、プロジェクトのニーズを満たす任意のデータベースを使用できます。manage.pyスクリプトは、ステップ2で実行したdjango-adminコマンドによってインストールされます。django-adminと同じコマンドを実行し、同じ引数を受け付けますが、プロジェクト固有の一部の設定を自動的に取得して使用できるため便利です。詳しくは、Djangoドキュメントを参照してください。
$ sudo python3 manage.py migrate
  1. このようなサンプルプロジェクトでは必須ではありませんが、Djangoの「superuser」アカウントを作成することを推奨します。
$ sudo python3 manage.py createsuperuser
  1. ステップ2でsettings.pyファイルが作成されたサブディレクトリに移動します。このファイルは、django-adminのstartprojectコマンドによって作成されたものです。
$ cd /var/www/djapp/djapp
  1. 任意のテキストエディターでsettings.pyを開きます。ここではnanoを使用します:
$ sudo nano settings.py
  1. Find the ALLOWED_HOSTSの行を見つけ、アプリケーションのドメイン名、ホスト名、またはIPアドレスを追加します:
ALLOWED_HOSTS = ['domain-name']
  1. さらに、アプリケーションが配信するすべての静的コンテンツを格納するディレクトリを指定するため、ファイルの末尾に次の行を追加します(ステップ9を参照)。
STATIC_ROOT = '/var/www/djapp/djapp/static'
  1. メインプロジェクトディレクトリ(manage.pyがあるディレクトリ)に戻ります。
$ cd ..
  1. Djangoプロジェクト内のすべての静的ファイルを収集し、手順7で定義したmanage.pyのcollectstaticコマンドを実行して、STATIC_ROOTに配置します。
$ sudo python3 manage.py collectstatic

NGINXの設定

デフォルトでは、Django自体がプロジェクトの静的コンテンツを配信しますが、NGINX Open SourceとNGINX Plusを使用すると、より高いパフォーマンスが得られます。ここではNGINX Plusを設定しますが、以下に記載する1つの機能を除き、NGINX Open Sourceも使用できます。

  1. ディレクトリを「/etc/nginx/conf.d」に移動します。ここは、機能別(この例ではアプリケーション別)のHTTP設定ファイルを配置する一般的な場所です:
$ cd /etc/nginx/conf.d
  1. 次に、django.confという名前のファイルを作成します(ここでもnanoを使用します)。
$ sudo nano django.conf
  1. キャッシュを有効にするため、次の設定を挿入します。この設定には、NGINX Plus専用の機能も2つ含まれています。NGINX Plusを使用していて、これらの機能を利用する場合は、該当するディレクティブのコメントを解除してください。なお、NGINX Confのデモでは、proxy_set_headerディレクティブの第2引数にローカルマシンのIPアドレスを指定しました。本番環境では、以下のように$host変数を使用する方が適切です。
# Upstream group for the backend (NGINX Unit running the Python application)
upstream django_unit {
    zone django_unit 64k;
    server 127.0.0.1:8000;
}
 
server {
    listen 8080;
    # Uncomment to collect metrics if using NGINX Plus and the NGINX Plus API
    #status_zone django;
      	
    # enable caching
    proxy_cache django_cache;
    proxy_cache_valid 200 60m;
 
    # root directory for static files
    root /var/www/djapp/djapp;
 
    # proxy to the NGINX Unit backend
    location / {
        proxy_pass http://django_unit;

        # Second argument must match your production hostname and the value of 
        # ALLOWED_HOSTS in settings.py
        proxy_set_header Host $host; 
 
        # Uncomment to enable active health checks if using NGINX Plus
        #health_check;
    }

    # Location for the static files collected from Django and served by 
    # NGINX Plus; can be empty (as here), because it inherits the value of the 
    # 'root' directive from its parent block
    location /static {
    }
}
  1. 設定の構文が有効であることを確認します:
$ sudo nginx –t
  1. エラーを修正した後、設定を再読み込みします:
$ sudo nginx -s reload

NGINX Unitの設定

最後に、アプリケーションへのリクエストを処理するようにNGINX Unitを設定する必要があります。

  1. 次のcurlコマンドを実行して、PHP上で動作するWordPress用の現在のNGINX Unit構成を表示します。ここでは出力を示しませんが、WordPressの構成は、これから追加するPythonアプリケーションの構成とともに、後述のステップ6に記載されています。なお、このsudoはcurlコマンドに使用しています。通常、ほとんどのcurlコマンドでは不要ですが、ここではUNIXソケットにアクセスするために、rootが持つ読み取り/書き込み権限が必要です。
$ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/
  1. NGINX Unitの設定ファイルがあるディレクトリに移動します。これらのファイルは必須ではなく、NGINX Unit APIの呼び出し時にすべてのデータを引数として入力せずに、一連の設定を読み込むための便利な手段にすぎない点に注意してください。ファイルの内容は、すべての設定データと同様にAPI経由でアップロードされるため、NGINX Unitはファイルの場所を認識せず、起動時にファイルを自動的に読み込むことはできません(NGINX Open SourceおよびNGINX Plusとは異なります)。代わりに、NGINX Unitは実行時の状態を別のディレクトリに保存します。
$ cd /etc/unit
  1. 次の名前のファイルを作成します:django.config(ここでもnanoを使用します)
$ sudo nano django.config
  1. Pythonアプリケーションを表す次のJSONを追加します。
{
      "type": "python",
      "processes": 5,
      "module": "djapp.wsgi",
      "path": "/var/www/djapp"
}
  1. 次のcurlコマンドを実行し、django.configに含まれるJSONを、NGINX Unitで管理する新しいアプリケーションオブジェクトとして読み込み、名前を「djapp」とします:
$ sudo curl -X PUT --data-binary @/etc/unit/django.config --unix-socket /run/control.unit.sock http://localhost/config/applications/djapp
  1. このコマンドでは:
    • HTTPの「PUT」メソッドは、最後の引数(URL)で指定された場所に新しいNGINX Unit構成オブジェクトを作成します。以下の最後の箇条書きを参照してください。
    • The --data-binary引数は、curlに対し、django.configの内容を、改行とキャリッジリターンを保持し、いかなる処理も行わず、指定されたとおりに読み込むよう指示します。
    • The --unix-socket引数は、NGINX Unit APIのリッスン先を指定します。(ソケットのデフォルト所有者であるsudoコマンドを使用するのは、rootを使用しているためです。)
    • 最後の引数では、django.config内のJSON形式の構成データを設定する新しいアプリケーションオブジェクトの場所と名前を指定します。configはNGINX Unitの最上位の構成オブジェクト、applicationsはアプリケーションオブジェクトの親、djappは新しいアプリケーションオブジェクトの名前です。
  2. アプリケーションのリスナーオブジェクトを定義します。ステップ4のように設定データのファイルを読み込むのではなく、データをcurlコマンドラインで直接定義し、djappアプリケーションがポート8000でリッスンするように指定します。
$ sudo curl -X PUT --data-binary '{"application":"djapp"}' --unix-socket /run/control.unit.sock 'http://localhost/config/listeners/*:8000'
  1. ステップ1のcurlコマンドを再度実行して、NGINX Unitの設定を表示します。設定にはPythonアプリケーション「djapp」が追加されており、オレンジ色で強調表示されています。
$ sudo curl --unix-socket /run/control.unit.sock http://localhost/config/{
      "listeners": {
            "127.0.0.1:8090": {
                  "application": "script_index_php"
            },
 
            "127.0.0.1:8091": {
                  "application": "direct_php"
            },
 
            "*:8000": { "application": "djapp" }
      },
 
      "applications": {
            "script_index_php": {
                  "type": "php",
                  "processes": {
                        "max": 20,
                        "spare": 5
                   },
 
                  "user": "www-data",
                  "group": "www-data",
                  "root": "/var/www/wordpress",
                  "script": "index.php"
            },
 
            "direct_php": {
                  "type": "php",
                  "processes": {
                        "max": 5,
                        "spare": 0
                  },
 
                  "user": "www-data",
                  "group": "www-data",
                  "root": "/var/www/wordpress",
                  "index": "index.php"
                  },
 
            "djapp": { "type": "python", "processes": 5, "module": "djapp.wsgi", "path": "/var/www/djapp" }
      }
}

まとめ

この記事では、まず本番環境のWordPress向けPHPアプリケーションをNGINX Unitで実行し、そこにPythonアプリケーションを追加しました。デモではNGINX Plusダッシュボードを使用し、新しいアプリケーションを追加しても既存のアプリケーションが中断されないことを示しています。この確認には、psコマンドなど、任意のシステム監視ツールを使用できます。NGINX Unitの動的な設定により、実行中のアプリケーションのリソースを節約できるほか、新規デプロイ時のダウンタイムをゼロに抑え、アプリケーションのバージョン間をスムーズに移行できます。

詳細については、unit.nginx.orgをご覧ください。


共有
タグ: Python, F5 NGINX, Tech

関連するブログ記事

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
NGINX | 2024/01/18

チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する

OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
NGINX | 2023/05/31

AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正

Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
NGINX | 2023/02/09

JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法

Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINX | 2022/05/24

F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング

NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
NGINX | 2018/08/17

SELinuxでNGINXおよびNGINX Plusを使用する

Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。

NGINX PlusによるAWS Auto Scalingグループの負荷分散
NGINX | 2017/03/06

NGINX PlusによるAWS Auto Scalingグループの負荷分散

新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります