デビアン11でDjangoをPostgres、Nginx、Gunicornと共にセットアップする方法
はじめに
Djangoは、Pythonのアプリケーションやウェブサイトを立ち上げるのに役立つ強力なウェブフレームワークです。Djangoには、コードをローカルでテストするための開発サーバーが含まれていますが、本番に関連するものは、より安全でパワフルなウェブサーバーが必要です。
このガイドでは、Debian 11でいくつかのコンポーネントをインストールして設定し、Djangoアプリケーションをサポート・公開します。デフォルトのSQLiteデータベースの代わりに、PostgreSQLデータベースを設定します。また、アプリケーションとやり取りするためにGunicornアプリケーションサーバーを設定します。そして、アクセス可能なセキュリティ機能とパフォーマンス機能を持つNginxを設定し、Gunicornへの逆プロキシを行います。これにより、アプリケーションを提供するために必要な機能が得られます。
前提条件と目標
このガイドを完了するためには、基本的なファイアウォールとsudo権限が設定されたnon-rootユーザーを持った新鮮なDebian 11サーバーインスタンスが必要です。初期サーバーセットアップガイドを実行することで、これを設定する方法を学ぶことができます。
仮想環境内にDjangoをインストールします。プロジェクト固有の環境にDjangoをインストールすることで、プロジェクトとその要件を別々に管理することができます。
データベースとアプリケーションが稼働している状態になったら、Gunicornアプリケーションサーバーをインストールして設定します。これは、クライアントのHTTPリクエストをPythonの呼び出しに変換し、アプリケーションが処理できるようにするためのインターフェースとして機能します。その後、高性能な接続処理メカニズムとセキュリティ機能を活用するために、Gunicornの前にNginxを設定します。
始めましょう。
Debianリポジトリからパッケージをインストールする
プロセスを開始するには、Debianのリポジトリから必要なすべてのアイテムをダウンロードしてインストールします。後でPythonパッケージマネージャーであるpipを使用して追加のコンポーネントをインストールします。
最初に、ローカルなaptパッケージインデックスを更新してから、パッケージをダウンロードしてインストールする必要があります。
- sudo apt update
- sudo apt install python3-venv python3-dev libpq-dev postgresql postgresql-contrib nginx curl
このコマンドは、Pythonプロジェクトの仮想環境を作成するためのツール、後でGunicornをビルドするために必要なPython開発ファイル、Postgresデータベースシステムとそれとの相互作用に必要なライブラリ、およびNginxウェブサーバーをインストールします。
PostgreSQLのデータベースとユーザーを作成する。
今では、直接データベースとデータベースユーザーを作成して、Djangoアプリケーションを始めることができます。
デフォルトでは、Postgresはローカル接続に対して「ピア認証」と呼ばれる認証方式を使用します。要するに、ユーザーのオペレーティングシステムのユーザー名が有効なPostgresのユーザー名と一致する場合、そのユーザーは追加の認証なしでログインできます。
Postgresのインストール中に、postgresという名前のオペレーティングシステムのユーザーが作成されました。これはpostgresのPostgreSQL管理ユーザーに対応しています。管理タスクを実行するためには、このユーザーを使用する必要があります。sudoを使用し、-uオプションでユーザー名を渡すことができます。
「タイプして、インタラクティブなPostgresセッションにログインしてください。」
- sudo -u postgres psql
私たちの要件を設定できるように、PostgreSQLのプロンプトが提供されます。
最初に、プロジェクト用のデータベースを作成してください。
- CREATE DATABASE myproject;
Note
次に、プロジェクト用のデータベースユーザーを作成してください。安全なパスワードを選択してください。
- CREATE USER myprojectuser WITH PASSWORD ‘password‘;
その後、作成したユーザーのいくつかの接続パラメータを変更します。これにより、データベースの処理が高速化され、接続が確立される度に正しい値を問い合わせて設定する必要がなくなります。
Djangoが期待するように、デフォルトの文字エンコーディングをUTF-8に設定します。また、デフォルトのトランザクション分離方式を「読み取りコミット」に設定し、未確定のトランザクションからの読み取りをブロックします。最後に、タイムゾーンを設定します。デフォルトでは、DjangoプロジェクトはUTCを使用するように設定されます。これらは全てDjangoプロジェクト自体からの推奨事項です。
- ALTER ROLE myprojectuser SET client_encoding TO ‘utf8’;
- ALTER ROLE myprojectuser SET default_transaction_isolation TO ‘read committed’;
- ALTER ROLE myprojectuser SET timezone TO ‘UTC’;
今、新しいユーザーに新しいデータベースの管理権限を付与することができます。
- GRANT ALL PRIVILEGES ON DATABASE myproject TO myprojectuser;
作業が終わったら、PostgreSQLのプロンプトから退出するために、入力すること。
- \q
🇯🇵 PostgreSQLは現在、Djangoが接続し、データベース情報を管理できるように設定されています。
プロジェクトのためのPython仮想環境を作成する
データベースが準備できたので、プロジェクトの残りの要件を取得し始めることができます。仮想環境内でPythonの要件をインストールします。
最初に、プロジェクトファイルを保存できるディレクトリを作成し、そこに移動してください。
- mkdir ~/myprojectdir
- cd ~/myprojectdir
プロジェクトディレクトリ内で、以下のコマンドを入力してPythonの仮想環境を作成してください。
- python3 -m venv myprojectenv
以下のように日本語で表現することができます:「これにより、myprojectdir ディレクトリ内に myprojectenv という名前のディレクトリが作成されます。内部には、パッケージの管理に使用するローカルバージョンのPythonとpipがインストールされます。この仮想環境の構造を使用して、作成したいプロジェクトのために分離されたPython環境をインストールおよび設定することができます。」
プロジェクトのPythonの要件をインストールする前に、仮想環境をアクティベートする必要があります。以下のように入力することでアクティベートできます。
- source myprojectenv/bin/activate
以下の日本語訳の候補を1つ提供します。
プロンプトは、Pythonの仮想環境内で操作していることを示すように変更する必要があります。次のように表示されます:(myprojectenv)user@host:~/myprojectdir$。
仮想環境をアクティブにした状態で、pipを使用してDjango、Gunicorn、そしてpsycopg2 PostgreSQLアダプターをインストールしてください。
Note
- pip install django gunicorn psycopg2-binary
今は、Djangoプロジェクトを始めるために必要なソフトウェアをすべて揃えるべきです。
新しいDjangoプロジェクトの作成と設定
Pythonのコンポーネントがインストールされている場合、実際のDjangoプロジェクトファイルを作成することができます。
Djangoプロジェクトを作成する
プロジェクトディレクトリが既に存在するので、Djangoにここにファイルをインストールするように指示します。実際のコードを含む2番目のレベルのディレクトリが作成され、このディレクトリに管理スクリプトが配置されます。重要な点は、現在のディレクトリに対してDjangoが相対的な決定をするのではなく、ディレクトリを明示的に定義していることです。
- django-admin startproject myproject ~/myprojectdir
この時点で、あなたのプロジェクトディレクトリ(この例では~/myprojectdir)には次の内容が含まれているはずです。
- ~/myprojectdir/manage.py: A Django project management script.
- ~/myprojectdir/myproject/: The Django project package. This should contain the __init__.py, settings.py, urls.py, asgi.py, and wsgi.py files.
- ~/myprojectdir/myprojectenv/: The virtual environment directory you created earlier.
プロジェクトの設定を調整する。 (Purojekuto no settei o chōsa suru)
新たに作成したプロジェクトファイルを扱う際に最初に行うべきことは、設定の調整です。nanoやお好みのテキストエディタを使用して設定ファイルを開いてください。
- nano ~/myprojectdir/myproject/settings.py
ALLOWED_HOSTSディレクティブを探し始めます。これにより、サーバーのアドレスまたはドメイン名のリストを定義し、Djangoインスタンスに接続するために使用できます。このリストに含まれていないHostヘッダーを持つ着信リクエストは例外を発生させます。Djangoは、この設定を行うことで、特定のセキュリティ上の脆弱性を防止する必要があります。
以下のスクエアブラケット内には、Djangoサーバーに関連付けられているIPアドレスまたはドメイン名をリストしてください。各項目は、引用符で囲んで、エントリーをカンマで区切ってください。ドメイン全体とそのサブドメインへのリクエストを希望する場合は、エントリーの先頭にピリオドを付けてください。以下のスニペットでは、デモンストレーションとしていくつかのコメントアウトされた例が使用されています。
Note
. . .
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']
次に、データベースアクセスの設定を行うセクションを探してください。DATABASESから始まります。このファイルの設定はSQLiteデータベース用ですが、私たちのプロジェクトには既にPostgreSQLデータベースを作成済みなので、設定を調整する必要があります。
ポストグレスのデータベース情報を使用して、設定を変更します。pipでインストールしたpsycopg2アダプターを使用するようにDjangoに指示します。データベース名、データベースユーザー名、データベースユーザーのパスワードを入力し、データベースがローカルコンピュータ上にあることを指定します。PORT設定を空の文字列のままでおいておいてください。
. . .
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'myproject',
'USER': 'myprojectuser',
'PASSWORD': 'password',
'HOST': 'localhost',
'PORT': '',
}
}
. . .
次に、ファイルの最後に移動して、静的ファイルの配置先を示す設定を追加します。これは、Nginxがこれらのアイテムに対するリクエストを処理できるようにするために必要です。以下の行は、Djangoにそれらをプロジェクトの基本ディレクトリにあるstaticというディレクトリに配置するよう指示しています。
「~/myprojectdir/myproject/settings.py」
. . .
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
import os
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
作業が終わったら、ファイルを保存して閉じてください。もしnanoを使っている場合は、Ctrl+Xを押し、その後にYとEnterを押してください。
最初のプロジェクトのセットアップを完了する。
今、管理スクリプトを使用して、初期のデータベーススキーマを私たちのPostgreSQLデータベースに移行できます。
- ~/myprojectdir/manage.py makemigrations
- ~/myprojectdir/manage.py migrate
プロジェクトの管理ユーザーを作成するには、タイプしてください。
- ~/myprojectdir/manage.py createsuperuser
ユーザーネームを選択し、メールアドレスを入力し、パスワードを選択し確認する必要があります。 (Yūzānēmu o sentaku shi, mēru adoresu o nyūryoku shi, pasuwādo o sentaku shi kakunin suru hitsuyō ga arimasu.)
指定したディレクトリの場所に、静的なコンテンツをすべて収集するには、次のように入力してください。
- ~/myprojectdir/manage.py collectstatic
操作を確認してください。その後、静的ファイルはプロジェクトディレクトリ内の「static」というディレクトリに配置されます。
もし最初のサーバーセットアップガイドに従ったならば、サーバーはUFWファイアウォールで守られているはずです。開発サーバーをテストするために、使用するポートへのアクセスを許可する必要があります。
ポート8000に対して例外を作成するために、以下のように入力してください。
- sudo ufw allow 8000
最終的に、次のコマンドでDjango開発サーバーを起動して、プロジェクトをテストすることができます。
- ~/myprojectdir/manage.py runserver 0.0.0.0:8000
ウェブブラウザで、サーバのドメイン名またはIPアドレスの後に “:8000” を付けてアクセスしてください。
http://server_domain_or_IP:8000
デフォルトのDjangoインデックスページを受け取るべきです。
アドレスバーのURLの末尾に/adminを追加すると、createsuperuserコマンドで作成した管理者のユーザー名とパスワードを入力するよう求められます。
認証後、デフォルトのDjango管理者インターフェースにアクセスできます。
探索が終わったら、開発サーバーをシャットダウンするためにターミナルウィンドウでCTRL-Cを押してください。
Gunicornのプロジェクトへのサービス能力をテスト中。
仮想環境から出る前に行う最後の作業は、Gunicornがアプリケーションを適切に提供できるかをテストすることです。プロジェクトディレクトリに移動し、gunicornを使用してプロジェクトのWSGIモジュールを読み込むことで、これを行うことができます。
- cd ~/myprojectdir
- gunicorn –bind 0.0.0.0:8000 myproject.wsgi
Djangoの開発サーバーが実行されていたインターフェースで、これによりGunicornが開始されます。ブラウザでアプリを再度テストすることができます。
Note
Djangoのwsgi.pyファイルへの相対ディレクトリパスを指定して、Gunicornにモジュールを渡しました。このファイルの中で、アプリケーションとの通信に使用されるapplicationという名前の関数が定義されています。WSGI仕様の詳細については、ここをクリックしてください。
テストが終わったら、Gunicornを停止するためにターミナルウィンドウでCTRL-Cを押してください。
Djangoアプリケーションの設定が完了しました。仮想環境から終了するには、次のコマンドを入力してください。
- deactivate
あなたのプロンプトにある仮想環境のインジケーターは削除されます。
「Gunicornのためのsystemdのソケットとサービスファイルを作成する」
GunicornとDjangoアプリケーションが連携できることは確認しましたが、アプリケーションサーバーの起動と停止をより堅牢な方法で実装する必要があります。これを実現するために、systemdのサービスファイルとソケットファイルを作成します。
Gunicornのソケットは起動時に作成され、接続を待ち受けます。接続が発生すると、systemdは自動的にGunicornプロセスを起動して接続を処理します。
最初に、Gunicornのためのsystemdソケットファイルをsudo権限で作成して開きます。
- sudo nano /etc/systemd/system/gunicorn.socket
内部には、[Unit]セクションを作成してソケットを説明し、[Socket]セクションでソケットの位置を定義し、[Install]セクションでソケットが正しい時に作成されるようにします。
[Unit]
Description=gunicorn socket
[Socket]
ListenStream=/run/gunicorn.sock
[Install]
WantedBy=sockets.target
作業が終わったら、ファイルを保存して閉じてください。
次に、テキストエディタでsudo特権を持ってGunicornのsystemdサービスファイルを作成し、開きます。サービスのファイル名は、拡張子を除いてソケットのファイル名と一致する必要があります。
- sudo nano /etc/systemd/system/gunicorn.service
以下は、日本語での一つのオプションの言い換えです:
メタデータと依存関係を指定するために使用される「[Unit]」セクションから始めます。ここにサービスの説明を記載し、ネットワーキングターゲットに到達後にのみこのサービスを起動するようにinitシステムに指示します。ソケットファイルからのソケットに依存しているため、関連性を示すためにRequiresディレクティブを含める必要があります。
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
その後、[Service]セクションを書きます。実行するユーザーとグループを指定します。関連するファイルはすべて所有しているので、通常のユーザーアカウントに処理の所有権を与えます。また、NginxがGunicornと通信できるように、グループ所有権をwww-dataグループに与えます。
次に、作業ディレクトリをマップし、サービスを開始するために使用するコマンドを指定します。この場合、仮想環境内にインストールされているGunicornの実行ファイルの完全なパスを指定する必要があります。次に、作成したUnixソケットにプロセスをバインドして、プロセスがNginxと通信できるようにします。Gunicornのログをjournaldプロセスが収集できるように、すべてのデータを標準出力に記録します。また、ここで任意のGunicornの調整も指定できます。例えば、この場合は3つのワーカープロセスを指定しました。
「/etc/systemd/system/gunicorn.service」
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
最後に、[Install]セクションを追加します。これにより、起動時にこのサービスを有効にする場合、systemdにこのサービスをどのように関連付けるかを指示します。このサービスは通常のマルチユーザーシステムが起動して稼働しているときに起動するようにしたいです。
「/etc/systemd/system/gunicorn.service」
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target
[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/myprojectdir
ExecStart=/home/sammy/myprojectdir/myprojectenv/bin/gunicorn \
--access-logfile - \
--workers 3 \
--bind unix:/run/gunicorn.sock \
myproject.wsgi:application
[Install]
WantedBy=multi-user.target
それによって、あなたのsystemdのサービスファイルは完成します。保存して閉じてください。
Gunicornソケットを今すぐ開始し有効化することができます。これにより、ソケットファイルが/run/gunicorn.sockに作成され、起動時にも同様に生成されます。そのソケットへの接続が行われると、systemdは自動的にgunicorn.serviceを起動して処理します。
- sudo systemctl start gunicorn.socket
- sudo systemctl enable gunicorn.socket
ソケットファイルを確認することで、操作が成功したことを確認できます。
Gunicornのソケットファイルをチェックしています。
プロセスのステータスをチェックして、開始できたかどうかを確認してください。
- sudo systemctl status gunicorn.socket
このような出力を受け取るべきです。 (Kono you na shutsuryoku o uketoru beki desu.)
● gunicorn.socket – gunicorn socket Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: enabled) Active: active (listening) since Thu 2022-08-04 19:02:54 UTC; 5s ago Triggers: ● gunicorn.service Listen: /run/gunicorn.sock (Stream) CGroup: /system.slice/gunicorn.socket Apr 18 17:53:25 django systemd[1]: Listening on gunicorn socket.
次に、/runディレクトリ内にgunicorn.sockファイルが存在するかを確認してください。
- file /run/gunicorn.sock
/run/gunicorn.sock: socket
以下のように日本語で言い換えます(1つのオプションのみ):
systemctl statusコマンドがエラーを示した場合、またはディレクトリ内にgunicorn.sockファイルが見つからない場合、それはGunicornソケットが正しく作成できなかったことを示しています。Gunicornソケットのログを確認するには、次のコマンドを入力してください。
- sudo journalctl -u gunicorn.socket
続行する前に、問題がないかどうか確認するために、/etc/systemd/system/gunicorn.socketファイルをもう一度見直してください。
Socket Activationのテストを行う
現在、gunicorn.socketユニットのみを起動している場合、ソケットに接続がまだないため、gunicorn.serviceはまだアクティブになりません。これを確認するには、次のように入力してください。
- sudo systemctl status gunicorn
○ gunicorn.service – gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: inactive (dead) TriggeredBy: ● gunicorn.socket
ソケットアクティベーションの仕組みをテストするために、curlを使ってソケットへの接続を送信することができます。
- curl –unix-socket /run/gunicorn.sock localhost
アプリケーションのHTML出力がターミナルで受け取れるはずです。これは、Gunicornが起動し、Djangoアプリケーションを提供できたことを示しています。Gunicornサービスが実行中であることを確認するには、次のように入力してください。
- sudo systemctl status gunicorn
● gunicorn.service – gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: active (running) since Thu 2022-08-04 19:03:51 UTC; 5s ago TriggeredBy: ● gunicorn.socket Main PID: 102674 (gunicorn) Tasks: 4 (limit: 4665) Memory: 94.2M CPU: 885ms CGroup: /system.slice/gunicorn.service ├─102674 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn –access-logfile – –workers 3 –bind unix:/run/gunicorn.sock myproject.wsgi:application ├─102675 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn –access-logfile – –workers 3 –bind unix:/run/gunicorn.sock myproject.wsgi:application ├─102676 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn –access-logfile – –workers 3 –bind unix:/run/gunicorn.sock myproject.wsgi:application └─102677 /home/sammy/myprojectdir/myprojectenv/bin/python3 /home/sammy/myprojectdir/myprojectenv/bin/gunicorn –access-logfile – –workers 3 –bind unix:/run/gunicorn.sock myproject.wsgi:application Apr 18 17:54:49 django systemd[1]: Started gunicorn daemon. Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Starting gunicorn 20.1.0 Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Listening at: unix:/run/gunicorn.sock (102674) Apr 18 17:54:49 django gunicorn[102674]: [2022-04-18 17:54:49 +0000] [102674] [INFO] Using worker: sync Apr 18 17:54:49 django gunicorn[102675]: [2022-04-18 17:54:49 +0000] [102675] [INFO] Booting worker with pid: 102675 Apr 18 17:54:49 django gunicorn[102676]: [2022-04-18 17:54:49 +0000] [102676] [INFO] Booting worker with pid: 102676 Apr 18 17:54:50 django gunicorn[102677]: [2022-04-18 17:54:50 +0000] [102677] [INFO] Booting worker with pid: 102677 Apr 18 17:54:50 django gunicorn[102675]: – – [18/Apr/2022:17:54:50 +0000] “GET / HTTP/1.1” 200 10697 “-” “curl/7.81.0”
もしcurlの出力またはsystemctl statusの出力に問題が発生したことが示されている場合、詳細情報のためにログを確認してください。
- sudo journalctl -u gunicorn
/etc/systemd/system/gunicorn.service ファイルに問題がないか確認してください。/etc/systemd/system/gunicorn.service ファイルに変更を加えた場合は、デーモンをリロードしてサービスの定義を再読み込みし、Gunicorn プロセスを再起動するために、次のコマンドを入力してください。
- sudo systemctl daemon-reload
- sudo systemctl restart gunicorn
続行する前に、上記の問題点をトラブルシューティングしてください。 (Zokō suru mae ni, jōki no mondai-ten o toraburushūtingu shite kudasai.)
Nginxを設定して、GunicornにProxy Passを行うようにします。
Gunicornが設定されたので、Nginxを構成してトラフィックをプロセスに渡す必要があります。
Nginxのsites-availableディレクトリに新しいサーバーブロックを作成して開き始めます。 (Nginxのsites-availableディレクトリに新しいサーバーブロックを作成して開始することから始めましょう。)
- sudo nano /etc/nginx/sites-available/myproject
内部で、新しいサーバーブロックを開きます。まず、このブロックが通常のポート80で待ち受けるように指定し、サーバーのドメイン名またはIPアドレスに応答するようにします。
server {
listen 80;
server_name server_domain_or_IP;
}
次に、Nginxにはファビコンが見つからないという問題を無視するように指示します。また、~ / myprojectdir / staticディレクトリに収集した静的アセットの場所を指定します。これらのすべてのファイルの標準的なURIプレフィックスは”/static”ですので、それらのリクエストに一致するようにロケーションブロックを作成できます。
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/myprojectdir;
}
}
最後に、他のすべてのリクエストに一致するロケーション/ {}ブロックを作成します。このロケーションの内部に、Nginxのインストールに含まれる標準のプロキシパラムファイルを含め、トラフィックを直接Gunicornのソケットに渡します。
server {
listen 80;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/sammy/myprojectdir;
}
location / {
include proxy_params;
proxy_pass http://unix:/run/gunicorn.sock;
}
}
作業が終わったらファイルを保存して閉じてください。そして、サイトの有効化ディレクトリにリンクすることでファイルを有効にすることができます。
- sudo ln -s /etc/nginx/sites-available/myproject /etc/nginx/sites-enabled
構文エラーがないかNginxの設定をテストするために、次のように入力してください。
- sudo nginx -t
エラーが報告されていない場合は、次のようにしてNginxを再起動してください。
- sudo systemctl restart nginx
最後に、ポート80で正常なトラフィックを受け入れるためにファイアウォールを開放する必要があります。開発サーバーへのアクセスは不要になったので、ポート8000を開くルールを削除することもできます。
- sudo ufw delete allow 8000
- sudo ufw allow ‘Nginx Full’
あなたは今、サーバーのドメインまたはIPアドレスにアクセスしてアプリケーションを表示できるはずです。
Note
ドメイン名がある場合、トラフィックを保護するためのSSL証明書を取得する最も直接的な方法は、Let’s Encryptを使用することです。このガイドに従って、Debian 11上のNginxでLet’s Encryptを設定してください。このガイドで作成したNginxのサーバーブロックを使用して手続きに従ってください。
NginxとGunicornのトラブルシューティング
もしこの最後のステップでアプリケーションが表示されない場合は、インストールのトラブルシューティングが必要です。
NginxはDjangoアプリケーションの代わりにデフォルトのページを表示しています。
Nginxがアプリケーションにプロキシする代わりにデフォルトのページを表示する場合、通常は/etc/nginx/sites-available/myprojectファイル内のserver_nameを調整して、サーバーのIPアドレスまたはドメイン名にポイントする必要があります。
Nginxは、server_nameを使用してどのサーバーブロックを使用してリクエストに応答するかを判断します。デフォルトのNginxページが表示される場合、Nginxはリクエストを明示的にサーバーブロックにマッチさせることができなかった証拠です。そのため、Nginxは/etc/nginx/sites-available/defaultで定義されたデフォルトブロックにフォールバックしています。
プロジェクトのserverブロック内のserver_nameは、デフォルトのserverブロック内のものよりも具体的である必要があります。それによって選択されます。
Nginxは、Djangoアプリケーションの代わりに502 Bad Gatewayエラーを表示しています。
502エラーは、Nginxがリクエストを正常にプロキシできないことを示しています。様々な設定の問題が502エラーとして現れることがありますので、適切にトラブルシューティングするためには詳細な情報が必要です。
詳細な情報を探すための主要な場所は、Nginxのエラーログです。通常、これによってプロキシイベント中に問題が発生した条件がわかります。Nginxのエラーログを確認するには、次のように入力してください。
- sudo tail -F /var/log/nginx/error.log
今、ブラウザで別のリクエストを行い、新しいエラーを生成してください(ページをリフレッシュしてみてください)。ログに記載される新しいエラーメッセージを受け取るはずです。メッセージを見ると、問題の特定に役立つでしょう。
以下のメッセージを受け取る可能性があります。
unix:/run/gunicorn.sock への connect() が失敗しました (2: ファイルやディレクトリが存在しません)。
これは、Nginxが指定された場所にあるgunicorn.sockファイルを見つけることができなかったことを示しています。/etc/nginx/sites-available/myprojectファイル内で定義されているproxy_passの場所と、gunicorn.socket systemdユニットによって生成されたgunicorn.sockファイルの実際の場所を比較する必要があります。
/runディレクトリ内にgunicorn.sockファイルが見つからない場合は、通常systemdソケットファイルが作成できなかったことを意味します。Gunicornのトラブルシューティング手順を進めるため、Gunicornのソケットファイルを確認するセクションに戻ってください。
unix:/run/gunicorn.sockへのconnect()に失敗しました(13: 許可が拒否されました)
NginxがGunicornソケットに接続できなかったのは、パーミッションの問題のためです。rootユーザーではなくsudoユーザーを使用して手順を実行すると、これが起こることがあります。systemdはGunicornソケットファイルを作成できる一方、Nginxはそれにアクセスできません。
もし、rootディレクトリ(/)とgunicorn.sockファイルの間のいずれかのポイントで権限が制限されている場合、これは起こり得ます。 socketファイルおよびそれぞれの親ディレクトリの所有権と権限の値を確認するには、socketファイルへの絶対パスをnameiコマンドに渡すことで確認できます。
- namei -l /run/gunicorn.sock
f: /run/gunicorn.sock drwxr-xr-x root root / drwxr-xr-x root root run srw-rw-rw- root root gunicorn.sock
出力はディレクトリの各コンポーネントの権限を表示します。権限(最初の列)、所有者(2番目の列)、およびグループ所有者(3番目の列)を見ることで、ソケットファイルへのアクセスタイプを判断することができます。
上記の例では、ソケットファイルとソケットファイルに至るまでの各ディレクトリには、世界読み取りおよび実行の権限(ディレクトリの権限列はr-xで終わる)が与えられています。Nginxプロセスはソケットに正常にアクセスできるはずです。
ソケットに至るまでのディレクトリのいずれかに、ワールドの読み取りおよび実行権限がない場合、Nginxはワールドへの読み取りおよび実行権限を許可するか、Nginxが所属しているグループにグループ所有権を与えることなく、ソケットにアクセスすることはできません。
Djangoが表示しています:「サーバーに接続できませんでした:接続が拒否されました」
ウェブブラウザでアプリケーションの一部にアクセスしようとした際に、Djangoから受け取ることがあるメッセージは以下の通りです。
OperationalError at /admin/login/
could not connect to server: Connection refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
これは、DjangoがPostgresデータベースに接続できないことを示しています。Postgresインスタンスが実行されていることを確認するために、以下のコマンドを入力してください。
- sudo systemctl status postgresql
もし設定されていなければ、起動時に自動的に開始するように、手動で起動することもできます。
- sudo systemctl start postgresql
- sudo systemctl enable postgresql
もしまだ問題がある場合は、~/myprojectdir/myproject/settings.py ファイルで定義されたデータベースの設定が正しいか確認してください。
追加のトラブルシューティング
追加のトラブルシューティングには、ログが原因の絞り込みに役立ちます。それぞれを順番に確認し、問題箇所を示すメッセージを探してください。
(Additional troubleshootingの部分を修正しました)
次のログが役立つかもしれません。
- Check the Nginx process logs by typing: sudo journalctl -u nginx
- Check the Nginx access logs by typing: sudo less /var/log/nginx/access.log
- Check the Nginx error logs by typing: sudo less /var/log/nginx/error.log
- Check the Gunicorn application logs by typing: sudo journalctl -u gunicorn
- Check the Gunicorn socket logs by typing: sudo journalctl -u gunicorn.socket
設定やアプリケーションを更新する際には、変更を反映させるためにおそらくプロセスの再起動が必要になるでしょう。
Djangoアプリケーションを更新したら、以下のコマンドを入力してGunicornプロセスを再起動することで、変更内容を反映させることができます。
- sudo systemctl restart gunicorn
Gunicornのソケットやサービスファイルを変更した場合は、デーモンをリロードし、プロセスを再起動するために次のように入力してください。
- sudo systemctl daemon-reload
- sudo systemctl restart gunicorn.socket gunicorn.service
Nginxのサーバーブロック設定を変更した場合は、設定をテストし、Nginxを入力してください。
- sudo nginx -t && sudo systemctl restart nginx
構成を調整する過程で変更点を把握するために、以下のコマンドが役立ちます。
結論
このガイドでは、Djangoプロジェクトを独自の仮想環境でセットアップします。クライアントのリクエストを処理するために、Gunicornを設定して翻訳します。その後、クライアントの接続を処理し、クライアントリクエストに応じて正しいプロジェクトを提供する逆プロキシとしてNginxをセットアップします。
Djangoは、多くの共通の要素を提供することで、プロジェクトやアプリケーションの作成をサポートしています。一般的なツールチェーンを活用することで、作成したアプリケーションを単一のサーバーから提供することができます。