gunicornとnginxを使用したDjangoのデプロイ


81

これは幅広い質問ですが、私は標準的な答えを得たいと思います。私が使用してサイトに展開しようとしているgunicornnginxのDjangoに。たくさんのチュートリアルを読んだ後、私は成功しましたが、私が従った手順が問題なくサイトを運営するのに十分であるか、あるいはそれを行うためのより良い方法があるかどうかはわかりません。その不確実性は迷惑です。

だから私は初心者のために非常に詳細でよく説明された答えを探しています。私が知っていることと私が知らないことをあまり説明したくありません。なぜなら、これは答えを少し歪める可能性があり、他の人々はあなたの答えからより少ない程度で利益を得る可能性があるからです。しかし、私が言及してもらいたいいくつかのことは次のとおりです。

  • どの「セットアップ」が最も効果的だと思いますか?virtualenvを使用して、Djangoプロジェクトをこの環境内に移動しましたが、仮想環境用のフォルダーとプロジェクト用のフォルダーがある別のセットアップを見ました。

  • 複数のサイトを単一のサーバーでホストできるように設定するにはどうすればよいですか?

  • なぜ一部の人が使用gunicorn_django -b 0.0.0.0:8000を提案し、他の人が提案するのgunicorn_django -b 127.0.0.1:8000ですか?後者をAmazonEC2インスタンスでテストしましたが、前者が問題なく機能している間は機能しませんでした。

  • nginxの設定ファイルの背後にあるロジックは何ですか?大幅に異なる構成ファイルを使用したチュートリアルが非常に多いため、どちらが優れているか混乱しています。たとえば、使用する人もいれば、を使用する人alias /path/to/static/folderもいroot /path/to/static/folderます。たぶん、あなたはあなたの好みの設定ファイルを共有することができます。

  • なぜ我々は間のシンボリックリンクを作成しますsite-availablesites-enabledでは/etc/nginx

  • いくつかのベストプラクティスはいつも歓迎されています:-)

ありがとう


これらのnginxとgunicorn / uwsgiに関する例をgitに投稿してください。私のような新しい学習者にとってより役立つでしょう。
シヴァ

@Shiva実際、miki725の回答には、構成ファイルの非常に完全なサンプルが含まれています。nginxで何が起こっているかについて非常に徹底的に紹介したい場合は、< ahref=" amazon.com/Nginx-HTTP-Server-Cl%C3%A9ment-Nedelcu/dp/…book < /a >をお勧めします。 gunicornの統合は非常に簡単です。概要は< ahref = " docs.djangoproject.com/en/dev/howto/deployment/wsgi/gunicorn/…>–
Robert Smith

回答:


106

どの「セットアップ」が最も効果的だと思いますか?virtualenvを使用して、djangoプロジェクトをこの環境内に移動しましたが、仮想環境用のフォルダーとプロジェクト用のフォルダーがある別のセットアップを見ました。

virtualenvは、Python環境を分離する方法です。そのため、展開時に大きな役割を果たすことはありませんが、開発およびテスト中は、強く推奨されていない場合は要件です。

virtualenvから得られる価値は、アプリケーションに正しいバージョンのライブラリがインストールされていることを確認できることです。したがって、仮想環境自体をどこに貼り付けるかは問題ではありません。ソースコードのバージョン管理システムの一部として含めないように注意してください。

ファイルシステムのレイアウトは重要ではありません。ディレクトリレイアウトの長所を称賛する記事がたくさんあり、出発点としてクローンを作成できるスケルトンプロジェクトもあります。これは難しい要件というよりも個人的な好みだと思います。確かにそれは素晴らしいことです。ただし、理由わからない限り、展開プロセスに何の価値も追加されません。シナリオに意味がない限り、一部のブログで推奨されているため、そうしないでください。たとえばsetup.py、展開ワークフローの一部であるプライベートPyPiサーバーがない場合は、ファイルを作成する必要はありません。

複数のサイトを単一のサーバーでホストできるように設定するにはどうすればよいですか?

複数のサイト設定を行うために必要なことが2つあります。

  1. SSLを使用している場合は、ポート80またはポート443、あるいはその両方でパブリックIPをリッスンしているサーバー。
  2. 実際のdjangoソースコードを実行している一連の「プロセス」。

非常に高速なプロキシであり、Apacheのような包括的なサーバーのオーバーヘッドがないため、人々は#1にnginxを使用します。慣れている場合は、Apacheを自由に使用できます。「複数のサイトの場合、nginxを使用する」という要件はありません。そのポートでリッスンし、実際のdjangoコードを実行しているプロセスにリダイレクト(プロキシ)する方法を知っているサービスが必要です。

#2の場合、これらのプロセスを開始する方法はいくつかあります。gevent / uwsgiが最も人気のあるものです。ここで覚えておくべき唯一のことは、本番環境でrunserverを使用しないことです。

これらは絶対的な最小要件です。通常、人々は、実行中のすべての「djangoサーバー」(#2)を制御するために、ある種のプロセスマネージャーを追加します。ここであなたは見upstartsupervisor言及するでしょう。(スタートアップとは異なり)システム全体を引き継ぐ必要がないので、私はスーパーバイザーを好みます。ただし、繰り返しになりますが、これは難しい要件ではありません。あなたは完璧にたくさんを実行することができますscreenセッションをそれらを切り離すます。欠点は、サーバーが再起動した場合、画面セッションを再起動する必要があることです。

個人的に私はお勧めします:

  1. #1のNginx
  2. uwsgiとgunicornの間で選択してください-私はuwsgiを使用します。
  3. スーパーバイザーバックエンドプロセスを管理するための。
  4. ホストしている各アプリケーションの個々のシステムアカウント(ユーザー)。

#4をお勧めする理由は、権限を分離するためです。繰り返しますが、要件ではありません。

gunicorn_django -b 0.0.0.0:8000の使用を提案する人もいれば、gunicorn_django -b 127.0.0.1:8000を提案する人もいるのはなぜですか?後者をAmazonEC2インスタンスでテストしましたが、前者が問題なく機能している間は機能しませんでした。

0.0.0.0「すべてのIPアドレス」を意味します-そのメタアドレス(つまり、プレースホルダーアドレス)。127.0.0.1は常にローカルマシンを指す予約済みアドレスです。そのため、「localhost」と呼ばれています。同じシステムで実行されているプロセスにのみ到達可能です。

通常、フロントエンドサーバー(上記のリストの#1)がパブリックIPアドレスをリッスンしています。サーバーを1つのIPアドレスに明示的にバインドする必要があります

ただし、何らかの理由でDHCPを使用している場合、またはIPアドレスが何であるかがわからない場合(たとえば、新しくプロビジョニングされたシステム)、nginx / apache /その他のプロセスにバインドするように指示できます0.0.0.0これは一時的な一時的な対策である必要があります。

本番サーバーの場合、静的IPがあります。動的IP(DHCP)を使用している場合は、そのままにしておくことができます0.0.0.0。ただし、実稼働マシンにDHCPを使用することは非常にまれです。

gunicorn / uwsgiをこのアドレスにバインドすることは、本番環境では推奨さません。バックエンドプロセス(gunicorn / uwsgi)を0.0.0.0にバインドすると、フロントエンドプロキシ(nginx / apache / etc)をバイパスして、「直接」アクセスできるようになる可能性があります。特にフロントエンドサーバー(nginx)とバックエンドプロセス(django / uwsgi / gevent)が同じマシンで実行されている場合、誰かがhttp://your.public.ip.address:9000/アプリケーションを直接リクエストしてアクセスする可能性があります

ただし、フロントエンドプロキシサーバーを実行する手間をかけたくない場合は、自由に実行できます。

nginxの設定ファイルの背後にあるロジックは何ですか?大幅に異なる構成ファイルを使用したチュートリアルが非常に多いため、どちらが優れているか混乱しています。たとえば、「エイリアス/ path / to / static / folder」を使用する人もいれば、「root / path / to / static / folder」を使用する人もいます。たぶん、あなたはあなたの好みの設定ファイルを共有することができます。

nginxについて最初に知っておくべきことは、nginxはApacheやIISのようなWebサーバーではないということです。プロキシです。したがって、「アップストリーム」/「ダウンストリーム」などのさまざまな用語と、複数の「サーバー」が定義されていることがわかります。少し時間を取って、最初にnginxのマニュアルを読んでください。

nginxを設定する方法はたくさんあります。しかし、ここにalias対に関するあなたの質問に対する1つの答えがありますrootrootnginxのドキュメントルート(「ホームディレクトリ」)をバインドする明示的なディレクティブです。これは、次のようなパスなしでリクエストを送信したときに表示されるディレクトリです。http://www.example.com/

alias「名前をディレクトリにマップする」という意味です。エイリアスディレクトリ、ドキュメントルートのサブディレクトリではない場合があります

/ etc / nginxで、site-availableとsites-enabledの間にシンボリックリンクを作成するのはなぜですか?

これはdebian(およびubuntuのようなdebianのようなシステム)に固有のものです。 sites-availableシステム上のすべての仮想ホスト/サイトの構成ファイルを一覧表示します。からのシンボリックリンクはsites-enabledsites-availableそのサイトまたは仮想ホストを「アクティブ化」します。これは、構成ファイルを分離し、ホストを簡単に有効/無効にする方法です。


1
素晴らしい答えです!多くの質問が明らかになりました。サーバーをIPアドレスに明示的にバインドし、バインドするgunicorn / uwsgiを0.0.0.0にバインドする必要があるという意味について、もう少し詳しく説明(または例を追加)できますか?残念ながら、それが私がやっていたことだと思います。ありがとう!
ロバートスミス

7
一般的なコンピューターには、少なくとも2つのIPアドレスがあります127.0.0.1。1つはネットワークによってコンピューターに割り当てられます。これは最小限です-マシンには複数のインターフェースと複数のIPアドレスがある場合があります。Webサーバー(または実際には任意のプロセス)を構成する必要があります。1つのIPアドレスでリッスンする-これは私が明示的に意味することです。にバインドすると0.0.0.0マシンに割り当てられる可能性のある新しいアドレスを含むすべてのIPアドレスリッスンするようにプログラムに指示します。これはさまざまな理由で適切な方法ではありません(セキュリティもその1つです)。
Burhan Khalid

とった。私はすでにGunicornを適切に構成しました。どうもありがとうございました!
ロバートスミス

nginxは静的コンテンツを提供できます。
Marcin

サーバーがどのファイルでサーバーアドレスを構成したかをサーバーがどのように知るか/etc/nginx/sites-enabled
Shiva

11

私はデプロイメントの第一人者ではありませんが、djangoをgeventでデプロイするための私のプラクティスのいくつかを共有します(ただし、gunicornに似ているはずです)。

virtualenv私が入らない理由で素晴らしいです。ただし、virtualenv-wrapperdocs)は、さまざまなvirtualenvを簡単に切り替えることができるため、特に多くのプロジェクトで作業している場合に非常に便利であることがわかりました。これは実際にはデプロイメント環境には当てはまりませんが、SSHを使用してサーバーでトラブルシューティングを行う必要がある場合、これは非常に便利であることがわかりました。これを使用するもう1つの利点は、virtualenvディレクトリを管理するため、手作業が少なくて済むことです。Virtualenvは使い捨てであるため、バージョンの問題やその他のインストールの問題が発生した場合は、envをダンプして新しいものを作成できます。そのため、virtualenv内にプロジェクトコードを含めないことがベストプラクティスです。別々に保管する必要があります。

複数のサイトを設定することに関してvirtualenvは、ほとんどの答えです。プロジェクトごとに個別のvirutalenvが必要です。それだけで多くの問題を解決できます。次に、デプロイすると、異なるPythonプロセスが異なるサイトを実行し、デプロイメント間で発生する可能性のある競合を回避します。同じサーバー上の複数のサイトを管理するのに特に役立つと思ったツールの1つは、supervisorドキュメント)。さまざまなDjangoインスタンスを開始、停止、再起動するための簡単なインターフェイスを提供します。また、プロセスが失敗したとき、またはコンピューターが起動したときに、プロセスを自動再起動することもできます。したがって、たとえば、何らかの例外が発生し、それをキャッチするものがない場合、Webサイト全体がダウンする可能性があります。スーパーバイザーはそれをキャッチし、Djangoインスタンスを自動的に再起動します。以下は、サンプルのスーパーバイザープログラム(単一プロセス)の構成です。

[program:foo]
command=/path/toviertualenv/bin/python deploy.py
directory=/path/where/deploy.py/is/located/
autostart=true
autorestart=true
redirect_stderr=True
user=www

Nginxの場合、最初は圧倒される可能性があることを私は知っています。Nginxの本はとても便利だと思いました。すべての主要なnginxディレクティブについて説明しています。

私のnginxインストールでは、ベストプラクティスはnginx.confファイル内のコア構成のみをセットアップすることであり、sitesホストする各サイトのnginx構成を保持する個別のフォルダーがあります。次に、そのフォルダーのすべてのファイルをコア構成ファイルに含めます。ディレクティブを使用しinclude sites/+*.conf;ます。このように+sitesフォルダ内の記号で始まるファイルのみが含まれます。そうすれば、ファイル名だけで、どの構成ファイルをロードするかを制御できます。したがって、特定のサイトを無効にしたい場合は、構成ファイルの名前を変更してnginxを再起動するだけです。質問の「/ etc / nginxでサイトが利用可能とサイトが有効になる間のシンボリックリンク」が何を意味するのかよくわかりません。これらはApacheの名前付きフォルダーですが、includeディレクティブと同様のタスクを実行します。

用としてrootaliasディレクティブ、彼らはかなり彼らのルートを計算する場合を除き、同じです。でalias、で何でもlocationドロップしましたが、ルートではそうではありません。次のnginx構成があるイメージ:

location /static {
    alias /some/path/;
}
location /static2 {
    root /some/other/path/;
}

ユーザーがこれらのURLにアクセスすると、nginxはシステムの次の場所でファイルを検索しようとします。

/static/hello/world.pdf => /some/path/hello/world.pdf
/static2/hello/world.pdf => /some/other/path/static2/hello/world.pdf

これはnginxサイトの簡単な設定です:

server {
    server_name .foodomain.com;
    listen 80;

    access_log logs/foodomain.log;

    gzip                on;
    gzip_http_version   1.0;
    gzip_comp_level     2;
    gzip_proxied        any;
    gzip_min_length     1100;
    gzip_buffers        16 8k;
    gzip_types          text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    # Some version of IE 6 don't handle compression well on some mime-types, so just disable for them
    gzip_disable "MSIE [1-6].(?!.*SV1)";

    # Set a vary header so downstream proxies don't send cached gzipped content to IE6
    gzip_vary on;

    location / {
        proxy_read_timeout      30s;
        proxy_pass              http://localhost:8000;
        proxy_set_header        Host                 $host;
        proxy_set_header        User-Agent           $http_user_agent;
        proxy_set_header        X-Real-IP            $remote_addr;
    }

    location /media {
        alias   /path/to/media/;
        expires 1y;
    }

    location /static {
        autoindex on;
        expires   1y;
        alias     /path/to/static/;
    }

     location /favicon.ico {
        alias /path/to/favicon.ico;
    }
}

うまくいけば、これはあなたに少し役立つでしょう。


実際、あなたの答えは大いに役立ちます!スーパーバイザーは素晴らしく聞こえます、そしてそれはブロガーの間でコンセンサスがあるように思われる数少ないものの1つです。仮想環境とそのラッパーに関する優れたアドバイス。virtualenv-wrapperをミックスに追加したくなりましたが、この質問の複雑さを不必要に増やしたくありませんでした。サイト利用可能およびサイト対応に関しては、nginxにはそれらのディレクトリが含まれています。nginxの設定ファイルはどこに作成しますか?Djangoプロジェクトの内部ですか?
ロバートスミス

私は個人的にnginxconfigフォルダーにそれらを持っています。私の場合は/usr/local/nginx/config/sitesです。しかし、それが正しい方法なのか、それともより良い方法なのかはわかりません。私がそれらをそこに保持する理由は、それを移動した場合、手動でincludeディレクティブを含めるか、シンボリックリンクを作成することによって、どういうわけかそれをnginxに含める必要があるためです。どちらの場合も、それは手作業なので、メインの設定場所に置いておきます。
miki725 2012年

私はあなたが推薦した本を読んでいます:-)それは素晴らしいです、そしてあなたが覚えているかもしれないように、/ sites/*。confはそれをするための1つの提案された方法です。とにかく、答えてくれてありがとう。
ロバートスミス

どういたしまして。私があまり役に立たなかった本に関する1つのセクションは、nginxでDjangoを使用する方法です。Bookは、プロキシパスを使用するほど適切ではないfastcgiを使用することを推奨しています。あなたは第6章をスキップすることができますので、
miki725

その本を読み終えたところです。それは素晴らしい。hoy fastcgiの動作を知りたかったので、実際に第6章を読みましたが、その通りです...あまり役に立ちませんでした。ありがとう!
ロバートスミス

2

さて、あなたがあなたの質問で尋ねたベストプラクティスに関する限り、私は文字通り、私にとって驚異的に機能したツールを共有せずにはいられません!私自身、いくつかのサイトのgunicorn、nginx、supervisorDのいくつかの設定ファイルで混乱していました!しかし、アプリやサイトに変更を加えてすぐにデプロイできるように、プロセス全体を何らかの方法で自動化することを切望していました。その名前はdjango-fagungisです。DjangoDeploymentの自動化に関する私の経験の詳細はここにあります。fabfile.pyを一度構成しました(django-fagungisはファブリックを使用してプロセス全体を自動化し、リモートサーバーでvirtualenvを作成します。これは非常に便利です単一のサーバーでホストされている複数のサイトの依存関係を管理します。nginx、gunicorn、supervisorDを使用してDjangoプロジェクト/サイトのデプロイを処理します)そしてdjango-fagungisはbitbucket(サブバージョンに使用)から最新のプロジェクトを複製し、リモートサーバーにデプロイします。シェルで3つのコマンドを入力するだけです私のローカルマシンのそれとそれ!私にとって、これはDjangoのデプロイに最適で手間のかからない方法であることがわかりました。


ありがとう!見ていきます。
ロバートスミス

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.