序章

Django は、PythonアプリケーションまたはWebサイトをすばやく立ち上げるのに役立つ強力なWebフレームワークです。 これには、オブジェクトリレーショナルマッパー、Python API、アプリケーション用のカスタマイズ可能な管理インターフェイスなど、いくつかの便利な機能が含まれています。 また、キャッシングフレームワークが含まれており、URLディスパッチャーおよびテンプレートシステムを通じてクリーンなアプリの設計を促進します。

箱から出してすぐに、Djangoにはテストとローカル開発用の最小限のWebサーバーが含まれていますが、本番ユースケース用のより堅牢なサービングインフラストラクチャと組み合わせる必要があります。 Djangoは、静的ファイルリクエストとHTTPSリダイレクトを処理するためのNginxウェブサーバーと、アプリを提供するための GunicornWSGIサーバーとともに展開されることがよくあります。

このガイドでは、JavascriptやCSSスタイルシートなどの静的ファイルをDigitalOcean Spacesにオフロードし、オプションでCオンテントD配信N[X208X ] etwork、またはCDN。これらのファイルをエンドユーザーの近くに保存して、転送時間を短縮します。 また、データストアとしてDigitalOcean Managed PostgreSQL database を使用して、データレイヤーを簡素化し、スケーラブルなPostgreSQLデータベースを手動で構成する必要をなくします。

前提条件

このガイドを開始する前に、次のものを利用できるようにしておく必要があります。

  • 基本的なファイアウォールと非rootユーザーを備えた新しいUbuntu18.04サーバーインスタンス sudo 構成された特権。 Ubuntu 18.04を使用した初期サーバーセットアップを実行することで、これをセットアップする方法を学ぶことができます。
  • DigitalOceanマネージドPostgreSQLクラスター。 クラスタの作成方法については、DigitalOcean管理対象データベースの製品ドキュメントを参照してください。
  • Djangoプロジェクトの静的ファイルとこのスペースのアクセスキーのセットを保存するDigitalOceanスペース。 スペースの作成方法については、スペースの作成方法の製品ドキュメントを参照してください。また、スペースのアクセスキーの作成方法については、アクセスキーを使用したスペースへのアクセスの共有を参照してください。
  • Nginxは、選択したドメイン名で動作するようにサーバーにインストール、保護、および構成されています。 Let’s Encrypt を使用したAレコードの設定とNginxインストールの保護の詳細については、 Ubuntu18.04でLet’sEncryptを使用してNginxを保護する方法を参照してください。

ステップ1—Ubuntuリポジトリからパッケージをインストールする

まず、Ubuntuリポジトリから必要なすべてのアイテムをダウンロードしてインストールします。 Pythonパッケージマネージャーを使用します pip 少し後で追加のコンポーネントをインストールします。

最初にローカルを更新する必要があります apt パッケージインデックスを作成し、パッケージをダウンロードしてインストールします。

このガイドでは、 Python3でDjangoを使用します。 必要なライブラリをインストールするには、サーバーにログインして次のように入力します。

  1. sudo apt update
  2. sudo apt install python3-pip python3-dev libpq-dev curl postgresql-client

これによりインストールされます pip、Gunicornのビルドに必要なPython開発ファイル、 Pyscopg PostgreSQL Pythonアダプターのビルドに必要なlibpqヘッダーファイル、およびPostgreSQLコマンドラインクライアント。

打つ Y その後 ENTER パッケージのダウンロードとインストールを開始するように求められたら。

次に、Djangoアプリで動作するようにデータベースを構成します。

ステップ2—PostgreSQLデータベースとユーザーを作成する

次に、Djangoアプリケーション用のデータベースとデータベースユーザーを作成します。

まず、クラウドコントロールパネルからデータベースに移動し、データベースをクリックして、クラスターの接続パラメーターを取得します。 クラスタのいくつかのパラメータを含む接続の詳細ボックスが表示されます。 これらを書き留めてください。

コマンドラインに戻り、これらの資格情報と psql インストールしたばかりのPostgreSQLクライアント:

  1. psql -U username -h host -p port -d database -set=sslmode=require

プロンプトが表示されたら、Postgresユーザー名の横に表示されているパスワードを入力し、 ENTER.

データベースを管理できるPostgreSQLプロンプトが表示されます。

まず、プロジェクトのデータベースを作成します。 polls:

  1. CREATE DATABASE polls;

注:すべてのPostgresステートメントはセミコロンで終了する必要があるため、問題が発生している場合は、コマンドがセミコロンで終了していることを確認してください。

これで、に切り替えることができます polls データベース:

  1. \c polls;

次に、プロジェクトのデータベースユーザーを作成します。 安全なパスワードを選択してください。

  1. CREATE USER myprojectuser WITH PASSWORD 'password';

次に、作成したユーザーの接続パラメーターのいくつかを変更します。 これにより、データベース操作が高速化されるため、接続が確立されるたびに正しい値を照会して設定する必要がなくなります。

デフォルトのエンコーディングをに設定しています UTF-8、Djangoが期待しています。 また、デフォルトのトランザクション分離スキームを「読み取りコミット」に設定しています。これは、コミットされていないトランザクションからの読み取りをブロックします。 最後に、タイムゾーンを設定します。 デフォルトでは、Djangoプロジェクトは使用するように設定されます UTC. これらはすべて、Djangoプロジェクト自体からの推奨事項です。

PostgreSQLプロンプトで次のコマンドを入力します。

  1. ALTER ROLE myprojectuser SET client_encoding TO 'utf8';
  2. ALTER ROLE myprojectuser SET default_transaction_isolation TO 'read committed';
  3. ALTER ROLE myprojectuser SET timezone TO 'UTC';

これで、新しいユーザーに新しいデータベースを管理するためのアクセス権を与えることができます。

  1. GRANT ALL PRIVILEGES ON DATABASE polls TO myprojectuser;

終了したら、次のように入力してPostgreSQLプロンプトを終了します。

  1. \q

これで、Djangoアプリがこのデータベースに接続して管理する準備が整いました。

次のステップでは、インストールします virtualenv Djangoプロジェクト用のPython仮想環境を作成します。

ステップ3—プロジェクト用のPython仮想環境を作成する

アプリケーションで動作するようにデータベースを設定したので、このプロジェクトの依存関係をシステムのグローバルPythonインストールから分離するPython仮想環境を作成します。

これを行うには、最初ににアクセスする必要があります virtualenv 指図。 これをインストールできます pip.

アップグレード pip 次のように入力してパッケージをインストールします。

  1. sudo -H pip3 install --upgrade pip
  2. sudo -H pip3 install virtualenv

virtualenv インストールすると、Python仮想環境を保存するディレクトリを作成し、Djangoで使用できるようになります。 polls アプリ。

と呼ばれるディレクトリを作成します envs それにナビゲートします:

  1. mkdir envs
  2. cd envs

このディレクトリ内に、というPython仮想環境を作成します polls 次のように入力します。

  1. virtualenv polls

これにより、というディレクトリが作成されます polls 以内 envs ディレクトリ。 内部には、Pythonのローカルバージョンとのローカルバージョンがインストールされます pip. これを使用して、プロジェクト用に分離されたPython環境をインストールおよび構成できます。

プロジェクトのPython要件をインストールする前に、仮想環境をアクティブ化する必要があります。 次のように入力すると、次のように入力できます。

  1. source polls/bin/activate

プロンプトが変化して、Python仮想環境内で操作していることを示します。 次のようになります。 (polls)user@host:~/envs$.

仮想環境をアクティブにして、Django、Gunicorn、および psycopg2 ローカルインスタンスが pip:

注:仮想環境がアクティブ化されたとき(プロンプトが (polls) その前に)、使用する pip それ以外の pip3、Python3を使用している場合でも。 ツールの仮想環境のコピーには常に名前が付けられます pip、Pythonのバージョンに関係なく。

  1. pip install django gunicorn psycopg2-binary

これで、Djangoを実行するために必要なすべてのソフトウェアが揃うはずです。 polls アプリ。 次のステップでは、Djangoプロジェクトを作成し、このアプリをインストールします。

ステップ4—PollsDjangoアプリケーションを作成する

これで、サンプルアプリケーションを設定できます。 このチュートリアルでは、DjangoドキュメントのPollsデモアプリケーションを使用します。 これは、ユーザーが投票を表示して投票できる公開サイトと、管理者が投票を変更、作成、および削除できる管理コントロールパネルで構成されています。

このガイドでは、チュートリアルの手順をスキップし、DigitalOceanコミュニティ django-pollsrepoから最終的なアプリケーションのクローンを作成します。

手順を手動で完了する場合は、次のディレクトリを作成します。 django-polls ホームディレクトリに移動し、そこに移動します。

  1. cd
  2. mkdir django-polls
  3. cd django-polls

そこから、公式のDjangoドキュメントから最初のDjangoアプリの作成チュートリアルに従うことができます。 完了したら、ステップ5にスキップします。

完成したアプリのクローンを作成するだけの場合は、ホームディレクトリに移動して使用します git django-polls repo のクローンを作成するには:

  1. cd
  2. git clone https://github.com/do-community/django-polls.git

cd その中に、ディレクトリの内容を一覧表示します。

  1. cd django-polls
  2. ls

次のオブジェクトが表示されます。

Output
LICENSE README.md manage.py mysite polls templates

manage.py アプリを操作するために使用されるメインのコマンドラインユーティリティです。 polls が含まれています polls アプリコード、および mysite プロジェクトスコープのコードと設定が含まれています。 templates 管理インターフェイス用のカスタムテンプレートファイルが含まれています。 プロジェクトの構造とファイルの詳細については、Djangoの公式ドキュメントからプロジェクトの作成を参照してください。

アプリを実行する前に、デフォルト設定を調整してデータベースに接続する必要があります。

ステップ5—アプリの設定を調整する

このステップでは、Djangoプロジェクトのデフォルト構成を変更してセキュリティを強化し、Djangoをデータベースに接続して、静的ファイルをローカルディレクトリに収集します。

テキストエディタで設定ファイルを開くことから始めます。

  1. nano ~/django-polls/mysite/settings.py

を見つけることから始めます ALLOWED_HOSTS 指令。 これは、Djangoインスタンスへの接続に使用するアドレスまたはドメイン名のリストを定義します。 このリストにないHostヘッダーを持つ着信要求は、例外を発生させます。 Djangoでは、特定のクラスのセキュリティ脆弱性を防ぐために、これを設定する必要があります。

角かっこ内に、Djangoサーバーに関連付けられているIPアドレスまたはドメイン名をリストします。 各項目は、エントリをコンマで区切って引用符で囲む必要があります。 リストには次のものも含まれます localhost、ローカルNginxインスタンスを介して接続をプロキシするため。 ドメイン全体とサブドメインのリクエストを含める場合は、エントリの先頭にピリオドを追加します。

以下のスニペットには、これらのエントリがどのように表示されるかを示すコメントアウトされた例がいくつかあります。

〜/ django-polls / mysite / settings.py
. . .

# The simplest case: just add the domain name(s) and IP addresses of your Django server
# ALLOWED_HOSTS = [ 'example.com', '203.0.113.5']
# To respond to 'example.com' and any subdomains, start the domain with a dot
# ALLOWED_HOSTS = ['.example.com', '203.0.113.5']
ALLOWED_HOSTS = ['your_server_domain_or_IP', 'second_domain_or_IP', . . ., 'localhost']

. . . 

次に、データベースアクセスを構成するファイルのセクションを見つけます。 それはで始まります DATABASES. ファイル内の構成はSQLiteデータベース用です。 プロジェクト用にPostgreSQLデータベースをすでに作成しているため、これらの設定を調整する必要があります。

Djangoに使用するように指示します psycopg2 インストールしたデータベースアダプタ pip、デフォルトのSQLiteエンジンの代わりに。 また、ステップ2で参照されている接続パラメータを再利用します。 この情報は、DigitalOceanクラウドコントロールパネルの管理対象データベースセクションからいつでも見つけることができます。

データベース設定でファイルを更新します:データベース名(polls)、データベースユーザー名、データベースユーザーのパスワード、およびデータベース hostport. データベース固有の値を独自の情報に置き換えてください。

〜/ django-polls / mysite / settings.py
. . .

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'polls',
        'USER': 'myprojectuser',
        'PASSWORD': 'password',
        'HOST': 'managed_db_host',
        'PORT': 'managed_db_port',
    }
}

. . .

次に、ファイルの一番下に移動し、静的ファイルを配置する場所を示す設定を追加します。 これは、Nginxがこれらのアイテムのリクエストを処理できるようにするために必要です。 次の行は、Djangoにそれらをというディレクトリに配置するように指示しています static ベースプロジェクトディレクトリ:

〜/ django-polls / mysite / settings.py
. . .

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')

終了したら、ファイルを保存して閉じます。

この時点で、Djangoプロジェクトのデータベース、セキュリティ、静的ファイルの設定を構成しました。 あなたが従った場合 polls チュートリアルを最初から行い、GitHubリポジトリのクローンを作成しなかった場合は、ステップ6に進むことができます。 GitHubリポジトリのクローンを作成した場合、追加の手順が1つ残っています。

Django設定ファイルには SECRET_KEY さまざまなDjangoオブジェクトのハッシュを作成するために使用される変数。 一意の予測できない値に設定することが重要です。 The SECRET_KEY 変数はGitHubリポジトリからスクラブされているため、組み込みの関数を使用して新しい変数を作成します。 django と呼ばれるPythonパッケージ get_random_secret_key(). コマンドラインから、Pythonインタープリターを開きます。

  1. python

次の出力とプロンプトが表示されます。

Output
Python 3.6.7 (default, Oct 22 2018, 11:32:17) [GCC 8.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>>

をインポートします get_random_secret_key Djangoパッケージから関数を作成し、関数を呼び出します。

  1. from django.core.management.utils import get_random_secret_key
  2. get_random_secret_key()

結果のキーをクリップボードにコピーします。

を押してPythonインタープリターを終了します CTRL+D.

次に、テキストエディタで設定ファイルをもう一度開きます。

nano ~/django-polls/mysite/settings.py

を見つけます SECRET_KEY 変数を作成し、生成したキーを貼り付けます。

〜/ django-polls / mysite / settings.py
. . .

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'your_secret_key_here'

. . .

ファイルを保存して閉じます。

次に、Django開発サーバーを使用してアプリをローカルでテストし、すべてが正しく構成されていることを確認します。

ステップ6—アプリをテストする

Django開発サーバーを実行する前に、 manage.py データベーススキーマを作成し、静的ファイルを収集するユーティリティ STATIC_ROOT ディレクトリ。

プロジェクトのベースディレクトリに移動し、PostgreSQLデータベースに初期データベーススキーマを作成します。 makemigrationsmigrate コマンド:

  1. cd django-polls
  2. ./manage.py makemigrations
  3. ./manage.py migrate

makemigrations Djangoモデルに加えられた変更に基づいて、移行またはデータベーススキーマの変更を作成します。 migrate これらの移行をデータベーススキーマに適用します。 Djangoでの移行の詳細については、Djangoの公式ドキュメントのMigrationsを参照してください。

次のように入力して、プロジェクトの管理ユーザーを作成します。

  1. ./manage.py createsuperuser

ユーザー名を選択し、メールアドレスを入力し、パスワードを選択して確認する必要があります。

次のように入力して、構成したディレクトリの場所にすべての静的コンテンツを収集できます。

  1. ./manage.py collectstatic

静的ファイルは、次のディレクトリに配置されます。 static プロジェクトディレクトリ内。

サーバーの初期設定ガイドに従った場合は、サーバーを保護するUFWファイアウォールが必要です。 開発サーバーをテストするには、使用するポートへのアクセスを許可する必要があります。

ポートの例外を作成する 8000 次のように入力します。

  1. sudo ufw allow 8000

Django開発サーバーを使用したアプリのテスト

最後に、次のコマンドでDjango開発サーバーを起動して、プロジェクトをテストできます。

  1. ./manage.py runserver 0.0.0.0:8000

Webブラウザーで、サーバーのドメイン名またはIPアドレスにアクセスし、その後にアクセスします。 :8000 そしてその polls 道:

  1. http://server_domain_or_IP:8000/polls

Pollsアプリのインターフェースが表示されます。

管理インターフェースを確認するには、サーバーのドメイン名またはIPアドレスにアクセスしてから、 :8000 および管理インターフェースのパス:

  1. http://server_domain_or_IP:8000/admin

Pollsアプリの管理者認証ウィンドウが表示されます。

で作成した管理ユーザー名とパスワードを入力します createsuperuser 指図。

認証後、Pollsアプリの管理インターフェースにアクセスできます。

探索が終了したら、 CTRL-C ターミナルウィンドウで、開発サーバーをシャットダウンします。

Gunicornを使用したアプリのテスト

静的ファイルをオフロードする前に最後に実行したいのは、Gunicornをテストして、アプリケーションにサービスを提供できることを確認することです。 これを行うには、プロジェクトディレクトリに入り、 gunicorn プロジェクトのWSGIモジュールをロードするには:

  1. gunicorn --bind 0.0.0.0:8000 mysite.wsgi

これにより、Django開発サーバーが実行されていたのと同じインターフェースでGunicornが起動します。 戻ってアプリをもう一度テストできます。

注: Gunicornはこれに関与する静的CSSコンテンツを見つける方法を知らないため、管理インターフェースにはスタイルが適用されません。

Djangoへの相対ディレクトリパスを指定して、Gunicornにモジュールを渡しました。 wsgi.py ファイル、アプリケーションへのエントリポイント。 このファイルは、と呼ばれる関数を定義します application、アプリケーションと通信します。 WSGI仕様の詳細については、ここをクリックをクリックしてください。

テストが終了したら、 CTRL-C ターミナルウィンドウでGunicornを停止します。

次に、アプリケーションの静的ファイルをDigitalOceanSpacesにオフロードします。

ステップ7—静的ファイルをDigitalOceanスペースにオフロードする

この時点で、GunicornはDjangoアプリケーションを提供できますが、静的ファイルは提供できません。 通常、これらのファイルを提供するようにNginxを構成しますが、このチュートリアルでは、django-storagesプラグインを使用してそれらをDigitalOceanSpacesにオフロードします。 これにより、静的コンテンツを一元化し、サーバーリソースを解放することで、Djangoを簡単にスケーリングできます。 さらに、DigitalOceanSpacesCDNを使用してこの静的コンテンツを配信できます。

Django静的ファイルをオブジェクトストレージにオフロードするための完全なガイドについては、Djangoを使用してオブジェクトストレージをセットアップする方法を参照してください。

インストールと構成 django-storages

まず、インストールします。 django-storages Pythonパッケージ。 The django-storages パッケージはDjangoに S3Boto3Storage を使用するストレージバックエンド boto3 S3互換のオブジェクトストレージサービスにファイルをアップロードするためのライブラリ。

開始するには、django-storagesboto3 を使用したPythonパッケージ pip:

  1. pip install django-storages boto3

次に、アプリのDjango設定ファイルをもう一度開きます。

  1. nano ~/django-polls/mysite/settings.py

下に移動します INSTALLED_APPS ファイルのセクション、および追加 storages インストールされているアプリのリストへ:

〜/ django-polls / mysite / settings.py
. . .

INSTALLED_APPS = [
    . . .
    'django.contrib.staticfiles',
    'storages',
]

. . .

ファイルをさらに下にスクロールして、 STATIC_URL 以前に変更しました。 これらの値を上書きして、新しい値を追加します S3Boto3Storage バックエンドパラメータ。 以前に入力したコードを削除し、スペースのアクセスと場所の情報を含む次のブロックを追加します。 ここで強調表示されている値を独自の情報に置き換えることを忘れないでください::

〜/ django-polls / mysite / settings.py
. . .

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

AWS_ACCESS_KEY_ID = 'your_spaces_access_key'
AWS_SECRET_ACCESS_KEY = 'your_spaces_secret_key'

AWS_STORAGE_BUCKET_NAME = 'your_space_name'
AWS_S3_ENDPOINT_URL = 'spaces_endpoint_URL'
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
AWS_DEFAULT_ACL = 'public-read'

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

STATIC_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, AWS_LOCATION)
STATIC_ROOT = 'static/'

次の構成項目を定義します。

  • AWS_ACCESS_KEY_ID:チュートリアルの前提条件で作成したスペースのアクセスキーID。 アクセスキーのセットを作成しなかった場合は、アクセスキーを使用したスペースへのアクセスの共有を参照してください。
  • AWS_SECRET_ACCESS_KEY:DigitalOceanSpaceの秘密鍵。
  • AWS_STORAGE_BUCKET_NAME:DigitalOceanSpaceの名前。
  • AWS_S3_ENDPOINT_URL :オブジェクトストレージサービスへのアクセスに使用されるエンドポイントURL。 DigitalOceanの場合、これは次のようになります https://nyc3.digitaloceanspaces.com スペースリージョンによって異なります。
  • AWS_S3_OBJECT_PARAMETERS 静的ファイルにキャッシュ制御ヘッダーを設定します。
  • AWS_LOCATION:すべての静的ファイルが配置されるオブジェクトストレージバケット内のディレクトリを定義します。
  • AWS_DEFAULT_ACL:静的ファイルのアクセス制御リスト(ACL)を定義します。 に設定する public-read エンドユーザーがファイルに公的にアクセスできるようにします。
  • STATICFILES_STORAGE:Djangoが静的ファイルをオフロードするために使用するストレージバックエンドを設定します。 このバックエンドは、DigitalOceanSpacesを含むすべてのS3互換バックエンドで動作するはずです。
  • STATIC_URL:静的ファイルのURLを生成するときにDjangoが使用するベースURLを指定します。 ここでは、エンドポイントURLと静的ファイルサブディレクトリを組み合わせて、静的ファイルのベースURLを作成します。
  • STATIC_ROOT:静的ファイルをオブジェクトストレージにコピーする前に、ローカルで収集する場所を指定します。

編集が完了したら、ファイルを保存して閉じます。

これから、走ると collectstatic、Djangoはアプリの静的ファイルをSpaceにアップロードします。 Djangoを起動すると、このスペースからCSSやJavascriptなどの静的アセットの提供が開始されます。

次のセクションでは、このSpaceのCDNを有効にし、オプションでSpacesCDNのカスタムサブドメインを構成します。 これにより、地理的に分散したエッジサーバーのネットワーク全体にキャッシュすることで、Djangoプロジェクトの静的ファイルの配信が高速化されます。 CDNの詳細については、CDNを使用した静的コンテンツ配信の高速化を参照してください。 Spaces CDNを有効にしたくない場合は、CORSヘッダーの設定に進んでください。

CDNの有効化(オプション)

DigitalOcean Spaces CDNを介した静的ファイル配信をアクティブ化するには、まずDigitalOceanSpaceのCDNを有効にします。 これを行う方法については、DigitalOcean製品ドキュメントの SpacesCDNを有効にする方法を参照してください。

Spaces CDNでカスタムドメインを使用する場合は、サブドメインでSpaces CDNエンドポイントをカスタマイズする方法に従って、サブドメインCNAMEレコードと適切なSSL証明書を作成します。

SpacesCDNでカスタムドメインを使用することを強くお勧めします。 これにより、オフロードされたアセットのURLをDjangoサイトのURLと同様に保つことで、サイトの検索エンジン最適化(SEO)が大幅に向上します。 Spaces CDNでカスタムドメインを使用するには、最初にドメインをDigitalOceanアカウントに追加する必要があります。 これを行う方法については、ドメインを追加する方法を参照してください。

スペースのCDNを有効にし、オプションでそのカスタムサブドメインを作成したら、クラウドコントロールパネルを使用してスペースに移動します。 スペース名の下に新しいEndpointsリンクが表示されます。

これらのエンドポイントには、スペース名が含まれている必要があります。 Spaces CDNのカスタムサブドメインを作成した場合、このリストにはサブドメインという追加のエンドポイントが含まれます。

Edge エンドポイントは、SpacesオブジェクトのリクエストをCDN経由でルーティングし、可能な限りエッジキャッシュからそれらを提供します。 このEdgeエンドポイントを書き留めてください。これを使用して、 django-storages プラグイン。 Spaces CDNのサブドメインを作成した場合、SubdomainエンドポイントはこのEdgeエンドポイントのエイリアスです。

次に、アプリのDjango設定ファイルをもう一度編集します。

  1. nano ~/django-polls/mysite/settings.py

最近変更した[静的ファイル]セクションに移動します。 追加します AWS_S3_CUSTOM_DOMAIN を構成するためのパラメーター django-storages プラグインCDNエンドポイントと更新 STATIC_URL この新しいCDNエンドポイントを使用するためのパラメーター:

〜/ django-polls / mysite / settings.py
. . .

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/

# Moving static assets to DigitalOcean Spaces as per:
# how-to-set-up-object-storage-with-django
AWS_ACCESS_KEY_ID = 'your_spaces_access_key'
AWS_SECRET_ACCESS_KEY = 'your_spaces_secret_key'

AWS_STORAGE_BUCKET_NAME = 'your_space_name'
AWS_S3_ENDPOINT_URL = 'spaces_endpoint_URL'
AWS_S3_CUSTOM_DOMAIN = 'spaces_edge_endpoint_URL'
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
AWS_DEFAULT_ACL = 'public-read'

STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

STATIC_URL = '{}/{}/'.format(AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATIC_ROOT = 'static/'

ここで、 spaces_edge_endpoint_URL 書き留めたばかりのEdgeエンドポイントを使用して、 https:// プレフィックス。 たとえば、エッジエンドポイントURLが https://example.sfo2.cdn.digitaloceanspaces.com, AWS_S3_CUSTOM_DOMAIN 次のように設定する必要があります example.sfo2.cdn.digitaloceanspaces.com.

カスタムサブドメインを作成した場合は、 spaces_edge_endpoint_URL カスタムサブドメインエンドポイントを使用して、 https:// プレフィックス。 たとえば、サブドメインのエンドポイントURLが https://assets.example.com, AWS_S3_CUSTOM_DOMAIN 次のように設定する必要があります assets.example.com.

完了したら、ファイルを保存して閉じます。

Djangoを起動すると、DigitalOceanSpaceのCDNを使用して静的コンテンツが提供されるようになります。

これがすべて正しく機能していることをテストする前に、Spacesファイルの Cross-Origin Resource Sharing(CORS)ヘッダーを構成する必要があります。そうしないと、特定の静的アセットへのアクセスがWebブラウザーによって拒否される場合があります。 Djangoで使用されているのと同じドメインに対してSpacesCDNでカスタムサブドメインを使用している場合は、 Spaces Static FileDeliveryのテストに進んでください。

CORSヘッダーの設定

CORSヘッダーは、あるドメインで実行されているアプリケーションが別のドメインにあるスクリプトまたはリソースにアクセスできることをWebブラウザーに通知します。 この場合、スペース内の静的ファイルのリクエストがWebブラウザーによって拒否されないように、Djangoサーバーのドメインのクロスオリジンリソース共有を許可する必要があります。

注:この手順は、SpacesCDNでカスタムサブドメインを使用していない場合にのみ必要です。

まず、クラウドコントロールパネルを使用して、スペースの設定ページに移動します。

CORS構成セクションで、追加をクリックします。

ここで、 Origin の下に、ワイルドカードの原点を入力します。 *

警告:アプリを本番環境にデプロイするときは、必ずこの値を正確な元のドメイン( http:// また https:// プロトコル)。 ワイルドカードオリジンとしてこれを残すことは安全ではありません。オリジンをhttp://example.com:8000(非標準ポートを使用)に設定することは現在サポートされていないため、ここではテスト目的でのみこれを行います。

許可されたメソッドで、GETを選択します。

ヘッダーの追加をクリックし、表示されるテキストボックスに次のように入力します Access-Control-Allow-Origin.

アクセス制御の最大経過時間をに設定します 600 作成したヘッダーが10分ごとに期限切れになるようにします。

[オプションの保存]をクリックします。

今後、スペース内のオブジェクトには適切なものが含まれます Access-Control-Allow-Origin 応答ヘッダー。最新の安全なWebブラウザーがドメイン間でこれらのファイルをフェッチできるようにします。

テストスペースの静的ファイル配信

ここで、DjangoがDigitalOceanSpaceから静的ファイルを正しく提供していることをテストします。

Djangoアプリディレクトリに移動します。

  1. cd ~/django-polls

ここから、実行します collectstatic 静的ファイルを収集してDigitalOceanSpaceにアップロードするには:

  1. python manage.py collectstatic

次の出力が表示されます。

Output
You have requested to collect static files at the destination location as specified in your settings. This will overwrite existing files! Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel:

タイプ yes とヒット ENTER 確認するために。

次のような出力が表示されます。

Output
121 static files copied.

これは、Djangoが正常にアップロードしたことを確認します polls 静的ファイルをスペースに適用します。 クラウドコントロールパネルを使用してスペースに移動し、 static ディレクトリ。

次に、Djangoが適切なURLを書き換えていることを確認します。

Gunicornサーバーを起動します。

  1. gunicorn --bind 0.0.0.0:8000 mysite.wsgi

Webブラウザーで、サーバーのドメイン名またはIPアドレスにアクセスし、その後にアクセスします。 :8000/admin:

http://server_domain_or_IP:8000/admin

もう一度、Pollsアプリの管理者認証ウィンドウが表示されます。今回は正しいスタイルで表示されます。

次に、ブラウザの開発者ツールを使用して、ページの内容を調べ、ソースファイルの保存場所を明らかにします。

Google Chromeを使用してこれを行うには、ページを右クリックして、検査を選択します。

次のウィンドウが表示されます。

ここから、ツールバーのソースをクリックします。 左側のペインのソースファイルのリストに、次のように表示されます。 /admin/login Djangoサーバーのドメインの下で、 static/admin SpaceのCDNエンドポイントの下。 内部 static/admin、両方が表示されるはずです cssfonts ディレクトリ。

これにより、CSSスタイルシートとフォントがSpaceのCDNから正しく提供されていることが確認されます。

テストが終了したら、 CTRL-C ターミナルウィンドウでGunicornを停止します。

次のように入力すると、アクティブなPython仮想環境を無効にできます deactivate:

  1. deactivate

プロンプトは通常に戻るはずです。

この時点で、Djangoサーバーから静的ファイルを正常にオフロードし、オブジェクトストレージからそれらを提供しています。 これで、システムサービスとして自動的に開始するようにGunicornを構成することに進むことができます。

ステップ8—Gunicorn用のsystemdソケットおよびサービスファイルの作成

ステップ6では、GunicornがDjangoアプリケーションと対話できることをテストしましたが、アプリケーションサーバーを起動および停止するためのより堅牢な方法を実装する必要があります。 これを実現するために、systemdサービスとソケットファイルを作成します。

Gunicornソケットは起動時に作成され、接続をリッスンします。 接続が発生すると、systemdは接続を処理するためにGunicornプロセスを自動的に開始します。

まず、Gunicornのsystemdソケットファイルを作成して開きます。 sudo 特権:

  1. sudo nano /etc/systemd/system/gunicorn.socket

内部では、を作成します [Unit] ソケットを説明するセクション、 [Socket] ソケットの位置を定義するセクション、および [Install] ソケットが適切なタイミングで作成されていることを確認するセクション。 次のコードをファイルに追加します。

/etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

終了したら、ファイルを保存して閉じます。

次に、Gunicornのsystemdサービスファイルを作成して開きます。 sudo テキストエディタの権限。 サービスファイル名は、拡張子を除いてソケットファイル名と一致する必要があります。

  1. sudo nano /etc/systemd/system/gunicorn.service

から始めます [Unit] メタデータと依存関係を指定するセクション。 ここにサービスの説明を入力し、ネットワークターゲットに到達した後にのみこれを開始するようにinitシステムに指示します。 私たちのサービスはソケットファイルのソケットに依存しているため、 Requires その関係を示すディレクティブ:

/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

次に、 [Service] セクション。 実行する処理を行うユーザーとグループを指定します。 プロセスは関連するすべてのファイルを所有しているため、通常のユーザーアカウントにプロセスの所有権を付与します。 グループの所有権を www-data NginxがGunicornと簡単に通信できるようにグループ化します。

次に、作業ディレクトリをマップし、サービスの開始に使用するコマンドを指定します。 この場合、仮想環境内にインストールされているGunicorn実行可能ファイルへのフルパスを指定する必要があります。 プロセスを、内で作成したUnixソケットにバインドします。 /run プロセスがNginxと通信できるようにディレクトリ。 すべてのデータを標準出力に記録して、 journald プロセスはGunicornのログを収集できます。 ここでは、ワーカープロセスの数など、オプションのGunicornの微調整を指定することもできます。 ここでは、3つのワーカープロセスでGunicornを実行します。

次のサービスセクションをファイルに追加します。 ここにリストされているユーザー名を自分のユーザー名に置き換えてください。

/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=sammy
Group=www-data
WorkingDirectory=/home/sammy/django-polls
ExecStart=/home/sammy/envs/polls/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          mysite.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/django-polls
ExecStart=/home/sammy/envs/polls/bin/gunicorn \
          --access-logfile - \
          --workers 3 \
          --bind unix:/run/gunicorn.sock \
          mysite.wsgi:application

[Install]
WantedBy=multi-user.target

これで、systemdサービスファイルが完成しました。 今すぐ保存して閉じます。

これで、Gunicornソケットを起動して有効にできます。 これにより、ソケットファイルが次の場所に作成されます。 /run/gunicorn.sock 今そして起動時に。 そのソケットに接続が確立されると、systemdは自動的に gunicorn.service それを処理するには:

  1. sudo systemctl start gunicorn.socket
  2. sudo systemctl enable gunicorn.socket

ソケットファイルを確認することで、操作が成功したことを確認できます。

Gunicornソケットファイルの確認

プロセスのステータスをチェックして、プロセスが正常に開始されたかどうかを確認します。

  1. sudo systemctl status gunicorn.socket

次の出力が表示されます。

Output
Failed to dump process list, ignoring: No such file or directory ● gunicorn.socket - gunicorn socket Loaded: loaded (/etc/systemd/system/gunicorn.socket; enabled; vendor preset: enabled) Active: active (running) since Tue 2019-03-05 19:19:16 UTC; 1h 22min ago Listen: /run/gunicorn.sock (Stream) CGroup: /system.slice/gunicorn.socket Mar 05 19:19:16 django systemd[1]: Listening on gunicorn socket.

次に、の存在を確認します gunicorn.sock 内のファイル /run ディレクトリ:

  1. file /run/gunicorn.sock
Output
/run/gunicorn.sock: socket

の場合 systemctl status コマンドはエラーが発生したことを示した、またはあなたが見つからない場合 gunicorn.sock ディレクトリ内のファイルが表示されている場合は、Gunicornソケットが正しく作成されていないことを示しています。 次のように入力して、Gunicornソケットのログを確認します。

  1. sudo journalctl -u gunicorn.socket

あなたのをもう一度見てください /etc/systemd/system/gunicorn.socket 続行する前に問題を修正するためのファイル。

ソケットアクティベーションのテスト

現在、始めたばかりの場合 gunicorn.socket ユニット、 gunicorn.service ソケットはまだ接続を受信していないため、アクティブにはなりません。 次のように入力して、これを確認できます。

  1. sudo systemctl status gunicorn
Output
● gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: inactive (dead)

ソケットアクティベーションメカニズムをテストするために、を介してソケットに接続を送信できます curl 次のように入力します。

  1. curl --unix-socket /run/gunicorn.sock localhost

ターミナルにアプリケーションからのHTML出力が表示されます。 これは、Gunicornが起動し、Djangoアプリケーションを提供できることを示しています。 次のように入力して、Gunicornサービスが実行されていることを確認できます。

  1. sudo systemctl status gunicorn
Output
● gunicorn.service - gunicorn daemon Loaded: loaded (/etc/systemd/system/gunicorn.service; disabled; vendor preset: enabled) Active: active (running) since Tue 2019-03-05 20:43:56 UTC; 1s ago Main PID: 19074 (gunicorn) Tasks: 4 (limit: 4915) CGroup: /system.slice/gunicorn.service ├─19074 /home/sammy/envs/polls/bin/python3 /home/sammy/envs/polls/bin/gunicorn --access-logfile - --workers 3 --bind unix:/run/gunicorn.sock mysite.wsgi:application ├─19098 /home/sammy/envs/polls/bin/python3 /home/sammy/envs/polls/bin/gunicorn . . . Mar 05 20:43:56 django systemd[1]: Started gunicorn daemon. Mar 05 20:43:56 django gunicorn[19074]: [2019-03-05 20:43:56 +0000] [19074] [INFO] Starting gunicorn 19.9.0 . . . Mar 05 20:44:15 django gunicorn[19074]: - - [05/Mar/2019:20:44:15 +0000] "GET / HTTP/1.1" 301 0 "-" "curl/7.58.0"

からの出力の場合 curl またはの出力 systemctl status 問題が発生したことを示します。詳細については、ログを確認してください。

  1. sudo journalctl -u gunicorn

あなたもチェックすることができます /etc/systemd/system/gunicorn.service 問題のファイル。 このファイルに変更を加えた場合は、必ずデーモンをリロードしてサービス定義を再読み込みし、Gunicornプロセスを再起動してください。

  1. sudo systemctl daemon-reload
  2. sudo systemctl restart gunicorn

Nginxサーバーの構成に進む前に、問題のトラブルシューティングを必ず行ってください。

ステップ8—NginxHTTPSとGunicornプロキシパッシングの設定

Gunicornがより堅牢な方法でセットアップされたので、接続を暗号化し、トラフィックをGunicornプロセスに渡すようにNginxを構成する必要があります。

前提条件に従い、Let’s Encryptを使用してNginxを設定した場合、Nginxで利用可能なドメインに対応するサーバーブロックファイルがすでに用意されているはずです。 sites-available ディレクトリ。 そうでない場合は、 Ubuntu 18.04でLet’sEncryptを使用してNginxを保護する方法に従って、この手順に戻ります。

これを編集する前に example.com サーバーブロックファイル、最初に削除します default Nginxのインストール後にデフォルトでロールアウトされるサーバーブロックファイル:

  1. sudo rm /etc/nginx/sites-enabled/default

ここで変更します example.com デフォルトの代わりにトラフィックをGunicornに渡すサーバーブロックファイル index.html 前提条件の手順で構成されたページ。

ドメインに対応するサーバーブロックファイルをエディターで開きます。

  1. sudo nano /etc/nginx/sites-available/example.com

次のようなものが表示されます。

/etc/nginx/sites-available/example.com
server {

        root /var/www/example.com/html;
        index index.html index.htm index.nginx-debian.html;

        server_name example.com www.example.com;

        location / {
                try_files $uri $uri/ =404;
        }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        listen 80;
        listen [::]:80;

        server_name example.com www.example.com;
    return 404; # managed by Certbot


}

これは、 Ubuntu 18.04にNginxをインストールする方法で作成されたデフォルトのサーバーブロックファイルと、Let’sEncryptによって自動的に追加された追加ファイルの組み合わせです。 このファイルの内容を削除し、HTTPトラフィックをHTTPSにリダイレクトし、前の手順で作成したGunicornソケットに着信要求を転送する新しい構成を記述します。

必要に応じて、を使用してこのファイルのバックアップを作成できます cp. テキストエディタを終了し、という名前のバックアップを作成します example.com.old:

  1. sudo cp /etc/nginx/sites-available/example.com /etc/nginx/sites-available/example.com.old

ここで、ファイルを再度開き、その内容を削除します。 新しい構成をブロックごとに作成します。

次のブロックに貼り付けることから始めます。これにより、HTTPリクエストがポートにリダイレクトされます。 80 HTTPSへ:

/etc/nginx/sites-available/example.com
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://example.com$request_uri;
}

ここでは、ポートでHTTPIPv4およびIPv6リクエストをリッスンします 80 リクエストをHTTPSポートにリダイレクトするために301応答ヘッダーを送信します 443 を使用して example.com ドメイン。 これにより、直接HTTPリクエストがサーバーのIPアドレスにリダイレクトされます。

このブロックの後に、次の設定コードのブロックを追加して、 example.com ドメイン:

/etc/nginx/sites-available/example.com
. . . 
server {
	listen [::]:443 ssl ipv6only=on;
	listen 443 ssl;
	server_name example.com www.example.com;
	
	# Let's Encrypt parameters
	ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
	include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
	
	location = /favicon.ico { access_log off; log_not_found off; }

    location / {
        proxy_pass         http://unix:/run/gunicorn.sock;
        proxy_redirect     off;

        proxy_set_header   Host              $http_host;
        proxy_set_header   X-Real-IP         $remote_addr;
        proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto https;
    }
}

ここでは、最初にポートでリッスンします 443 ヒットするリクエストの場合 example.comwww.example.com ドメイン。

次に、デフォルトのサーバーブロックファイルに含まれているものと同じLet’s Encrypt構成を提供します。これは、SSL証明書と秘密鍵の場所、およびいくつかの追加のセキュリティパラメーターを指定します。

The location = /favicon.ico 行は、ファビコンの検索に関する問題を無視するようにNginxに指示します。

最後 location = / ブロックは、ステップ8で構成されたGunicornソケットにリクエストを渡すようにNginxに指示します。 さらに、リクエストが転送されたことをアップストリームDjangoサーバーに通知し、さまざまなリクエストプロパティを提供するヘッダーを追加します。

これらの2つの構成ブロックを貼り付けると、最終的なファイルは次のようになります。

/etc/nginx/sites-available/example.com
server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 301 https://example.com$request_uri;
}
server {
        listen [::]:443 ssl ipv6only=on;
        listen 443 ssl;
        server_name example.com www.example.com;

        # Let's Encrypt parameters
        ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

        location = /favicon.ico { access_log off; log_not_found off; }

        location / {
          proxy_pass         http://unix:/run/gunicorn.sock;
          proxy_redirect     off;

          proxy_set_header   Host              $http_host;
          proxy_set_header   X-Real-IP         $remote_addr;
          proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;
          proxy_set_header   X-Forwarded-Proto https;
        }
}

終了したら、ファイルを保存して閉じます。

次のように入力して、構文エラーについてNginx構成をテストします。

  1. sudo nginx -t

構成にエラーがない場合は、次のように入力してNginxを再起動します。

  1. sudo systemctl restart nginx

これで、サーバーのドメインまたはIPアドレスにアクセスしてアプリケーションを表示できるようになります。 ブラウザは、安全なHTTPS接続を使用してDjangoバックエンドに接続する必要があります。

Djangoプロジェクトを完全に保護するには、いくつかのセキュリティパラメータを追加する必要があります settings.py ファイル。 エディターでこのファイルを再度開きます。

  1. nano ~/django-polls/mysite/settings.py

ファイルの一番下までスクロールし、次のパラメータを追加します。

〜/ django-polls / mysite / settings.py
. . .

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True

これらの設定は、サーバーでHTTPSを有効にしていることをDjangoに通知し、「安全な」Cookieを使用するように指示します。 これらの設定の詳細については、DjangoのセキュリティのSSL/HTTPSセクションを参照してください。

完了したら、ファイルを保存して閉じます。

最後に、Gunicornを再起動します。

  1. sudo systemctl restart gunicorn

この時点で、HTTPリクエストをリダイレクトし、これらのリクエストをGunicornに渡すようにNginxを設定しました。 これで、DjangoプロジェクトとアプリでHTTPSが完全に有効になります。 エラーが発生した場合は、NginxとGunicornのトラブルシューティングに関するこのディスカッションが役立つ場合があります。

警告: CORSヘッダーの構成で説明されているように、Spaces CDNのカスタムサブドメインを構成しなかった場合は、必ずOriginを変更してください。 ]ワイルドカードから * ドメインからドメイン名(https://example.com このガイドで)エンドユーザーがアプリにアクセスできるようにする前に。

結論

このガイドでは、Ubuntu18.04サーバーで実行されるスケーラブルなDjangoアプリケーションをセットアップして構成しました。 この設定を複数のサーバーに複製して、高可用性アーキテクチャを作成できます。 さらに、このアプリとその構成は、 Docker または別のコンテナーランタイムを使用してコンテナー化でき、デプロイとスケーリングが容易になります。 これらのコンテナは、Kubernetesなどのコンテナクラスタにデプロイできます。 今後のチュートリアルシリーズでは、このDjangoをコンテナ化して最新化する方法を探ります polls アプリをKubernetesクラスターで実行できるようにします。

静的ファイルに加えて、DjangoMediaファイルをオブジェクトストレージにオフロードすることもできます。 これを行う方法については、AmazonS3を使用してDjangoサイトの静的ファイルとメディアファイルを保存するを参照してください。 静的ファイルを圧縮して、エンドユーザーへの配信をさらに最適化することも検討してください。 これを行うには、DjangoコンプレッサーのようなDjangoプラグインを使用できます。