Jang go Tsamaisa Di-app tsa Python ka Gunicorn le Nginx mo VPS
Tsenya application ya Flask kgotsa FastAPI mo Ubuntu ka virtualenv, tirelo ya systemd ya Gunicorn, reverse proxy ya Nginx, TLS, difaele tsa tikologo, go loga, le lenaane la go tlhola diphoso tsa 502 le go lekanya badiri.

Server e e agilweng mo teng ya Flask le uvicorn --reload ke tsa tlhabololo. Mo VPS e e bulegileng o batla motsamaisi wa tsamaiso yo o simololang badiri gape, yo o golaganyang kwa localhost, yo o ntseng kwa morago ga reverse proxy e e laolang TLS le di-client tse di nanya. Gunicorn ke kgetho e e tlwaelegileng ya WSGI ya Flask le Django. FastAPI e ka tsamaya ka fa tlase ga Gunicorn ka class ya worker ya Uvicorn. Nginx (kgotsa Caddy) e feleletsa HTTPS mme e fetisetsa kwa 127.0.0.1:8000.
Kaelo e e tsamaya ka peakanyo e e tshelang go tshuba gape: porojeke mo /srv/app, virtualenv, .env e e nang le diphiri, yuniti ya gunicorn.service, server block ya Nginx, Let's Encrypt, le difaele tsa log tse o ka di grep-ang tota. Re tla bua le ka palo ya badiri, di-timeout, le gore ke ka ntlha yang 502 Bad Gateway e se gantsi e se 'Nginx e senyegile' — gantsi ke Gunicorn e e sa tsamayeng, e e golagantsweng kwa socket e e fosagetseng, kgotsa e e phutlhagang fa e import. Sekao se dirisa Flask, ka dintlha tsa FastAPI fa taelo e farologana.
Ke ka ntlha yang stack e
Gunicorn e prefork ditsamaiso tsa worker. Worker mongwe le mongwe o tshwara kopo e le nngwe ka nako ntle le fa o dirisa class e nngwe ya worker. Nginx e buffer di-client tse di nanya gore badiri ba se ka ba tshwarega ba romela di-byte kwa network ya mogala. systemd e simolola app gape fa e swa. Mmogo se se tena, e leng se o se batlang ka 3 a.m.
- Gunicorn: mofuta o o tsitsitseng wa tsamaiso ya WSGI/ASGI
- systemd: simolola fa o tshuba, simolola gape fa e phutlhaga, di-log tsa journald
- Nginx: TLS, difaele tsa static, meedi ya bogolo jwa kopo, gzip
- venv: Python ya system e nna e phepa
- go golaganya localhost: app ga e fitlhelelwe ntle le ka Nginx
Ditlhokego
Python 3.10+ mo Ubuntu 22.04/24.04 e siame. O se ka wa tsamaisa pip jaaka root mo di-site-package tsa system. O tlhoka domain bakeng sa TLS. Fa o rata Caddy jaaka proxy, yuniti ya Gunicorn mo athikeleng e e nna e tshwana — ke peakanyo ya kwa pele fela e e fetogang (bona athikele ya Caddy).
- VPS ya Ubuntu 22.04 kgotsa 24.04
- Application ya gago e e nang le requirements.txt kgotsa se se lekanang
- WSGI entrypoint (ya Flask: app:app) kgotsa ASGI (ya FastAPI: app:app ka badiri ba uvicorn)
- A record ya domain bakeng sa HTTPS
Kgato 1: Di-package tsa system, modirisi le directory ya porojeke
Tlhama modirisi wa system yo o sa kgoneng go tsena ka go bua, yo o tshwarang khoutu, yo o tsamaisang Gunicorn. Go tsenya python3-venv le didirisiwa tsa go aga go tila go palelwa ga pip mo di-package tse di santse di agang di-extension tsa C.
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/Kgato 2: Virtualenv le di-dependency
Tlhama venv jaaka appuser gore bong jwa difaele bo nne bo siame. Tshwara di-version mo production. Morago ga go tsenya, netefatsa gore o ka import app mo gunicorn --check-config e le nngwe kgotsa import ya Python. Diphoso tsa import fa ke diphoso tse di nnyang 502 moragonyana.
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')"Kgato 3: Faele ya tikologo
O se ka wa kwala SECRET_KEY kgotsa di-URL tsa database mo yuniting ya systemd ka tsela e e felelalang mo git e e ka balwang ke mongwe le mongwe. Dirisa EnvironmentFile. chmod 640, mong ke root, setlhopha ke appuser (kgotsa mong ke appuser fa o rata).
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/.envKgato 4: Tirelo ya systemd ya Gunicorn
Golaganya kwa 127.0.0.1:8000, e seng 0.0.0.0, ntle le fa o na le lebaka la go tlola Nginx. Palo ya badiri gantsi ke (2 x CPU) + 1 bakeng sa badiri ba sync; mo VPS ya 2 vCPU seo ke 5, se se ka nna se se dintsi fa worker mongwe le mongwe a laela model e e boima ya ML — ke gone o dirisang 2–3. Bakeng sa FastAPI, baya --worker-class uvicorn.workers.UvicornWorker mme o tsenye uvicorn. Di-timeout di tshwanetse go feta kopo ya gago e e nanya e e siameng, e seng metsotswana e le 30 fa o na le di-export tsa metsotso e le 2.
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 8000Kgato 5: Reverse proxy ya Nginx le TLS
Nginx e reetsa mo 80/443 mme e proxy kwa Gunicorn. client_max_body_size e botlhokwa bakeng sa go tsenya difaele. proxy_read_timeout e tshwanetse go tshwana kgotsa go feta timeout ya Gunicorn. Morago ga gore server block e bereke mo HTTP, ntsha setifikeiti ka Certbot (kgotsa fetolela kwa pele go Caddy). Snippet e e fa tlase ke ya HTTP fela gore o kgone go testa; mme o tsamaisa Certbot e e ka fetolang faele.
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.comKgato 6: Difaele tsa static, ditumelo le dintlha tsa Flask/FastAPI
Nginx e tshwanetse go direla difaele tsa static fa o kgona; e bonako go feta Gunicorn. Django collectstatic, Flask send_from_directory ya di-app tse dinnye thata, kgotsa CDN moragonyana. Appuser o tshwanetse go kgona go bala setlhare. Fa o dirisa FastAPI, tsenya uvicorn[standard] mo venv mme o fetole ExecStart go dirisa UvicornWorker. Fa o dirisa di-socket tsa Unix go na le TCP, baya proxy_pass kwa socket mme o tshwanise ditumelo gore www-data e kgone go kwala mo go yone.
# 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/appBadiri, memory le di-reload tse di se nang go kgaoga
Badiri ba sync ba Gunicorn ba motlhofo mme ba lekane bakeng sa di-API tsa kopo/karabo tse di bofefo mo CPU. Fa o tlhoka go leta I/O e e nanya e e ntsi ka nako e le nngwe, akanya gevent kgotsa worker ya ASGI — lekanya, o se ka wa akanya. Worker mongwe le mongwe o laela app ya gago; RAM ~= badiri baata RSS ya app. VPS ya 2 GB e e nang le badiri ba le 8 ba app ya 300 MB e tla swap mme e utlwale 'e nanya ka go sa solofelwa'. systemctl reload gunicorn (HUP) e ka simolola badiri gape ka khoutu e ntšha fa o tsentse difaele mo lefelong; go simolola gape ka botlalo go tlhamalala fa di-dependency di fetoga.
# 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/healthGo rarabolola 502 le go phutlhaga ga se se sa utlwaleng
502 e raya gore Nginx ga e a kgona go nna le karabo e e siameng go tswa mo upstream. journalctl -u gunicorn -e ke taelo ya ntlha. Mabaka a a tlwaelegileng: leina le le fosagetseng la module:app, senotlolo sa .env se se tlhaelang, Postgres ga e tsamaye, e golagantswe kwa 127.0.0.1 mme Nginx e mo host e nngwe, SELinux (ga e tlwaelega mo Ubuntu), kgotsa app e reetsa mo IPv6 fela. 504 ke timeout. Di-loop tsa 301 di diragala fa app e fetisetsa kwa HTTP fa X-Forwarded-Proto e sa reediwa.
- systemctl status gunicorn — a e a bereka?
- journalctl -u gunicorn -n 100 — ImportError, env e e tlhaelang, database
- curl -v http://127.0.0.1:8000/ go tswa mo VPS — fa se se palelwa, Nginx ga e na molato
- nginx -t le error.log — upstream e tswaletse kgolagano pele ga nako
- ss -tulpn | grep 8000 — ga go na sepe se se reetsang
- Disk e tletse — badiri ba phutlhaga ka ditsela tse di sa tlhaloganyesegeng
Tshireletso
App ga e ise e golaganye mo setšhabeng. Diphiri di nna mo .env. Nna o patched venv le OS. O se ka wa tsamaisa Gunicorn jaaka root. Fa o tshwara go tsena, baya di-cookie tsa session Secure le SameSite, mme o beakanye framework go tshepa X-Forwarded-Proto go tswa mo Nginx fela. Baya moedi wa lebelo mo ditseleng tsa go tsena mo Nginx kgotsa mo app.
- golaganya 127.0.0.1 kgotsa unix socket
- chmod 600 .env
- User= yo e seng root mo systemd
- TLS ka Certbot kgotsa Caddy
- Tima debug mode le auto-reload mo production
Dikeletso
- Tsenya tsela ya /health e e tlholang kgolagano ya DB bakeng sa Compose le di-load balancer
- Romela di-asset tsa static ka header ya cache-control mo Nginx
- Dirisa worker kgotsa queue e e kgethegileng (Redis + systemd) ya di-imeile le ditiro tse di boima
- Tshwara di-version tsa gunicorn le uvicorn mo requirements.txt
- Tsaya snapshot pele ga phetogo ya ntlha ya production
App ya Python mo VPS e siapame bakeng sa production fa e tsamaya ka fa tlase ga Gunicorn jaaka tirelo ya systemd, e golaganya fela kwa localhost, mme e fitlhelelwa ka Nginx kgotsa Caddy ka TLS. Baya diphiri mo EnvironmentFile, lekanya badiri ka RAM go na le foromula ya athikele, mme o rarabolole 502 go tswa mo journal ya Gunicorn pele. Fa tsela e e kwadilwe bakeng sa repo ya gago, tsenyo nngwe le nngwe e e tlang ke rsync kgotsa git pull, pip install, le systemctl restart gunicorn.