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.