2017-04-17 7 views
0

私はAnsibleプレイブックを使って構築するDjango/Gunicorn/Nginxのウェブサイトを持っています。私は現在、私のプレイブックで、新しい機能を追加したり、バグを修正したり、Djangoコードをリロードしたりするたびに、実行する必要があるタスクにタグ付けをしています。私の目標は、プロダクションサーバーをダウンさせることなく、ステージングサーバーでそれらをテストするとすぐに、そのような変更をプロダクションにプッシュできるようにすることです。500サーバーエラーなしでDjangoのWebサイトをリロードしますか?

私のプレーブックは現在、プロダクションに変更をプッシュしたいときは、ウェブサイトのディレクトリ全体を削除し、Pip仮想環境を再構築して残った "cruft"がないようにします。問題は、Ansibleプレイブックを実行すると、Webサイトのディレクトリを削除する時点で、瞬時500サーバーエラーが発生することです。次に、Githubからコードをチェックアウトする次のタスクが実行されると、エラーが消えます。明らかに、コードベースをリロードするたびに、タスクが実行された瞬間にユーザーが私のウェブサイトにアクセスした場合、この500エラーも発生します。 Gunicornが起動してDjangoコードがメモリにロードされると、サービスを中断することなくコードを削除して再ロードし、Gunicornを再起動できると私は考えていました。これ以外の場合はStackover questionと思われます。しかし、私のテストではそうでないことが示されます。

クライアントブラウザがDjangoにリクエストを送信すると、Djangoはすべての.pycファイルをメモリにリロードしますか?それがこの問題の原因ですか?古いコードを削除するタスクを削除せずにDjangoコードをリロードすると、この瞬間的な停止を防ぐ方法はありますか?

は、ここに私のAnsible脚本からの抜粋です:

- name: configure web server 
    hosts: webservers 
    gather_facts: True 
    tasks: 
    # This task causes momentary 500 server error 
    - name: delete any existing project repo 
     file: > 
     path={{ repo_path }} 
     state=absent 
     tags: reload 

    - name: check out {{ repo_version }} of Github repo 
     git: > 
     repo={{ repo_url }} 
     version={{ repo_version }} 
     dest={{ repo_path }} 
     accept_hostkey=yes 
     register: checkout 
     until: checkout|success 
     retries: 5 
     delay: 10 
     become: true 
     become_user: "{{ me }}" 
     tags: reload 

    # ... more tasks 

    - name: install python packages into virtual environment 
     pip: > 
     requirements={{ repo_path }}/requirements/{{ server_tier }}.txt 
     state=present 
     virtualenv={{ venvs_path }}/{{ commit_hash }} 
     tags: reload 

    # ... more tasks 

    - name: reload gunicorn 
     command: pkill -HUP gunicorn 
    become: true 
    become_user: root 
    tags: reload 
+0

なぜリポジトリを削除しますか? Gitは失効したファイルの削除を処理する必要があります。残っているものは何ですか?古いpipパッケージ? –

+0

トップレベルのWebサイトのディレクトリにあるすべてのものを削除して、新しいコードベースから始めるのが最善であると私は信じていました。私はYouTubeで見つかったリンカーンループのトーク「Django Deployments Done Right」のアドバイスを忠実に守ろうとしていました。私はGitが新しいディレクトリをチェックアウトするときに存在しなかったすべてのファイルを私のディレクトリから削除するかもしれないと考えるのをやめました。しかし、それでも、なぜこの問題を起こすのだろうか?とにかくすべてが記憶にあるのではないか?なぜGunicornをリロードするまで、ウェブサイトはディスクを見ているのですか? – William

+0

ロードバランサでこれを処理します。 – browskie

答えて

0

ソリューション:は、あなたのDjangoのルートディレクトリSYMBリンクしてください。

解決策を詳細に説明しましょう。あなたのコードルートがトラフィックを提供しているコードの実際のバージョンへのシンボリックリンクであることを確認してください。デプロイメントの間、あなたの不可能なスクリプトは本質的に新しいvirtualenvを作成し、要件をインストールします。名前に現在のタイムスタンプがあるはずの新しいディレクトリにコードをプルします。そして、トラフィックを処理できるように準備する必要があれば何でもしてください。そして最後のステップでは、djangoのルートディレクトリのリンクを新しい場所に向けることになります。

/home/ubuntu/project/current -> /home/ubuntu/project/releases/145678/ 
/home/ubuntu/project/releases/123456/ 
/home/ubuntu/project/releases/134567/ 
/home/ubuntu/project/releases/145678/ 

上記のディレクトリ構造では、現在のリリースの1つを指すことができます。新しいデプロイメントごとに、新しいリリースを作成してから、現在のリリースディレクトリに新しいリリースをポイントすることができます。

その後、新しいコードベースの設定を更新するためにgunicornを再起動することができます。

非常に古いリリースをマシンから削除するには、cronジョブを使用できます。

さらに詳しい説明が必要な場合は教えてください。

関連する問題