Djangoは、Pythonプログラミング言語で構築された、無料のオープンソースWebアプリケーションフレームワークです。Djangoは非常に高速で、安全で、拡張性に優れています。熟練した開発者の手にかかれば、Djangoは強力なWebサイトを迅速に構築できます。一般的なWebサーバー(Apache,、Nginx)や、データベース(MySQL, 、MariaDB, 、PostgreSQL, 、Oracle、およびSQLite)などとシームレスに統合できます。Djangoは、Instagram、Mozilla、NASAなど、世界最大規模のWebサイトのいくつかを支えています。このガイドでは、Ubuntu 20.04上で、PostgreSQL、Nginx、およびGunicornを使用して、DjangoによるWebアプリのベースラインをセットアップする方法を説明します。
前提条件
このガイドでは、基本的なファイアウォールとsudo権限を持つ非ルートユーザーが設定されたUbuntu 20.04サーバーが動作している必要があります。詳細については、Ubuntuサーバーのセットアップ方法に関するガイドを参照してください。このチュートリアルに従って、sudo権限を持つ非ルートユーザーを設定してください。また、このガイドの手順に従ってIptablesファイアウォールを設定することもできます。.
Djangoは仮想環境内にインストールします。プロジェクト専用の環境を用意することで、同じサーバーから複数のプロジェクトをより簡単に管理できるようになります。データベースとアプリが設定されたら、Gunicornアプリケーションサーバーをデプロイします。Gunicornは、クライアントからのHTTPリクエストを、アプリケーションが利用できるPython呼び出しに変換するアプリケーションインターフェースとなります。その後、高速な接続処理パフォーマンスと実装が容易なセキュリティ機能を利用するために、Gunicornの前段にNginxをデプロイします。
必要なパッケージのインストール
まず、必要なパッケージをすべてインストールすることから始めます。幸いなことに、これらのパッケージはすべて公式のUbuntuパッケージリポジトリから直接入手できます。ターミナルを開き、APTパッケージキャッシュを更新します:
|
1 |
sudo apt update |
パッケージリストは、WebアプリケーションがPython 2とPython 3のどちらを使用するかによって異なります。Python 3でDjangoをインストールするには、次のコマンドを実行します:
|
1 |
sudo apt install python3-pip python3-dev libpq-dev postgresql postgresql-contrib nginx curl |
Django 1.11 LTSは、Python 2をサポートする最後のDjangoリリースです。Python 2でDjangoを使用する場合は、次のパッケージをインストールしてください:
|
1 |
sudo apt install python-pip python-dev libpq-dev postgresql postgresql-contrib nginx curl |
PostgreSQLデータベースとユーザー
データベースソリューションとしては、PostgreSQLを使用します。これは、強力なオープンソースのオブジェクト関係データベースシステムです。PostgreSQLは、信頼性、堅牢性、およびパフォーマンスを提供します。PostgreSQLのセットアップに関する詳細な手順については、UbuntuサーバーでのPostgreSQLのセットアップに関するガイドを参照してください。このガイドでは、Djangoアプリケーション用の専用データベースとユーザーをセットアップします。
デフォルトでは、PostgreSQLはローカル接続の認証スキームとして「ピア認証」を実装しています。簡単に言うと、「ピア認証」は、ユーザーのオペレーティングシステムのユーザー名が有効なPostgreSQLユーザー名と一致する場合にログインを認証します。インストール中に、PostgreSQLはオペレーティングシステムユーザーであるpostgresを、PostgreSQLの管理ユーザーであるpostgresに対応するように設定しました。次のコマンドを使用して、postgresとしてPostgreSQLの対話型シェルセッションにログインします:
|
1 |
sudo -u postgres psql |
PostgreSQLのプロンプトが表示されます。最初のステップは、プロジェクト専用のデータベースを作成することです。デモンストレーションとして、データベース名はviktor_project:
|
1 |
CREATE DATABASE viktor_project; |
次のステップは、プロジェクトデータベース用の専用ユーザーを作成することです。ユーザーには強力なユーザー名を設定する必要があります。デモンストレーションとして、ユーザー名はviktor_project_user:
|
1 |
CREATE USER viktor_project_user WITH PASSWORD 'password123'; |
次に、いくつかのパラメータを変更します:
- 特定の接続パラメータ。要するに、接続が確立されるたびに正しい値を照会して設定する必要がなくなります。これにより、データベースのパフォーマンスが大幅に向上します。
- デフォルトのエンコーディングを
UTF-8に設定します。これはユニバーサルなエンコーディングであり、Djangoがこれを想定しています。 - デフォルトのトランザクション分離レベルを「read committed」に設定します。これにより、コミットされていないトランザクションからの読み取りがブロックされます。
- タイムゾーンを
UTC.
これらのパラメータ変更はすべて、Djangoプロジェクト自体によって推奨されています。これらの変更を適用するには、次のコマンドを実行します。データベースのユーザー名を正しいものに変更することを忘れないでください。
|
1 2 3 |
ALTER ROLE viktor_project_user SET client_encoding TO 'utf8'; ALTER ROLE viktor_project_user SET default_transaction_isolation TO 'read committed'; ALTER ROLE viktor_project_user SET timezone TO 'UTC'; |
データベースの管理者を専用のデータベースユーザーに変更します。
|
1 |
GRANT ALL PRIVILEGES ON DATABASE viktor_project TO viktor_project_user; |
これでPostgreSQLでの作業は一旦終了です。PostgreSQLのインタラクティブシェルを終了します。
|
1 |
\q |
Python仮想環境
データベースの準備ができたので、次はプロジェクトの残りの要件の確立に集中できます。管理を容易にするために、仮想環境を構築し、そこにすべてのPython要件をインストールします。仮想環境を生成するには、virtualenvが必要です。これはpipを使用して簡単にインストールできます。
次のコマンドは、pipをアップグレードし、virtualenvをインストールします。Python 3の場合は、次のコマンドを実行します。
|
1 2 |
sudo -H pip3 install --upgrade pip sudo -H pip3 install virtualenv |
Python 2の場合は、代わりに次のコマンドを実行します。
|
1 2 |
sudo -H pip install --upgrade pip sudo -H pip install virtualenv |
Once virtualenvがインストールされたら、仮想環境を作成します。次に、仮想環境用の専用ディレクトリを作成します。
|
1 |
mkdir -v ~/viktor_project |
その後、カレントディレクトリを仮想環境用の専用ディレクトリに変更します。
|
1 |
cd ~/viktor_project |
ディレクトリ内で、次のコマンドを実行します。virtualenvツールは、プロジェクト名で仮想環境を作成します。
|
1 |
virtualenv viktor_project |
プロジェクト名と同じ名前のサブディレクトリが作成されます。このサブディレクトリには、ローカルバージョンのPythonとpipが含まれます。これにより、プロジェクト用に隔離されたPython環境を柔軟にインストールおよび設定できます。
次のコマンドで仮想環境を有効化(アクティベート)します。
|
1 |
source viktor_project/bin/activate |
ターミナルのプロンプトが変化し、Python仮想環境内で操作していることが示されます。仮想環境に入ったので、必要なPython要件をインストールします。Django、Gunicorn、およびpsycopg2(PostgreSQLアダプター)が必要です。次のコマンドを実行して、ローカルのpipにコンポーネントをインストールさせます。
|
1 |
pip install django gunicorn psycopg2-binary |
Python 3を使用している場合でも、pipが正しいコマンドです。これは、仮想環境内ではpip3の名前がpipに変更されているためです。
新規Djangoプロジェクト
Pythonコンポーネントが整ったので、実際のDjangoプロジェクトファイルの作成を開始できます。
-
Djangoプロジェクトの作成
プロジェクトディレクトリはすでに作成されています。そこにファイルをインストールするようDjangoに指示します。この手順により、実際のコードを含む第2レベルのディレクトリが生成されます。このディレクトリには管理スクリプトも含まれます。重要なのは、現在のディレクトリに対する相対的なディレクトリをDjangoに決定させるのではなく、対象 of ディレクトリを明示的に指定している点です。
|
1 |
django-admin.py startproject viktor_project ~/viktor_project |
Djangoはそれに応じてプロジェクトを作成します。ここでは、注目する重要なファイルとディレクトリのいくつかを紹介します。ディレクトリ名とファイル名はデモンストレーションに従って使用されています。
~/viktor_project/manage.py: Djangoによるプロジェクト管理スクリプト。~/viktor_project/viktor_project/: Djangoプロジェクトを含むパッケージです。__init__.py、settings.py、urls.py、asgi.py、およびwsgi.pyファイルが含まれている必要があります。
-
プロジェクト設定の調整
プロジェクトが作成された後、最初に行うことはその設定を調整することです。テキストエディタでsettings.pyを開きます:
|
1 |
nano ~/viktor_project/viktor_project/settings.py |
最初に探すディレクティブはALLOWED_HOSTSです。これは、Djangoインスタンスに接続できるサーバーまたはドメイン名を定義します。もし、Host ヘッダーを持つリクエストがALLOWED_HOSTSのリストと一致しない場合、例外が発生します。これは、特定の種類のセキュリティ脆弱性を回避するためにDjangoによって推奨されています:
|
1 |
ALLOWED_HOSTS = ['<server_ip_or_domain_name_1>',' server_ip_or_domain_name_2','localhost'] |
次に注目するセクションはDATABASEです。これはデータベースへのアクセスを管理します。デフォルトでは、SQLiteデータベースエンジンの設定が含まれています。しかし、このプロジェクトではPostgreSQLデータベースを使用します。DjangoはPostgreSQLと通信するためにpsycopg2アダプターを使用します:
|
1 2 3 4 5 6 7 8 9 10 |
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'viktor_project', 'USER': 'viktor_project_user', 'PASSWORD': 'password123', 'HOST': 'localhost', 'PORT': '', } } |
次に、ファイルの一番下に移動します。静的ファイルの場所を示すために、次の行を追加します。これにより、Nginxがこれらのアイテムに対するリクエストを処理しやすくなります:
|
1 2 |
import os STATIC_ROOT = os.path.join(BASE_DIR, 'static/') |
ここでの settings.py の作業はこれで完了です。ファイルを保存してエディタを閉じます。
-
初期プロジェクトセットアップの完了
これで、初期データベーススキーマを専用のPostgreSQLデータベースにマイグレートできます。次のコマンドを実行してください:
|
1 2 |
~/viktor_project/manage.py makemigrations ~/viktor_project/manage.py migrate |
次に、プロジェクトのスーパーユーザーを作成する必要があります。スーパーユーザーを生成するには、次のコマンドを実行します:
|
1 |
~/viktor_project/manage.py createsuperuser |
すべての静的ファイルをsettings.pyで指定した場所に収集します。静いファイルは、プロジェクトディレクトリの下にある「static」という別のディレクトリに収集されます:
|
1 |
~/viktor_project/manage.py collectstatic |
次に、サーバーのファイアウォールを調整する必要があります。サーバー設定ガイドに従っていれば、すでにUFWが設定され、有効化されているはずです。ポート8000の例外を作成します。これはDjangoが使用するデフォルトのポートです。以下に関する詳細は、このガイドを参照してください:UFWファイアウォールの基本と使用方法.
|
1 |
sudo ufw allow 8000 |
次に、アクションを確認します:
|
1 |
sudo ufw status |
最後に、実際にサーバーをテストできます。Django開発サーバーを起動します:
|
1 |
~/viktor_project/manage.py runserver 0.0.0.0:8000 |
設定が正常に完了すると、Django開発サーバーが起動し、着信リクエストを受け付けるようになります。ブラウザを開き、ポート8000でサーバーのIP/ドメインにアクセスします:
|
1 |
http://<server_or_domain>:8000 |
Djangoのデフォルトのインデックスページが表示されるはずです。管理パネルにアクセスするには、URLの末尾に /admin を追加します。管理パネルには、事前作成したスーパーユーザーのみがアクセスできます:
|
1 |
http://<server_or_domain>:8000/admin |
ログインすると、デフォルトのDjango管理インターフェースが表示されます。
これで一旦テストは終了です。サーバーを停止するには、ターミナルウィンドウで「Ctrl + C」を押します。
-
Gunicornのテスト
仮想環境を抜ける前に、Gunicornがアプリケーションを配信できるか確認します。テストするには、Gunicornを使用してプロジェクトのWSGIモジュールをロードします。
Gunicornコマンドはプロジェクトディレクトリ内にあります。
|
1 2 |
cd ~/viktor_project gunicorn --bind 0.0.0.0:8000 viktor_project.wsgi |
これにより、Djangoが動作していたのと同じインターフェースでGunicornが起動します。通常のWebブラウザから再度アプリをテストできます。Gunicornはまだ静的CSSコンテンツの場所を認識していないため、管理インターフェースにスタイルが適用されないことに注意してください。
|
1 |
http://<server_or_domain>:8000 |
終了したら、ターミナルウィンドウで「Ctrl + C」を押してGunicornサーバーを停止します。
-
仮想環境の終了
Djangoアプリケーションの設定が完了しました。次のコマンドを実行して仮想環境を終了します。
|
1 |
deactivate |
Gunicornのソケットとサービスファイル
GunicornがDjangoアプリケーションと連携できることを確認しました。しかし、アプリケーションサーバーを管理するより堅牢な方法が必要です。そこでsystemdの登場です。Systemdは、Linuxで利用可能な最も人気のあるinitシステムの1つです。以下は、systemdのサービスとユニットを管理する方法.
Gunicorn用のソケットファイルとサービスファイルを作成することで、systemdにサービスとして管理させることができます。起動時にGunicornソケットが生成されます。ソケットは着信接続をリッスンします。接続が発生すると、systemdは接続を処理するためにGunicornプロセスを開始します。
-
Gunicornソケット
まず、Gunicornソケットを作成しましょう。このファイルはsudo権限で作成する必要があります。
|
1 |
sudo nano /etc/systemd/system/gunicorn.socket |
ファイル内に次のコードを入力します。
|
1 2 3 4 5 6 7 |
[Unit] Description=gunicorn socket [Socket] ListenStream=/run/gunicorn.sock [Install] WantedBy=sockets.target |
ご覧のとおり、コードには3つのセクションがあります。
[Unit]:このセクションではソケットについて説明します。[Socket]:ソケットの場所を定義します。[Install]:この部分は、systemdが適切なタイミングでソケットを作成するようにします。
ファイルを保存してエディタを閉じます。
-
Gunicornサービス
次に、Gunicorn用のサービスファイルを作成します。ソケットファイルと同様に、これもsudo権限で作成する必要があります。
|
1 |
sudo nano /etc/systemd/system/gunicorn.service |
次のコードを入力します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[Unit] Description=gunicorn daemon Requires=gunicorn.socket After=network.target [Service] User=cloudsigma Group=www-data WorkingDirectory=/home/cloudsigma/viktor_project ExecStart=/home/cloudsigma/viktor_project/viktor_project/bin/gunicorn \ --access-logfile - \ --workers 3 \ --bind unix:/run/gunicorn.sock \ viktor_project.wsgi:application [Install] WantedBy=multi-user.target |
コードには複数のセクションが含まれています。
[Unit]:このセクションでは、メタデータと依存関係を指定します。また、ネットワークターゲットに到達した後にのみ起動することも記述されています。[Service]:このセクションでは、プロセスを実行するユーザーとグループを指定します。NginxがGunicornと通信できるように、グループの所有権は「www-data」に設定されています。また、作業ディレクトリをマッピングし、起動コマンドを指定します。[Install]:このセクションでは、起動時にこのサービスが有効になっている場合に、systemdがこのサービスを何にリンクするかを指示します。通常のマルチユーザーシステムが起動した後に開始する必要があります。
次に、ファイルを保存してエディタを閉じます。
-
Gunicornソケットの有効化
Gunicornソケットを使用する準備が整いました。したがって、次のコマンドを実行できます。これにより、ソケットが起動し、有効になります。ソケットファイルは、起動時に /run/gunicorn.sock に作成されます。ソケットへの接続が行われると、systemdはそれを処理するためにGunicornサービスを起動します。
|
1 2 |
sudo systemctl start gunicorn.socket sudo systemctl enable gunicorn.socket |
Gunicornソケットのステータスを確認します。
|
1 |
sudo systemctl status gunicorn.socket |
次に、ソケットファイルの存在を確認します。
|
1 |
file /run/gunicorn.sock |
systemctlからのステータスがエラーを示しているか、gunicorn.sockファイルが見つからなかった場合は、ソケットが正しく作成されなかったことを示しています。詳細なログを確認して手がかりを探してください。
|
1 |
sudo journalctl -u gunicorn.socket |
エラーの可能性がないか、もう一度 gunicorn.socket ファイルを確認することを忘れないでください。
-
ソケットのアクティベーション
これまでに gunicorn.socket を起動しました。ただし、接続要求がない限り、gunicorn.service はアクティブになりません。次に、Gunicornのステータスを確認します。
|
1 |
sudo systemctl status gunicorn |
次のコマンドを使用して接続要求を送信することで、ソケットのアクティベーションメカニズムをテストできます:curl:
|
1 |
curl --unix-socket /run/gunicorn.sock localhost |
アプリケーションからHTML出力が返されるはずです。これは、Gunicornが正常に起動し、Djangoアプリケーションを提供できたことを示しています。Gunicornサービスの現在のステータスを確認します。
|
1 |
sudo systemctl status gunicorn |
予期しない動作や出力(エラーを示すもの)がある場合は、詳細なログを確認して手がかりを探してください。
|
1 |
sudo journalctl -u gunicorn |
gunicorn.serviceファイルに変更を加えた場合は、デーモンをリロードしてサービス定義を再読み込みする必要があります。また、Gunicornサービスを再起動する必要もあります。
|
1 2 |
sudo systemctl daemon-reload sudo systemctl restart gunicorn |
Nginxの設定
次に、入ってくるトラフィックをプロセスに渡すようにNginxを設定します。まず、Nginxに新しいサーバーブロックを作成します。
|
1 |
sudo nano /etc/nginx/sites-available/viktor_project |
次に、以下のコードを入力します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
server { listen 80; server_name 31.171.250.71; location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/cloudsigma/viktor_project; } location / { include proxy_params; proxy_pass http://unix:/run/gunicorn.sock; } } |
設定には複数のブロックがあります。
service:このブロックは、サーバーが通常ポート80でリッスンし、サーバーのドメイン名またはIPアドレスに応答する必要があることを定義します。location:これは最初のlocationエントリです。静的アセットの場所を定義します。location:これは2番目のlocationエントリです。このブロックは、標準のプロキシパラメータと、トラフィックをGunicornソケットに渡す方法を定義します。
ファイルを保存してエディタを閉じます。有効にするために、ファイルを「sites-enabled」ディレクトリにリンクします。
|
1 |
sudo ln -s /etc/nginx/sites-available/viktor_project /etc/nginx/sites-enabled |
その後、Nginxの設定に構文エラーがないかテストします:
|
1 |
sudo nginx -t |
エラーが見つからなかった場合は、Nginxを再起動して変更を適用します:
|
1 |
sudo systemctl restart nginx |
UFWルールを再度変更する必要があります。開発サーバーへのアクセスは不要になったため、ポート8000の例外を削除できます。さらに、通常のトラフィック用にポート80を開放します:
|
1 2 |
sudo ufw delete allow 8000 sudo ufw allow 'Nginx Full' |
これらのファイアウォールルールの変更を確認します:
|
1 |
sudo ufw status |
これで、通常のWebブラウザからサーバーにアクセスできるようになります。
トラブルシューティングの手順
すべての手順が正しく実行されていれば、インターネット経由でDjangoアプリケーションにアクセスできるはずです。アクセスできない場合は、インストールが計画通りに進まなかったことを示しています。問題の原因を特定するためにトラブルシューティングを行う必要があります。
-
Nginxがデフォルトページを表示する
Nginxがアプリケーションプロキシではなくデフォルトページを表示している場合、通常はサーバーブロック内のserver_nameの設定が間違っていることを意味します。
この例では、サーバーブロックは次の場所に保存されています:
|
1 |
/etc/nginx/sites-available/viktor_project |
The server_nameエントリは、Nginxがリクエストへの応答に使用するサーバーブロックを決定します。デフォルトページが表示される場合、Nginxはリクエストを明示的なサーバーブロックに一致させることができなかった可能性が高いため、代わりにデフォルトのブロックにフォールバックしています。
|
1 |
/etc/nginx/sites-available/default |
Djangoプロジェクトのサーバーブロックに適切なserver_name.
-
502 Bad Gateway
エラー502は、Nginxがリクエストを正常にプロキシできなかったことを示します。エラー502を引き起こす可能性のある設定の問題は多岐にわたるため、適切にトラブルシューティングを行うための手がかりが必要です。
手がかりの主な情報源はNginxのエラーログです。一般的に、プロキシ中に問題を引き起こした状況が示唆されます。次のコマンドを使用してNginxのエラーログを確認します:
|
1 |
sudo tail -F /var/log/nginx/error.log |
ログが開いたら、もう一度サーバーにアクセスしてみてください。ログに新しいエラーメッセージが生成されるはずです。これにより、問題を絞り込むことができます。考えられるメッセージをいくつか紹介します:
- connect() to unix:/run/gunicorn.sock failed (2: No such file or directory)
これは、Nginxが設定で定義された場所にgunicorn.sockを見つけられなかったことを示しています。その場所は、サイトブロック内のproxy_passディレクティブで記述されています。以下を確認してください:proxy_passが、次のgunicorn.sock(gunicorn.socket systemdユニットによって生成されたもの)の正しい場所を指しているか:
|
1 |
/etc/nginx/sites-available/viktor_project |
If gunicorn.sockが/runディレクトリの下に見つからなかった場合、systemdがそれを生成できなかったことを意味します。Gunicornソケットファイルの設定手順を再確認する必要があります。
- connect() to unix:/run/gunicorn.sock failed (13: Permission denied)
これは、権限の問題によりNginxがGunicornソケットに接続できなかったことを示しています。このプロセスがsudoユーザーではなく、rootユーザーとして実行された場合に発生する可能性があります。systemdはgunicorn.sockを正常に生成しましたが、Nginxはそれを使用できません。
原因の1つとして、ルートディレクトリ(/)とgunicorn.sockファイル間の権限が制限されていることが考えられます。ソケットファイルと、その各親ディレクトリの権限と所有権を確認してください:
|
1 |
namei -l /run/gunicorn.sock |
最初の列はファイルの権限を示しています。2番目の列は所有者ユーザー、3番目の列は所有者グループを示しています。gunicorn.sockに至るまでのディレクトリのいずれかに適切な読み取りおよび実行権限がない場合、Nginxはソケットへのアクセスに失敗します。
-
Djangoが「could not connect to the server: Connection refused」を表示する
これは、DjangoがPostgreSQLサーバーへの接続に失敗したことを示しています。PostgreSQLサーバーが起動して実行されていることを確認してください:
|
1 |
sudo systemctl status postgresql |
起動していない場合は、次のコマンドを実行して起動し、有効にします。
|
1 2 |
sudo systemctl start postgresql sudo systemctl enable postgresql |
それでもこのエラーが発生する場合は、データベースの認証情報が以下で適切に定義されていることを確認してください: settings.py:
|
1 |
~/viktor_project/viktor_project/settings.py |
その他のトラブルシューティング
追加のトラブルシューティングのために、さまざまなログが用意されています。これらのログは、問題の原因を絞り込むのに役立ちます。
役立つログの一覧は次のとおりです。
- Nginxログ
|
1 |
sudo journalctl -u nginx |
- アクセスログ - Nginx
|
1 |
sudo less /var/log/nginx/access.log |
- エラーログ - Nginx
|
1 |
sudo less /var/log/nginx/error.log |
- アプリケーションログ - Gunicorn
|
1 |
sudo journalctl -u gunicorn |
- ソケットログ - Gunicorn
|
1 |
sudo journalctl -u gunicorn.socket |
|
1 |
sudo systemctl restart gunicorn |
|
1 2 |
sudo systemctl daemon-reload sudo systemctl restart gunicorn.socket gunicorn.service |
|
1 2 |
sudo nginx -t sudo systemctl restart nginx |
最後に
このガイドでは、Djangoの基盤を構築する方法を説明しました。Djangoはウェブアプリケーションの一般的なコンポーネントの多くを提供しているため、独自の要素に集中することができます。Djangoプロジェクトは仮想環境内で動作します。GunicornはクライアントのリクエストとDjangoの間の通信を管理します。最後に、Nginxはクライアント接続を処理するリバースプロキシとして機能します。
快適なコンピューティングを!










コメント
コメントはまだありません。最初のコメントを投稿しましょう。