Kuidas käitada Pythoni rakendusi Gunicorn ja Nginxiga VPS-il
Juuruta Flask või FastAPI rakendus Ubuntuil virtualenviga, Gunicorn systemd teenusega, Nginx pöördproksiga, TLS-iga, keskkonnafailidega, logimisega ning 502 vigade ja workerite mõõtmise kontrollnimekirjaga.

Sisseehitatud Flaski server ja uvicorn --reload on arendamiseks. Avalikul VPS-il tahad protsessihaldurit, mis taaskäivitab workerid, seob localhostiga ja istub pöördproksi taga, mis tegeleb TLS-i ja aeglaste klientidega. Gunicorn on tavaline WSGI valik Flaskile ja Djangole. FastAPI saab joosta Gunicorn all Uvicorn worker klassiga. Nginx (või Caddy) lõpetab HTTPS-i ja edastab 127.0.0.1:8000 peale.
See juhend käib läbi paigutuse, mis elab taaskäivitused üle: projekt /srv/app, virtualenv, .env saladustega, gunicorn.service üksus, Nginx serveriplokk, Let's Encrypt ja logifailid, millest saad tegelikult greppida. Räägime ka workerite arvust, timeoutidest ja miks 502 Bad Gateway peaaegu kunagi ei ole 'Nginx on katki' — see on peaaegu alati Gunicorn, mis ei jookse, on seotud vale sokliga või krahhib impordil. Näide kasutab Flaski, märkustega FastAPI jaoks, kus käsk erineb.
Miks see virn
Gunicorn preforkib worker-protsesse. Iga worker käsitleb korraga üht päringut, kui sa ei kasuta teist worker klassi. Nginx puhverdab aeglasi kliente, et workerid ei jääks baitide saatmisele mobiilivõrku kinni. systemd taaskäivitab rakenduse, kui see sureb. Koos on see igav, mis on see, mida tahad kell kolm öösel.
- Gunicorn: stabiilne WSGI/ASGI protsessimudel
- systemd: start bootil, taaskäivitus krahhil, journald logid
- Nginx: TLS, staatilised failid, päringu suuruse piirangud, gzip
- venv: süsteemi Python jääb puhtaks
- localhost sidumine: rakenduseni jõuab ainult Nginxist
Nõuded
Python 3.10+ Ubuntu 22.04/24.04 peal sobib. Ära käita pipi rootina süsteemi site-packagesisse. TLS-i jaoks on vaja domeeni. Kui eelistad proksiks Caddyt, jääb selle artikli Gunicorn üksus samaks — muutub ainult esiosa seadistus (vaata Caddy artiklit).
- Ubuntu 22.04 või 24.04 VPS
- Sinu rakendus requirements.txt või samaväärsega
- WSGI sisenemispunkt (Flaskile: app:app) või ASGI (FastAPI-le: app:app uvicorn workeritega)
- Domeeni A-kirje HTTPS-i jaoks
Samm 1: Süsteemipaketid, kasutaja ja projektikataloog
Loo süsteemikasutaja, kes ei saa interaktiivselt sisse logida, oma koodi ja käita Gunicornt. python3-venv ja ehitustööriistade paigaldamine väldib pipi tõrkeid pakettidel, mis endiselt kompileerivad C-laiendeid.
ssh root@YOUR_VPS_IP
apt update && apt -y upgrade
apt -y install python3 python3-venv python3-pip python3-dev build-essential nginx curl
adduser --system --group --home /srv/app appuser
mkdir -p /srv/app
chown appuser:appuser /srv/app
# Copy your code (example):
# rsync -a --delete ./myproject/ appuser@YOUR_VPS_IP:/srv/app/Samm 2: Virtualenv ja sõltuvused
Loo venv appuserina, et failiomandus oleks õige. Lukusta versioonid tootmises. Pärast paigaldust kinnita, et saad rakenduse importida ühekordse gunicorn --check-config või Pythoni importiga. Impordivead siin on samad vead, millest hiljem saavad 502.
sudo -u appuser -H bash -lc '
cd /srv/app
python3 -m venv /srv/app/venv
/srv/app/venv/bin/pip install --upgrade pip
/srv/app/venv/bin/pip install -r /srv/app/requirements.txt gunicorn
'
# Flask example check:
sudo -u appuser -H /srv/app/venv/bin/python -c "from app import app; print('import ok')"Samm 3: Keskkonnafail
Ära kõvakodeeri SECRET_KEY-d ega andmebaasi URL-e systemd üksusesse viisil, mis satub maailmale loetavasse gitti. Kasuta EnvironmentFile. chmod 640, omanik root, grupp appuser (või omanik appuser, kui eelistad).
cat >/srv/app/.env <<'EOF'
FLASK_ENV=production
SECRET_KEY=replace-with-openssl-rand-hex-32
DATABASE_URL=postgresql://app:password@127.0.0.1:5432/app
EOF
chown appuser:appuser /srv/app/.env
chmod 600 /srv/app/.envSamm 4: Gunicorn systemd teenus
Seo 127.0.0.1:8000, mitte 0.0.0.0, kui sul pole põhjust Nginxist mööda minna. Workerite arv on sageli (2 x CPU) + 1 sünkroonitud workeritele; 2 vCPU VPS-il on see 5, mis võib olla liiga palju, kui iga worker laadib raske ML-mudeli — kasuta siis 2–3. FastAPI jaoks sea --worker-class uvicorn.workers.UvicornWorker ja paigalda uvicorn. Timeoutid peaksid ületama sinu kõige aeglasema ausa päringu, mitte 30 sekundit, kui sul on 2-minutilised ekspordid.
cat >/etc/systemd/system/gunicorn.service <<'EOF'
[Unit]
Description=Gunicorn for the web app
After=network.target
[Service]
User=appuser
Group=appuser
WorkingDirectory=/srv/app
EnvironmentFile=/srv/app/.env
ExecStart=/srv/app/venv/bin/gunicorn --workers 3 --bind 127.0.0.1:8000 --timeout 60 --access-logfile - --error-logfile - app:app
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now gunicorn
systemctl status gunicorn --no-pager
ss -tulpn | grep 8000Samm 5: Nginx pöördproksi ja TLS
Nginx kuulab 80/443 ja proksib Gunicornile. client_max_body_size loeb üleslaadimiste puhul. proxy_read_timeout peaks kattuma või ületama Gunicornt timeouti. Kui serveriplokk töötab HTTP-l, väljasta sertifikaat Certbotiga (või vaheta esiosa Caddyks). Alltoodud snippet on ainult HTTP, et saaksid testida; seejärel käivita Certbot, mis oskab faili muuta.
cat >/etc/nginx/sites-available/app <<'EOF'
server {
listen 80;
server_name app.example.com;
client_max_body_size 20m;
location /static/ {
alias /srv/app/static/;
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 90s;
}
}
EOF
ln -sf /etc/nginx/sites-available/app /etc/nginx/sites-enabled/app
nginx -t && systemctl reload nginx
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable
apt -y install certbot python3-certbot-nginx
certbot --nginx -d app.example.comSamm 6: Staatilised failid, õigused ja Flaski/FastAPI eripärad
Nginx peaks staatilisi faile serveerima, kui saad; see on kiirem kui Gunicorn. Django collectstatic, Flask send_from_directory pisikestele rakendustele või CDN hiljem. appuser peab puud saama lugeda. Kui kasutad FastAPI-d, paigalda uvicorn[standard] venv-i ja muuda ExecStart UvicornWorkerit kasutama. Kui kasutad TCP asemel Unixi sokleid, suuna proxy_pass soklile ja kattu õigused, et www-data saaks sinna kirjutada.
# FastAPI ExecStart example:
# ExecStart=/srv/app/venv/bin/gunicorn -k uvicorn.workers.UvicornWorker --workers 2 --bind 127.0.0.1:8000 app:app
# Unix socket variant:
# --bind unix:/run/gunicorn/app.sock
# Nginx: proxy_pass http://unix:/run/gunicorn/app.sock:
chown -R appuser:appuser /srv/appWorkerid, mälu ja null-downtime taaskäivitused
Sünkroonsed Gunicorn workerid on lihtsad ja piisavad CPU-kergete request/response API-de jaoks. Kui vajad palju samaaegseid aeglasi I/O ootamisi, kaalu geventi või ASGI workerit — mõõda, ära arva. Iga worker laadib sinu rakenduse; RAM ~= workerid korda rakenduse RSS. 2 GB VPS 8 workeriga 300 MB rakendusest hakkab swappima ja tundub 'juhuslikult aeglane'. systemctl reload gunicorn (HUP) oskab workerid uue koodiga taaskäivitada, kui juurutasid failid paigale; täielik taaskäivitus on selgem, kui sõltuvused muutuvad.
# After git pull / rsync of new code:
sudo -u appuser -H /srv/app/venv/bin/pip install -r /srv/app/requirements.txt
systemctl restart gunicorn
curl -I https://app.example.com/health502 ja vaiksete krahhide tõrkeotsing
502 tähendab, et Nginx ei saanud upstreamilt kehtivat vastust. journalctl -u gunicorn -e on esimene käsk. Tavalised põhjused: vale module:app nimi, puuduv .env võti, Postgres ei jookse, seotud 127.0.0.1, kuid Nginx teisel hostil, SELinux (haruldane Ubuntul) või rakendus kuulab ainult IPv6. 504 on timeout. 301 silmused tekivad, kui rakendus suunab HTTP-le, samas kui X-Forwarded-Proto ignoreeritakse.
- systemctl status gunicorn — kas see on aktiivne?
- journalctl -u gunicorn -n 100 — ImportError, puuduv env, andmebaas
- curl -v http://127.0.0.1:8000/ VPS-ilt — kui see ebaõnnestub, on Nginx süütu
- nginx -t ja error.log — upstream prematurely closed connection
- ss -tulpn | grep 8000 — midagi ei kuula
- Ketas täis — workerid krahivad salapärastel viisidel
Turvalisus
Rakendus ei seo kunagi avalikult. Saladused jäävad .env faili. Hoia venv ja OS paikadega. Ära käita Gunicornt rootina. Kui käsitled sisselogimisi, sea seansiküpsised Secure ja SameSite ning konfigureeri raamistik usaldama X-Forwarded-Proto ainult Nginxist. Kiirusepiira sisselogimisruute Nginxis või rakenduses.
- bind 127.0.0.1 või unix-sokkel
- chmod 600 .env
- Mitteroot User= systemd-is
- TLS Certboti või Caddy kaudu
- Keela silumisrežiim ja auto-reload tootmises
Näpunäited
- Lisa /health marsruut, mis kontrollib DB ühenduvust Compose'i ja koormusejaoturite jaoks
- Saada staatilised varad cache-control päisega Nginxis
- Kasuta e-posti ja raskete tööde jaoks eraldi workerit või järjekorda (Redis + systemd)
- Lukusta gunicorn ja uvicorn versioonid requirements.txt-s
- Tee hetktõmmis enne esimest tootmisele üleminekut
Pythoni rakendus VPS-il on tootmiskõlblik, kui see jookseb Gunicorn all systemd teenusena, seob ainult localhostiga ja selleni jõutakse Nginx või Caddy kaudu TLS-iga. Pane saladused EnvironmentFile'i, mõõda workerid RAM-i järgi, mitte blogivalemi järgi, ja otsi 502 esmalt Gunicornt päevikust. Kui see tee on sinu repo jaoks dokumenteeritud, on iga hilisem juurutus rsync või git pull, pip install ja systemctl restart gunicorn.