recarga automática de gunicorn en el cambio de fuente

113

Finalmente, migré mi entorno de desarrollo de runserver a gunicorn / nginx.

Sería conveniente replicar la función de recarga automática de runserver en gunicorn, para que el servidor se reinicie automáticamente cuando cambie la fuente. De lo contrario, tengo que reiniciar el servidor manualmente con kill -HUP.

¿Alguna forma de evitar el reinicio manual?

Paolo
fuente
Errata: en mi entorno, gunicorn es administrado / monitoreado por supervisor, por lo que realmente no kill -HUPprocesaría el PID, sino que usaría supervisorctl. Sin embargo, no creo que esto cambie mucho.
Paolo
3
github.com/benoitc/gunicorn/issues/154 tiene algunas soluciones
KZ

Respuestas:

232

Si bien esta es una pregunta antigua, solo por coherencia, ya que la versión 19.0 gunicorn tiene la --reloadopción. Así que no se necesitan más herramientas de terceros.

Dmitry Ziolkovskiy
fuente
5
convenido. Las otras respuestas pueden funcionar, pero esta es, con mucho, la más simple y no es una solución alternativa. Es exactamente lo que quería el OP.
J-bob
1
No creo que haya una opción --reload incorporada en gunicorn. ¿Dónde encontraste esto? Sus documentos dicen que vuelva a cargar la configuración, envíe un HUP ( killall -HUP procnamefuncionará bien) para que se inicien nuevos trabajadores y se apaguen los antiguos.
suavemente
3
Gracias @Guandalino, debo haberlo perdido. Sin embargo, es interesante notar que dicen "Esta configuración está destinada al desarrollo". Obviamente, esto funcionaría para la producción en algunos casos, pero también podría ser problemático para muchos otros. Sí, vi a continuación que aparentemente no está interesado en la producción / implementación.
suavemente
¿Cómo hacerlo de forma sencilla para servidores de producción?
juan Isaza
@juanIsaza, nunca debes usar dicha funcionalidad en producción. Si cree que lo necesita, debe reconsiderar su enfoque de desarrollo o implementación.
Dmitry Ziolkovskiy
20

Una opción sería usar --max-request para limitar cada proceso generado a atender solo una solicitud agregando --max-requests 1opciones de inicio. Cada proceso recién generado debería ver cambios en su código y, en un entorno de desarrollo, el tiempo de inicio adicional por solicitud debería ser insignificante.

Dave Forgac
fuente
1
Un truco agradable y elegante para dev env. No se puede usar en prod ... pero es posible que no desee la recarga automática en prod de todos modos, a menos que realice una "implementación continua". Si lo hace, de Bryan Helmig enfoque es mejor a pesar de que requiere el pippaquete de poder, watchdog.
placas de cocción el
2
Tomará ~ 3 segundos iniciar un nuevo trabajador, lo cual es demasiado lento para mí. (MBP de mediados de 2009)
Blaise
11

A Bryan Helmig se le ocurrió esto y lo modifiqué para usarlo en run_gunicornlugar de iniciarlo gunicorndirectamente, para que sea posible simplemente cortar y pegar estos 3 comandos en un shell en la carpeta raíz de su proyecto django (con su virtualenv activado):

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
encimeras
fuente
Solo lo usé para mí en fedora 15 con Django 1.5.4, gunicorn 18.0, watchdog 0.6, bash 4.2.
placas
No olvide poner su IP o FQDN y puerto en lugar de 127.0.0.1:80, si es necesario.
placas
1
@Guandalino, ¿suerte? Me ha funcionado bien durante un par de semanas. El único momento en que necesito reiniciar manualmente es cuando cambio settings.py, models.py(se requiere migración) o el código fuente de alguna aplicación externa que no está en mis watchmedopatrones.
placas
Gracias por el recordatorio. Pero no quiero votar sobre el éxito de otros. ¿Por qué esta (innecesaria) prisa? ¿Estoy violando alguna regla de StackOverflow? Si es así, hágamelo saber cómo remediarlo.
Paolo
1
Sin preocupaciones. Definitivamente no está violando una regla SO, solo es considerado / solícito / reflexivo poner esfuerzo / prioridad en la evaluación de respuestas útiles. Parece que Dave y yo nos tomamos nuestro tiempo para ayudarlo (muchos meses), por lo que mi sentido de urgencia por lograr que verifique nuestras soluciones es desproporcionado: estoy demasiado ansioso por saber si hay fallas ocultas en la forma en que He configurado mi servidor y si debo cambiar al enfoque de Dave . ¡Felices vacaciones!
placas
5

Utilizo git push para implementar en producción y configuro git hooks para ejecutar un script. La ventaja de este enfoque es que también puede realizar la migración y la instalación del paquete al mismo tiempo. 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

Luego crea un guión /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

Asegúrese de hacerlo chmod u+x post-receivey agregue usuarios a los sudoers. Permita que se ejecute sudo supervisorctlsin contraseña. https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

Desde mi servidor local / de desarrollo, configuro git remoteque me permite enviar al servidor de producción

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

Como beneficio adicional, podrá ver todas las indicaciones mientras se ejecuta el script. Entonces verá si hay algún problema con la migración / instalación del paquete / reinicio del supervisor.

user3628119
fuente
¡Tenga en cuenta que debe usar shebang #!/bin/bashcomo se indicó anteriormente en lugar de #!/bin/shlo que post-receivetenía el ejemplo de Git !
Curtisp