gunicorn autoreload na mudança de fonte


113

Por fim, migrei meu env de desenvolvimento de runserver para gunicorn / nginx.

Seria conveniente replicar o recurso autoreload de runserver para gunicorn, para que o servidor reinicie automaticamente quando a fonte mudar. Caso contrário, preciso reiniciar o servidor manualmente com kill -HUP.

Alguma maneira de evitar a reinicialização manual?


Errata: no meu env o gunicorn é gerenciado / monitorado pelo supervisord, então eu não usaria kill -HUPo PID do processo, mas usaria o supervisorctl. Mas não pense que isso muda muito.
Paolo,

3
KZ

Respostas:


232

Embora esta seja uma questão antiga, apenas para consistência - desde a versão 19.0 o gunicorn tem --reloadopção. Portanto, nenhuma ferramenta de terceiros precisava de mais.


5
acordado. As outras respostas podem funcionar, mas esta é de longe a mais simples e não é uma solução alternativa. É exatamente o que o OP queria.
J-bob

1
Eu não acredito que haja uma opção --reload embutida no gunicorn. Onde você achou isso? Seus documentos dizem para recarregar a configuração, enviar um HUP ( killall -HUP procnamefuncionará bem) para que novos trabalhos sejam iniciados e os antigos desligados sem problemas.
apenas

3
Obrigado @Guandalino, devo ter perdido. É interessante notar, porém, que eles dizem "Esta configuração é destinada ao desenvolvimento." Isso obviamente funcionaria para produção em alguns casos, mas também poderia ser problemático para muitos outros. Sim, vi abaixo que você aparentemente não está interessado em produção / implantação.
sofly

Como fazer de forma fácil para servidores de produção?
Juan Isaza

@juanIsaza você nunca deve usar tal funcionalidade na produção. Se você acha que precisa - você precisa repensar sua abordagem para desenvolvimento ou implantação.
Dmitry Ziolkovskiy

20

Uma opção seria usar --max-requisições para limitar cada processo gerado para servir apenas uma requisição adicionando --max-requests 1opções de inicialização. Cada processo recém-gerado deve ver suas alterações de código e, em um ambiente de desenvolvimento, o tempo extra de inicialização por solicitação deve ser insignificante.


1
Belo e elegante truque para dev env. Não pode ser usado no produto ... mas você pode não querer autoreload no produto de qualquer maneira, a menos que você faça "implantação contínua". Se o fizer, a abordagem de Bryan Helmig é melhor, embora requeira o pippacote capaz watchdog,.
fogão de

2
Levará cerca de 3 segundos para inicializar um novo trabalhador, o que é muito lento para mim. (MBP em meados de 2009)
Blaise,

11

Bryan Helmig veio com isso e eu modifiquei para usar em run_gunicornvez de iniciar gunicorndiretamente, para tornar possível apenas recortar e colar esses 3 comandos em um shell na pasta raiz do seu projeto django (com seu virtualenv ativado):

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

Usei-o para mim mesmo no fedora 15 com Django 1.5.4, gunicorn 18.0, watchdog 0.6, bash 4.2.
horas de

Não se esqueça de colocar seu IP ou FQDN e porta no lugar de 127.0.0.1:80, se necessário.
horas de

1
@Guandalino, alguma sorte? Está funcionando bem para mim há algumas semanas. Só preciso reiniciar manualmente quando mudo settings.py, models.py(migração necessária) ou o código-fonte de algum aplicativo externo que não está em meus watchmedopadrões.
horas

Obrigado pela lembrança. Mas não quero votar no sucesso dos outros. Por que essa pressa (desnecessária)? Estou violando alguma regra StackOverflow? Em caso afirmativo, deixe-me saber como corrigir.
Paolo

1
Não se preocupe. Definitivamente, não violando uma regra do SO, é apenas atencioso / solícito / atencioso colocar esforço / prioridade na avaliação de respostas úteis. Parece que Dave e eu demoramos muito para ajudá-lo (muitos meses), então meu senso de urgência em fazer com que você verifique nossas soluções é desproporcional - estou ansioso demais para saber se há falhas ocultas na maneira como eu configurei meu servidor e se devo mudar para a abordagem de Dave . Boas festas!
horas

5

Eu uso o git push para implantar na produção e configurar git hooks para executar um script. A vantagem dessa abordagem é que você também pode fazer a migração e a instalação do pacote ao mesmo tempo. 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

Em seguida, crie um 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

Certifique-se de chmod u+x post-receiveadicionar o usuário ao sudoers. Permita que ele seja executado sudo supervisorctlsem senha. https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

Do meu servidor local / de desenvolvimento, eu configurei o git remoteque me permite enviar para o servidor de produção

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 um bônus, você verá todos os prompts enquanto o script está sendo executado. Portanto, você verá se há algum problema com a migração / instalação do pacote / reinicialização do supervisor.


nota para usar shebang #!/bin/bash conforme mencionado acima, em vez de#!/bin/sh o post-receiveexemplo do Git !
curtisp
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.