gunicorn autoreload pada perubahan sumber

113

Akhirnya saya memigrasikan env pengembangan saya dari runserver ke gunicorn / nginx.

Akan lebih mudah untuk mereplikasi fitur autoreload runserver ke gunicorn, sehingga server secara otomatis memulai ulang ketika sumber berubah. Jika tidak, saya harus me-restart server secara manual dengan kill -HUP.

Adakah cara untuk menghindari restart manual?

Paolo
sumber
Kesalahan: di env gunicorn saya dikelola / dipantau oleh supervisord, jadi saya tidak akan benar kill -HUP- benar memproses PID, tetapi gunakan supervisorctl sebagai gantinya. Namun, jangan berpikir ini banyak berubah.
Paolo
3
github.com/benoitc/gunicorn/issues/154 memiliki beberapa solusi
KZ

Jawaban:

232

Meskipun ini pertanyaan lama, hanya untuk konsistensi - karena versi 19.0 gunicorn memiliki --reloadopsi. Jadi tidak ada alat pihak ketiga yang membutuhkan lebih banyak.

Dmitry Ziolkovskiy
sumber
5
sepakat. Jawaban lain mungkin berhasil, tetapi sejauh ini yang paling sederhana dan bukan solusi. Itulah yang diinginkan OP.
J-bob
1
Saya tidak percaya ada opsi --reload yang ada di dalam gunicorn. Di mana kamu menemukan ini? Dokumen mereka mengatakan untuk memuat ulang konfigurasi, kirim HUP ( killall -HUP procnameakan berfungsi dengan baik) agar pekerja baru dimulai dan yang lama ditutup dengan baik.
sofly
3
Terima kasih @Guandalino, saya pasti melewatkannya. Menarik untuk dicatat, bahwa mereka mengatakan "Pengaturan ini ditujukan untuk pengembangan." Ini jelas akan berhasil untuk produksi dalam beberapa kasus, tetapi juga dapat menjadi masalah bagi banyak kasus lainnya. Ya, saya melihat di bawah bahwa Anda tampaknya tidak tertarik pada produksi / penerapan.
sofly
Bagaimana melakukannya dengan cara yang mudah untuk server produksi?
juan Isaza
@juanIsaza Anda tidak boleh menggunakan fungsi seperti itu pada produksi. Jika Anda merasa membutuhkannya - Anda perlu memikirkan kembali pendekatan Anda untuk pengembangan atau penerapan.
Dmitry Ziolkovskiy
20

Salah satu opsinya adalah menggunakan --max-request untuk membatasi setiap proses yang muncul untuk melayani hanya satu permintaan dengan menambahkan --max-requests 1ke opsi startup. Setiap proses yang baru muncul akan melihat kode Anda berubah dan dalam lingkungan pengembangan waktu startup tambahan per permintaan harus dapat diabaikan.

Dave Forgac
sumber
1
Trik yang bagus dan elegan untuk dev env. Tidak dapat digunakan di prod ... tetapi Anda mungkin tidak ingin muat otomatis di prod, kecuali Anda melakukan "penerapan berkelanjutan". Jika Anda melakukannya, pendekatan Bryan Helmig lebih baik meskipun membutuhkan pippaket yang mampu watchdog,.
kompor
2
Diperlukan ~ 3 detik untuk mem-boot pekerja baru, yang terlalu lambat bagi saya. (pertengahan 2009 MBP)
Blaise
11

Bryan Helmig datang dengan ini dan saya memodifikasinya untuk digunakan run_gunicorndaripada meluncurkan gunicornsecara langsung, untuk memungkinkan untuk hanya memotong dan menempelkan 3 perintah ini ke dalam shell di folder root proyek django Anda (dengan virtualenv Anda diaktifkan):

pip install watchdog -U
watchmedo shell-command --patterns="*.py;*.html;*.css;*.js" --recursive --command='echo "${watch_src_path}" && kill -HUP `cat gunicorn.pid`' . &
python manage.py run_gunicorn 127.0.0.1:80 --pid=gunicorn.pid
kompor
sumber
Baru saja digunakan untuk diri saya sendiri di fedora 15 dengan Django 1.5.4, gunicorn 18.0, pengawas 0.6, bash 4.2.
kompor
Jangan lupa untuk menempatkan IP atau FQDN dan port Anda 127.0.0.1:80, jika perlu.
kompor
1
@Guandalino, apakah beruntung? Sudah bekerja dengan baik untuk saya selama beberapa minggu sekarang. Hanya waktu yang saya perlukan untuk memulai ulang secara manual adalah saat saya berubah settings.py, models.py(diperlukan migrasi), atau kode sumber dari beberapa aplikasi eksternal tidak ada dalam watchmedopola saya .
kompor
Terima kasih atas pengingatnya. Tetapi saya tidak ingin memberikan suara saya pada kesuksesan orang lain. Mengapa ini (tidak perlu) terburu-buru? Apakah saya melanggar beberapa aturan StackOverflow? Jika demikian, beri tahu saya cara memulihkannya.
Paolo
1
Jangan khawatir. Jelas tidak melanggar aturan SO, itu hanya perhatian / perhatian / bijaksana untuk menempatkan upaya / prioritas dalam mengevaluasi jawaban yang bermanfaat. Sepertinya Dave dan saya mengambil waktu manis kami untuk membantu Anda (berbulan-bulan), jadi perasaan mendesak saya untuk meminta Anda memverifikasi solusi kami tidak proporsional - saya terlalu ingin tahu apakah ada kekurangan tersembunyi dalam cara saya telah mengkonfigurasi server saya dan jika saya harus beralih ke pendekatan Dave . Selamat berlibur!
kompor
5

Saya menggunakan git push untuk menerapkan ke produksi dan menyiapkan git hook untuk menjalankan skrip. Keuntungan dari pendekatan ini adalah Anda juga dapat melakukan migrasi dan penginstalan paket secara bersamaan. https://mikeeverhart.net/2013/01/using-git-to-deploy-code/

mkdir -p /home/git/project_name.git
cd /home/git/project_name.git
git init --bare

Kemudian buat skrip /home/git/project_name.git/hooks/post-receive.

#!/bin/bash
GIT_WORK_TREE=/path/to/project git checkout -f
source /path/to/virtualenv/activate
pip install -r /path/to/project/requirements.txt
python /path/to/project/manage.py migrate
sudo supervisorctl restart project_name

Pastikan untuk chmod u+x post-receive, dan tambahkan pengguna ke sudoers. Biarkan berjalan sudo supervisorctltanpa kata sandi. https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

Dari server lokal / pengembangan saya, saya menyiapkan git remoteyang memungkinkan saya untuk mendorong ke server produksi

git remote add production ssh://user_name@production-server/home/git/project_name.git

# initial push
git push production +master:refs/heads/master

# subsequent push
git push production master

Sebagai bonus, Anda akan melihat semua petunjuk saat skrip sedang berjalan. Jadi Anda akan melihat apakah ada masalah dengan migrasi / instalasi paket / pengawas restart.

pengguna3628119
sumber
perhatikan untuk menggunakan shebang #!/bin/bashseperti yang disebutkan di atas alih-alih #!/bin/shyang merupakan post-receivecontoh Git !
memberikan