web-dev-qa-db-ja.com

Django Gunicornを使用したDockerでの開発によるコード変更の自動リロード

Django開発用にDockerコンテナを使用しています。コンテナはNginxでGunicornを実行します。コードを変更して自動読み込みを行いたいのですが、それらを読み込むための唯一の方法はdocker-compose(docker-compose build)。 「ビルド」の問題は、すべてのpipインストールを再実行することです。

Gunicornを使用しています--reloadフラグ。明らかに、私が望むことをすることになっています。ここに私のDocker設定ファイルがあります:

## Dockerfile:
FROM python:3.4.3
RUN mkdir /code
WORKDIR /code
ADD . /code/
RUN pip install -r /code/requirements/docker.txt

## docker-compose.yml:
web:
  restart: always
  build: .
  expose:
    - "8000"
  links:
    - postgres:postgres
  volumes:
    - /usr/src/app/static
  env_file: .env
  command: /usr/local/bin/gunicorn myapp.wsgi:application -w 2 -b :8000 --reload

nginx:
  restart: always
  build: ./config/nginx
  ports:
    - "80:80"
  volumes:
    - /www/static
  volumes_from:
    - web
  links:
    - web:web

postgres:
  restart: always
  image: postgres:latest
  volumes:
    - /var/lib/postgresql
  ports:
    - "5432:5432"

他のDockerコマンド(docker-compose restartdocker-compose up)。ただし、コードは更新されません。

私は何が欠けていますか?

39
Dolan Antenucci

Kikicarbonellのおかげで、コード用のボリュームがあることを検討し、 Docker Compose推奨Django setup を見て、volumes: - .:/codeをdocker-compose.ymlのWebコンテナに追加すると、コードの変更が自動的に適用されます。

## docker-compose.yml:
web:
  restart: always
  build: .
  expose:
    - "8000"
  links:
    - postgres:postgres
  volumes:
    - /usr/src/app/static
    - .:/code
  env_file: .env
  command: /usr/local/bin/gunicorn myapp.wsgi:application -w 2 -b :8000 --reload

更新:GunicornとDjango= Dockerを使用した完全な例については、これをチェックアウトしてください Rackspaceのプロジェクト例 また、ドッキングマシンを使用して、Rackspace Cloudなどのリモートサーバーでセットアップを起動する方法も示します。

警告:現在、このメソッドは、コードがローカルにあり、ドッカーホストがリモート(たとえば、デジタルオーシャンやラックスペースなどのクラウドプロバイダー)の場合は機能しません)。ローカルファイルシステムがVMにマウントされていない場合、これは仮想マシンにも適用されます。別のボリュームドライバー(flockerなど)があり、このニーズに対処するためにmightがあるかもしれないことに注意してください。 今のところ、「修正」は、リモートドッカーホスト上のディレクトリまでファイルをrsync/scpすることです。そうして --reloadフラグは、scp/rsyncの後にgunicornを自動リロードします。 更新:ドッカーホストを削除するためにコードをプッシュする場合、ドッカーコンテナを再構築する方がはるかに簡単であることがわかります(例:docker-compose build web && docker-compose up -d)。ただし、srcフォルダーが大きい場合、rsyncアプローチよりも遅くなります。

34
Dolan Antenucci

別の問題があります-Dockerは構築する各レイヤーをキャッシュします。毎回pip installを再実行する必要はありません!

ADD . /code/
RUN pip install -r /code/requirements/docker.txt

これが問題です。DockerはすべてのADDステートメントをチェックして、ファイルが変更されたかどうかを確認し、ファイルのキャッシュと、変更があればそれ以降のステップを無効にします。これを行う正しい方法は...

ADD ./requirements/docker.txt /code/requirements/
RUN pip install -r /code/requirements/docker.txt
ADD ./code/

要件ファイルが変更された場合にのみ、pipインストール行が無効になります!

24
Paul Becotte

望ましい解決策が見つからなかったので、この興味深いハックを検討してください。ここに投稿することで、この「回避策」について同様の/良い/悪い経験がある人がいるかどうかを見たかったのです。

開発用にコードをローカルでリロードするには、exit()をすぐに呼び出すビューを作成しました。出口はクラッシュしますDjangoそして、コードの変更が可能な場所でリロードが発生します。再起動には数秒かかり、ブラウザのタブrequests.get呼び出し、または他の同様の呼び出し。リロードは自動ではありませんが、再起動などのDockerラグはスキップします。

出口が呼び出されると、PIDの増分が表示されます(ログを追跡する場合):

web    | [2019-07-15 18:29:52 +0000] [22] [INFO] Worker exiting (pid: 22)
web    | [2019-07-15 18:29:52 +0000] [24] [INFO] Booting worker with pid: 24

これが他の人に役立つこと、および/またはこのアプローチにフィードバックを得ることを願っています。

1
Marc