gunicorn si carica automaticamente al cambio di sorgente


113

Alla fine ho migrato il mio ambiente di sviluppo da runerver a gunicorn / nginx.

Sarebbe conveniente replicare la funzione di caricamento automatico di runserver su gunicorn, in modo che il server si riavvii automaticamente quando la sorgente cambia. Altrimenti devo riavviare manualmente il server con kill -HUP.

Qualche modo per evitare il riavvio manuale?


Errata corrige: nel mio ambiente gunicorn è gestito / monitorato da supervisord, quindi non avrei realmente kill -HUPil PID del processo, ma invece userei supervisorctl. Non credo che questo cambi molto, però.
Paolo

Risposte:


232

Anche se questa è una vecchia domanda, solo per coerenza - dalla versione 19.0 gunicorn ha --reloadun'opzione. Quindi nessuno strumento di terze parti ha bisogno di più.


5
concordato. Le altre risposte potrebbero funzionare, ma questa è di gran lunga la più semplice e non è una soluzione alternativa. È esattamente quello che voleva l'OP.
J-bob

1
Non credo che ci sia un'opzione --reload incorporata in gunicorn. dove lo hai trovato? I loro documenti dicono di ricaricare la configurazione, inviare un HUP ( killall -HUP procnamefunzionerà bene) per avviare nuovi lavoratori e chiudere con grazia quelli vecchi.
dolcemente il

3
Grazie @Guandalino, devo averlo perso. È interessante notare, tuttavia, che dicono "Questa impostazione è destinata allo sviluppo". Questo ovviamente funzionerebbe per la produzione in alcuni casi, ma potrebbe anche essere problematico per molti altri. Sì, ho visto di seguito che apparentemente non sei interessato alla produzione / distribuzione.
dolcemente

Come farlo in modo semplice per i server di produzione?
juan Isaza

@juanIsaza non dovresti mai usare questa funzionalità in produzione. Se pensi di averne bisogno, devi ripensare al tuo approccio per lo sviluppo o la distribuzione.
Dmitry Ziolkovskiy

20

Un'opzione potrebbe essere quella di utilizzare --max-richieste per limitare ogni processo generato a servire solo una richiesta aggiungendo --max-requests 1alle opzioni di avvio. Ogni processo appena generato dovrebbe vedere le modifiche al codice e in un ambiente di sviluppo il tempo di avvio aggiuntivo per richiesta dovrebbe essere trascurabile.


1
Trucco carino ed elegante per dev env. Non può essere usato su prod ... ma potresti non volere il caricamento automatico su prod comunque, a meno che tu non faccia "distribuzione continua". Se lo fai, di Bryan Helmig approccio è migliore anche se richiede il pippacchetto di grado, watchdog.
piani cottura

2
Ci vorranno circa 3 secondi per avviare un nuovo worker, che è troppo lento per me. (MBP metà 2009)
Blaise

11

Bryan Helmig ha inventato questo e l'ho modificato per usarlo run_gunicorninvece di avviarlo gunicorndirettamente, per rendere possibile semplicemente tagliare e incollare questi 3 comandi in una shell nella cartella principale del tuo progetto django (con il tuo virtualenv attivato):

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

L'ho appena usato per me su fedora 15 con Django 1.5.4, gunicorn 18.0, watchdog 0.6, bash 4.2.
piani cottura

Non dimenticare di inserire il tuo IP o FQDN e la porta al posto di 127.0.0.1:80, se necessario.
piani cottura

1
@Guandalino, qualche fortuna? Funziona bene per me da un paio di settimane ormai. L'unica volta che ho bisogno di riavviare manualmente è quando modifico settings.py, models.py(migrazione richiesta) o il codice sorgente di alcune app esterne non nei miei watchmedoschemi.
piani cottura

Grazie del promemoria. Ma non voglio esprimere il mio voto sul successo degli altri. Perché questa (non necessaria) fretta? Sto violando qualche regola StackOverflow? In tal caso, per favore fatemi sapere come rimediare.
Paolo

1
Nessun problema. Sicuramente non viola una regola SO, è solo premuroso / sollecito / premuroso mettere impegno / priorità nella valutazione di risposte utili. Sembra che Dave e io ci siamo presi il nostro dolce tempo per aiutarti (molti mesi), quindi il mio senso di urgenza nel farti verificare le nostre soluzioni è sproporzionato: sono eccessivamente ansioso di sapere se ci sono difetti nascosti nel modo in cui io ho configurato il mio server e se devo passare all'approccio di Dave . Buone vacanze!
piani cottura

5

Uso git push per eseguire il deploy in produzione e impostare git hook per eseguire uno script. Il vantaggio di questo approccio è che puoi anche eseguire la migrazione e l'installazione del pacchetto contemporaneamente. 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

Quindi crea uno 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

Assicurati di chmod u+x post-receivee aggiungi l'utente a sudoers. Consentire l'esecuzione sudo supervisorctlsenza password. https://www.cyberciti.biz/faq/linux-unix-running-sudo-command-without-a-password/

Dal mio server locale / di sviluppo, ho impostato git remoteche mi consente di eseguire il push al server di produzione

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

Come bonus, vedrai tutti i prompt mentre lo script è in esecuzione. Quindi vedrai se ci sono problemi con la migrazione / installazione del pacchetto / riavvio del supervisore.


nota di usare shebang #!/bin/bashcome indicato sopra invece di #!/bin/shquello che post-receiveaveva l'esempio di Git !
curtisp
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.