gunicorn chargement automatique lors du changement de source


113

Enfin, j'ai migré mon environnement de développement de runserver vers gunicorn / nginx.

Il serait pratique de répliquer la fonction de chargement automatique de runserver sur gunicorn, de sorte que le serveur redémarre automatiquement lorsque la source change. Sinon, je dois redémarrer le serveur manuellement avec kill -HUP.

Un moyen d'éviter le redémarrage manuel?


Errata: dans mon env, gunicorn est géré / surveillé par supervisord, donc je ne voudrais pas vraiment kill -HUPle processus PID, mais utiliser supervisorctl à la place. Mais ne pensez pas que cela change beaucoup.
Paolo

Réponses:


232

Bien que ce soit une vieille question, juste pour la cohérence - depuis la version 19.0, gunicorn a l' --reloadoption. Aucun outil tiers n'a donc besoin de plus.


5
D'accord. Les autres réponses peuvent fonctionner, mais c'est de loin la plus simple et ce n'est pas une solution de contournement. C'est exactement ce que voulait l'OP.
J-bob

1
Je ne crois pas qu'il existe une option --reload intégrée à gunicorn. Où as tu trouvé ça? Leurs documents disent de recharger la configuration, d'envoyer un HUP ( killall -HUP procnamefonctionnera bien) pour que les nouveaux travailleurs démarrent et les anciens arrêtent gracieusement.
doucement le

3
Merci @Guandalino, j'ai dû le manquer. Il est intéressant de noter cependant qu'ils disent "Ce paramètre est destiné au développement". Cela fonctionnerait évidemment pour la production dans certains cas, mais pourrait également être problématique pour beaucoup d'autres. Oui, j'ai vu ci-dessous que vous n'êtes apparemment pas intéressé par la production / le déploiement.
doucement le

Comment le faire de manière simple pour les serveurs de production?
Juan Isaza

@juanIsaza, vous ne devez jamais utiliser une telle fonctionnalité en production. Si vous pensez que vous en avez besoin, vous devez repenser votre approche de développement ou de déploiement.
Dmitry Ziolkovskiy

20

Une option serait d'utiliser les --max-requests pour limiter chaque processus engendré à ne servir qu'une seule requête en ajoutant --max-requests 1aux options de démarrage. Chaque processus nouvellement créé devrait voir votre code changer et dans un environnement de développement, le temps de démarrage supplémentaire par demande devrait être négligeable.


1
Belle astuce élégante pour dev env. Ne peut pas être utilisé sur prod ... mais il se peut que vous ne souhaitiez pas le rechargement automatique sur prod de toute façon, sauf si vous faites un "déploiement continu". Si vous le faites, Bryan Helmig approche est meilleure , même si elle nécessite le pippaquet en mesure, watchdog.
plaques de cuisson

2
Cela prendra ~ 3 secondes pour démarrer un nouveau worker, ce qui est trop lent pour moi. (mi-2009 MBP)
Blaise

11

Bryan Helmig a proposé cela et je l'ai modifié pour l'utiliser run_gunicornau lieu de le lancer gunicorndirectement, pour permettre de simplement couper et coller ces 3 commandes dans un shell dans le dossier racine de votre projet django (avec votre virtualenv activé):

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

Je l'ai juste utilisé pour moi-même sur fedora 15 avec Django 1.5.4, gunicorn 18.0, watchdog 0.6, bash 4.2.
plaques de cuisson du

N'oubliez pas de mettre votre adresse IP ou FQDN et votre port à la place de 127.0.0.1:80, si nécessaire.
plaques de cuisson du

1
@Guandalino, une chance? Cela fonctionne bien pour moi depuis quelques semaines maintenant. Seul le temps que je dois redémarrer manuellement est quand je change settings.py, models.py(migration nécessaire), ou le code source d'une application externe pas dans mes watchmedohabitudes.
plaques de cuisson

Merci pour le rappel. Mais je ne veux pas voter sur le succès des autres. Pourquoi cette hâte (inutile)? Est-ce que je viole une règle StackOverflow? Si tel est le cas, veuillez me faire savoir comment y remédier.
Paolo

1
Pas de soucis. Ne violant certainement pas une règle SO, il est juste attentif / attentionné / réfléchi de mettre l'effort / la priorité dans l'évaluation des réponses utiles. On dirait que Dave et moi avons pris notre temps pour vous aider (plusieurs mois), donc mon sentiment d'urgence de vous amener à vérifier nos solutions est disproportionné - j'ai trop hâte de savoir s'il y a des défauts cachés dans la façon dont je 'ai configuré mon serveur et si je devrais passer à l'approche de Dave . Joyeuses fêtes!
plaques de cuisson

5

J'utilise git push pour déployer en production et configurer des hooks git pour exécuter un script. L'avantage de cette approche est que vous pouvez également effectuer la migration et l'installation du package en même temps. 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

Créez ensuite un script /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

Assurez-vous de le faire chmod u+x post-receiveet ajoutez un utilisateur aux sudoers. Autorisez-le à fonctionner sudo supervisorctlsans mot de passe. https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

Depuis mon serveur local / de développement, j'ai mis en place git remotece qui me permet de pousser vers le serveur de production

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

En prime, vous pourrez voir toutes les invites pendant l'exécution du script. Vous verrez donc s'il y a un problème avec la migration / l'installation du package / le redémarrage du superviseur.


notez d'utiliser shebang #!/bin/bashcomme indiqué ci-dessus au lieu de #!/bin/shce que l' post-receiveexemple Git avait!
bref le
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.