Gunicorn Autoreload bei Quellenwechsel


113

Schließlich habe ich meine Entwicklungsumgebung von runserver auf gunicorn / nginx migriert.

Es wäre praktisch, die Autoreload-Funktion von runserver auf gunicorn zu replizieren, damit der Server automatisch neu gestartet wird, wenn sich die Quelle ändert. Ansonsten muss ich den Server manuell mit neu startenkill -HUP .

Wie kann man den manuellen Neustart vermeiden?


Errata: In meiner Umgebung wird Gunicorn von Supervisord verwaltet / überwacht, daher würde ich kill -HUPdie Prozess-PID nicht wirklich verwenden, sondern stattdessen Supervisorctl verwenden. Denken Sie jedoch nicht, dass sich dies sehr ändert.
Paolo

Antworten:


230

Dies ist zwar eine alte Frage, nur aus Gründen der Konsistenz - da Version 19.0 Gunicorn --reloadOption hat. Es wurden also keine Tools von Drittanbietern mehr benötigt.


5
einverstanden. Die anderen Antworten mögen funktionieren, aber dies ist bei weitem die einfachste und keine Problemumgehung. Genau das wollte das OP.
J-Bob

1
Ich glaube nicht, dass es eine --reload-Option gibt, die in Gunicorn eingebaut ist. Wo hast du das gefunden? In ihren Dokumenten heißt es, die Konfiguration neu zu laden, ein HUP zu senden ( killall -HUP procnamefunktioniert einwandfrei), damit neue Worker gestartet und alte ordnungsgemäß heruntergefahren werden.
leise

3
Danke @Guandalino, ich muss es verpasst haben. Interessant ist jedoch, dass sie sagen "Diese Einstellung ist für die Entwicklung vorgesehen." Dies würde natürlich in einigen Fällen für die Produktion funktionieren, könnte aber auch für viele andere problematisch sein. Ja, ich habe unten gesehen, dass Sie anscheinend nicht an Produktion / Bereitstellung interessiert sind.
leise

Wie geht das auf einfache Weise für Produktionsserver?
Juan Isaza

@juanIsaza Sie sollten solche Funktionen niemals in der Produktion verwenden. Wenn Sie glauben, dass Sie es brauchen, müssen Sie Ihren Ansatz für die Entwicklung oder Bereitstellung überdenken.
Dmitry Ziolkovskiy

20

Eine Möglichkeit wäre, die --max-Anforderungen zu verwenden, um jeden erzeugten Prozess darauf zu beschränken, nur eine Anforderung zu bedienen, indem --max-requests 1zu den Startoptionen hinzugefügt wird . Bei jedem neu erzeugten Prozess sollten sich Ihre Codeänderungen ändern, und in einer Entwicklungsumgebung sollte die zusätzliche Startzeit pro Anforderung vernachlässigbar sein.


1
Schöner, eleganter Trick für Entwickler. Kann nicht für Produkte verwendet werden ... aber Sie möchten möglicherweise trotzdem kein automatisches Laden für Produkte, es sei denn, Sie führen eine "kontinuierliche Bereitstellung" durch. Wenn Sie dies tun, ist Bryan Helmigs Ansatz besser, obwohl er das pipfähige Paket erfordert watchdog.
Kochfelder

2
Das Starten eines neuen Workers dauert ca. 3 Sekunden, was für mich zu langsam ist. (Mitte 2009 MBP)
Blaise

11

Bryan Helmig hat sich das ausgedacht und ich habe es so geändert, dass es verwendet wird, run_gunicornanstatt es gunicorndirekt zu starten , damit diese 3 Befehle einfach ausgeschnitten und in eine Shell in Ihrem Django-Projektstammordner eingefügt werden können (wobei Ihre virtuelle Umgebung aktiviert ist):

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

Ich habe es gerade für mich auf Fedora 15 mit Django 1.5.4, Gunicorn 18.0, Watchdog 0.6, Bash 4.2 verwendet.
Kochfelder

Vergessen Sie nicht 127.0.0.1:80, bei Bedarf Ihre IP-Adresse oder Ihren FQDN und Ihren Port anstelle von zu verwenden .
Kochfelder

1
@ Guandalino, hast du Glück? Es funktioniert jetzt seit ein paar Wochen gut für mich. Nur wenn ich manuell neu starten müssen , ist , wenn ich ändern settings.py, models.py(Migration erforderlich) oder den Quellcode einer externen App nicht in meinem watchmedoMuster.
Kochfelder

Danke für die Erinnerung. Aber ich möchte nicht über den Erfolg anderer abstimmen. Warum diese (unnötige) Eile? Verstoße ich gegen eine StackOverflow-Regel? Wenn ja, lassen Sie mich bitte wissen, wie ich Abhilfe schaffen kann.
Paolo

1
Keine Sorge. Es verstößt definitiv nicht gegen eine SO-Regel, sondern ist nur rücksichtsvoll / besorgt / nachdenklich, wenn es darum geht, hilfreiche Antworten zu bewerten. Es sieht so aus, als hätten Dave und ich uns die Zeit genommen, Ihnen zu helfen (viele Monate). Daher ist meine Dringlichkeit, Sie dazu zu bringen, unsere Lösungen zu überprüfen, unverhältnismäßig - ich bin übermäßig gespannt, ob es versteckte Fehler in meiner Art gibt Ich habe meinen Server konfiguriert und sollte zu Daves Ansatz wechseln . Schöne Ferien!
Kochfelder

5

Ich verwende Git Push, um es für die Produktion bereitzustellen, und richte Git Hooks ein, um ein Skript auszuführen. Der Vorteil dieses Ansatzes besteht darin, dass Sie gleichzeitig Ihre Migration und Paketinstallation durchführen können. 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

Dann erstellen Sie ein Skript /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

chmod u+x post-receiveStellen Sie sicher , und fügen Sie Benutzer zu sudoers hinzu. Lassen Sie es sudo supervisorctlohne Passwort laufen . https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

Von meinem lokalen / Entwicklungsserver aus habe ich eingerichtet, git remotedass ich auf den Produktionsserver pushen kann

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

Als Bonus sehen Sie alle Eingabeaufforderungen, während das Skript ausgeführt wird. Sie werden also sehen, ob es ein Problem mit der Migration / Paketinstallation / dem Neustart des Supervisors gibt.


beachte, dass #!/bin/bashdu shebang wie oben erwähnt verwendest, anstatt #!/bin/shwas Git post-receiveBeispiel hatte!
Curtisp
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.