Nginx vs Caddy vs Traefik: ipi ni bora kwa VPS yako?
Linganisha Nginx, Caddy, na Traefik ili kuchagua reverse proxy sahihi. Jifunze tofauti zao katika usimamizi wa vyeti vya TLS, usanidi wa Docker, na utendaji wa websockets.
Nginx dhidi ya Caddy dhidi ya Traefik: jibu fupi
Nginx, Caddy na Traefik zote hufanya kazi sawa kama reverse proxy: husikiliza kwenye port 443, husoma hostname katika kila ombi, na kuielekeza kwenye huduma sahihi katika VPS yako. Yoyote kati ya hizo tatu itaweka programu nne unazojiendeshea nyuma ya anwani moja ya IP ya umma, na zote zina kasi ya kutosha kiasi kwamba programu zako ndizo zitakuwa sehemu ya polepole. Kinachotofautiana ni jinsi kila moja inavyopata cheti cha TLS (transport layer security) na kiasi cha usanidi ambacho kila programu ya ziada inakugharimu. Tofauti nyingine hujitokeza baadaye, siku utakapohitaji kitu ambacho mafunzo ya kawaida hayakigusi.
Chagua Caddy ikiwa unataka HTTPS ishughulikiwe kwa ajili yako na huduma zako ni programu za kawaida za wavuti. Chagua Traefik ikiwa kila kitu kinaendeshwa ndani ya Docker Compose na unaongeza huduma mpya kila baada ya wiki chache. Chagua Nginx ikiwa tayari unaitumia, au ikiwa unahitaji response caching, client certificates, raw TCP forwarding, au usanidi mkubwa uliopo ambao ungependelea usiuandike upya.
Kila moja hupataje cheti cha TLS?
Mhimili huu ndio huamua kwa watu wengi, kwa hivyo anza hapa. Zote tatu huishia kuwa na cheti kilekile kutoka kwa mamlaka ileile. Kazi unayofanya ili kufika hapo si sawa.
Caddy huomba cheti kwa sababu umetaja hostname. Andika app.example.com kama anwani ya tovuti na Caddy huomba cheti kupitia ACME (automatic certificate management environment) kutoka Let's Encrypt, hutumia ZeroSSL ikiwa hiyo itafeli, hutoa redirect ya HTTP kwenda HTTPS kwenye port 80, na hujihuisha yenyewe. Hakuna zana ya pili na hakuna timer ya kukagua. Vyeti hukaa kwenye saraka ya data ya mtumiaji wa caddy, /var/lib/caddy/.local/share/caddy kwenye usakinishaji wa kifurushi, kwa hivyo ongeza njia hiyo kwenye backups zako au ukubali utoaji mpya baada ya kujenga upya. Kwa hostname isiyo ya umma, tls internal hutia saini kwa kutumia mamlaka ya cheti cha ndani ya Caddy badala yake. Hiyo hukupa kitu kilekile kama kuunda cheti kilichotiwa saini na wewe mwenyewe kwenye Ubuntu, huku uhuishaji ukishughulikiwa kwa ajili yako.
Nginx haina mteja wa ACME. Certbot hupata cheti, na plugin yake ya --nginx huandika upya server block yako ili kuongeza msikilizaji wa 443 na redirect. Uhuishaji huendeshwa kutoka kwa systemd timer ambayo kifurushi husakinisha, kwa hivyo kuna sehemu mbili zinazohamia na vitu viwili vya kuthibitisha: systemctl list-timers | grep certbot huonyesha timer ipo, na sudo certbot renew --dry-run huthibitisha njia ya uhuishaji bado inafanya kazi. Hatua kwa hatua ziko kwenye Certbot kwenye Ubuntu 24.04 na Nginx, na zana hiyo hiyo inashughulikia cheti cha wildcard kupitia changamoto ya DNS-01 unapokuwa na subdomain nyingi kuliko unazotaka kuorodhesha.
Traefik hubeba mteja wake wa ACME. Unasanidi resolver moja ya cheti katika usanidi tuli, na kila router inaweza kuitumia. Hali yote, ikijumuisha ufunguo wa akaunti na vyeti, hukaa kwenye faili moja ya acme.json. Traefik hukataa kutumia faili hiyo ikiwa inaweza kusomwa na mtu yeyote isipokuwa mmiliki wake, na hukuambia hivyo kabla ya kuacha resolver:
The ACME resolver "le" is skipped from the resolvers list because: unable to get ACME account: permissions 660 for /letsencrypt/acme.json are too open, please use 600Mount saraka na uiruhusu Traefik iunde faili yenyewe. Iunde kwanza kwa touch na itarithi umask yako, ambayo ndiyo njia ambayo watu wengi hukutana na mstari huo.
Kitu kimoja ni kweli kwa zote tatu. Changamoto ya HTTP-01 inahitaji port 80 iweze kufikiwa kutoka kwenye Internet, kwa sababu mamlaka ya cheti huunganisha kurudi kwayo. Fungua 443 pekee na utoaji utafeli kwa njia inayosomeka kama hitilafu ya DNS.
Kazi ileile ya kuelekeza programu mbili katika usanidi tatu
Kazi yenyewe: app.example.com inaelekea kwenye huduma iliyo kwenye 127.0.0.1:8080, files.example.com inaelekea kwenye huduma iliyo kwenye 127.0.0.1:8081, zote zikipitia HTTPS. Hapa kuna kila kitu katika kila proksi, ili tofauti ya ukubwa wa usanidi ionekane badala ya kusimuliwa tu.
Nginx
# /etc/nginx/sites-available/app.example.com
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
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;
}
}Kisha iunganishe, ifanyie majaribio, ianzishe upya (reload), na uongeze cheti.
sudo ln -s /etc/nginx/sites-available/app.example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d app.example.comnginx -t inayochapisha syntax is ok na test is successful ndiyo ukaguzi wa kufanya kabla ya kila reload. Programu ya pili ni kizuizi kilekile chenye hostname na port iliyobadilishwa. Mistari ya proxy_set_header si mapambo: wakati proxy_pass inapotaja anwani, nginx hutuma Host: 127.0.0.1:8080 kwenda upstream kwa chaguo-msingi, kwa hivyo programu inayounda URL kamili kutoka kwa Host header itawapeleka watumiaji wako kwenye localhost.
Caddy
app.example.com {
reverse_proxy 127.0.0.1:8080
}
files.example.com {
reverse_proxy 127.0.0.1:8081
}sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddyHiyo ndiyo faili nzima. reverse_proxy huweka X-Forwarded-For, X-Forwarded-Proto na X-Forwarded-Host yenyewe, na kwa chaguo-msingi hupuuza chochote ambacho mteja alituma katika vichwa (headers) hivyo, kwa hivyo ombi haliwezi kudanganya backend yako kuhusu mahali lilipotoka. Vyeti, kuelekeza upya (redirect) kwa port 80 na usasishaji vyote hufuata kutoka kwa anwani mbili za tovuti. Hakuna kingine kwenye faili kinachoviomba.
Traefik
Traefik inahitaji usanidi tuli (static configuration) kabla ya kuelekeza chochote. Kama huduma ya Compose, ikiwa na tag ya image iliyo ya sasa kufikia Agosti 2026:
services:
traefik:
image: traefik:v3.7
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.le.acme.email=you@example.com"
- "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.le.acme.httpchallenge.entrypoint=web"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./letsencrypt:/letsencryptKila programu kisha hubeba uelekezaji wake, kwenye labels, katika faili yake ya compose:
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`app.example.com`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls.certresolver=le"
- "traefik.http.services.app.loadbalancer.server.port=8080"loadbalancer.server.port ni port iliyo ndani ya container, si port iliyochapishwa (published), kwa sababu Traefik hufikia container kupitia mtandao wa Docker ulioshirikiwa. Programu haihitaji mstari wa ports: hata kidogo, na hiyo ndiyo faida halisi: Traefik pekee ndiyo iliyochapishwa. Ujenzi kamili, ikijumuisha mtandao ulioshirikiwa na middleware ya kuelekeza upya, uko kwenye kuelekeza programu nyingi kwa kutumia Traefik na Docker Compose.
Kila programu ya ziada inagharimu kiasi gani cha usanidi?
The data behind this chart
[
{
"tool": "Nginx",
"proxy_setup_lines": 0,
"lines_per_app": 11
},
{
"tool": "Caddy",
"proxy_setup_lines": 0,
"lines_per_app": 3
},
{
"tool": "Traefik",
"proxy_setup_lines": 17,
"lines_per_app": 5
}
]Imehesabiwa kutoka kwa vizuizi vilivyo hapo juu. Kizuizi cha seva ya Nginx kina mistari 11 isiyo tupu, na unaandika tena kwa kila hostname. Kizuizi cha tovuti ya Caddy kina mistari 3. Traefik inahitaji mistari 17 ya usanidi tuli kabla ya kuhudumia ombi lolote, kisha lebo 5 kwa kila programu.
Tathmini uwiano, si mshindi. Traefik inagharimu zaidi kabla ya programu ya kwanza na kidogo zaidi kwa kila programu inayofuata, na jumla hizo mbili hukutana karibu na tovuti ya tatu. Chini ya hapo, usanidi tuli ni mzigo usio wa lazima. Juu ya hapo, lebo huchukua nafasi ya mbele na kuendelea kuongoza, kwa sababu uelekezaji (routing) unakaa karibu na huduma inayoelekezwa. Futa huduma na uelekezaji wake utafutika, jambo ambalo faili kuu ya usanidi hushindwa kufanya: vizuizi vya seva vilivyopitwa na wakati kwa programu ambazo ziliacha kuwepo miezi iliyopita.
Idadi ya mistari pia huipendelea Nginx. Kila kizuizi kati ya hivyo kinahitaji symlink, nginx -t, reload na uendeshaji wa certbot, wakati marekebisho ya Caddy yanahitaji reload moja na marekebisho ya Traefik hayahitaji amri yoyote. Zote tatu hufanya reload bila kukata miunganisho inayotumika. Tofauti ni idadi ya hatua tofauti unazopaswa kukumbuka saa tisa za usiku.
Ni nani anayefahamu kuhusu kontena zako?
Traefik hufuatilia Docker socket na kujenga routers kutoka kwenye labels za kontena kadiri kontena zinavyoanza na kusimama. Hakuna kingine hapa kinachofanya hivyo. Nginx na Caddy vyote vinahitaji marekebisho ya usanidi na reload wakati kontena mpya inapoonekana, na vinahitaji anwani inayoweza kufikiwa: aidha port iliyochapishwa kwenye loopback, au Docker network ya pamoja ambayo proxy imeunganishwa nayo.
Kipengele hicho kina gharama, na ni vyema kusema wazi. Traefik inasoma /var/run/docker.sock. Mtu yeyote anayeweza kuwasiliana na socket hiyo anaweza kuanzisha kontena yenye mfumo wa faili wa host uliopachikwa ndani yake, jambo ambalo ni root kwenye host. Kuipachika kwa hali ya read-only hupunguza hatari bila kuiondoa kabisa. Ikiwa hilo ni muhimu kwa mtindo wako wa vitisho, weka socket proxy katikati ambayo inafichua tu endpoints za orodha ya kontena ambazo Traefik inahitaji.
Caddy inaweza kufanya ugunduzi wa msingi wa labels kupitia plugin ya jamii, lakini plugins za Caddy huunganishwa wakati wa compilation, kwa hivyo unajenga binary maalum au image maalum na xcaddy na kisha unawajibika kwa build hiyo na masasisho yake. Kwa huduma tatu au nne, kuhariri Caddyfile ni kazi ndogo zaidi.
Websockets na utiririshaji: nini kinaharibika, na kwa nini
Nginx ndiyo inayohitaji kusaidiwa. Muunganisho wa WebSocket huanza kama ombi la HTTP lenye Upgrade: websocket, na nginx haipitishi hop-by-hop headers kwenda kwenye upstream isipokuwa ukiiagiza ifanye hivyo.
# /etc/nginx/conf.d/upgrade-map.conf
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}Kisha, ndani ya block ya location, lazima mistari mitatu ifuatayo iwepo yote:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;Ukiiondoa, console ya kivinjari itaonyesha WebSocket connection to 'wss://app.example.com/ws' failed huku log ya backend yako ikionyesha GET ya kawaida. map ipo kwa sababu Connection: upgrade iliyowekwa kwa kudumu ingetumwa kwenye kila ombi, ikiwemo yale ya kawaida ambayo yanapaswa kusema close.
Mipangilio mingine miwili ya kawaida ya Nginx inaleta changamoto. proxy_read_timeout ni sekunde 60 na inatumika kwenye tunnel baada ya upgrade, kwa hivyo websocket isiyo na trafiki kwa dakika moja hufungwa na proxy. Na server-sent events hufika kwa kuchelewa au kwa vipindi hadi utakapoweka proxy_buffering off; kwenye location hiyo, kwa sababu nginx huhifadhi majibu kwenye buffer yake wakati ukurasa wako unasubiri.
Caddy hufanya upgrade na kubadilisha muunganisho kuwa tunnel ya pande mbili bila maelekezo yoyote ya ziada. Pia, hutoa data mara moja wakati jibu ni text/event-stream au halina urefu unaojulikana, kwa hivyo utiririshaji hufanya kazi bila kubadilishwa. Traefik hupitisha upgrades na haihifadhi majibu kwenye buffer isipokuwa uongeze middleware yake ya buffering mwenyewe. Ikiwa huduma zako zinajumuisha chat, terminal ya wavuti, log tails au dashibodi za moja kwa moja, hiyo ni tofauti kubwa katika kiasi cha usanidi utakachoandika na kutatua.
Block kamili ya seva ya Nginx, ikijumuisha websockets na SSE
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name app.example.com;
client_max_body_size 64m;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
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_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_read_timeout 3600s;
proxy_buffering off;
}
}map inapaswa kuwa katika muktadha wa http, si ndani ya server, kwa hivyo iweke kwenye faili yake yenyewe chini ya /etc/nginx/conf.d/. Zima proxy_buffering kwenye location zinazotiririsha data pekee, kwa sababu buffering ndiyo inayoruhusu nginx kuachia backend worker mapema kwenye majibu ya kawaida. Certbot huandika upya block hii unapoitumia, kwa hivyo soma faili hiyo tena baada ya hapo.
Nini hutokea unapohitaji kitu kisicho cha kawaida?
Hapa ndipo Nginx inapojipatia sifa kwa mistari yake ya ziada ya usanidi.
- Vyeti vya mteja (Client certificates), vinavyojulikana pia kama mTLS (mutual TLS), ambapo mteja lazima awasilishe cheti pia. Nginx inahitaji
ssl_client_certificate /etc/ssl/ca.pem;nassl_verify_client on;katika block ya seva. Caddy inahitaji block yaclient_authndani yatls. Lebo za Traefik haziwezi kuelezea hili kabisa: unafafanua chaguo la TLS katika mtoa huduma wa faili (file provider) na kuelekeza router kwalo kwa kutumiatraefik.http.routers.app.tls.options=mtls@file. Mfumo wa kuweka kila kitu kwenye lebo hupata ubaguzi mara ya kwanza unapohitaji hili. - Upakiaji mkubwa wa faili (Large uploads). Nginx hupunguza ukubwa wa miili ya maombi (request bodies) hadi 1 MB kwa chaguomsingi. Upakiaji mkubwa zaidi hurejesha
413 Request Entity Too Large, na logi ya makosa husemaclient intended to send too large body. Ongezaclient_max_body_size. Caddy na Traefik hazina kikomo cha mwili kwa chaguomsingi, kwa hivyo ombi hufika kwenye programu yako na kikomo cha programu yako yenyewe ndicho huamua. - Caching ya majibu (Response caching). Nginx ina
proxy_cache, na ni thabiti. Caddy inahitaji plugin iliyokusanywa (compiled) ndani yake. Toleo la chanzo huria la Traefik halina cache ya HTTP kabisa, jambo ambalo huwashangaza watu wanaodhani kila proxy hufanya caching. - TCP au UDP ghafi, kwa ajili ya port ya database au seva ya mchezo. Nginx ina moduli ya
stream. Traefik ina routers za TCP na UDP kwenye entrypoints zake zenyewe. Caddy inahitaji plugin nyingine, kwa hivyo inahitaji ujenzi mwingine maalum (custom build). - Seva ya wavuti iliyo nyuma ya proxy. Ikiwa huduma ni programu ya kawaida ya PHP, basi LAMP stack kwenye Ubuntu 24.04 tayari inajumuisha Apache, na kuweka proxy mbele yake hukupa maeneo mawili yanayoweka headers na mawili yanayoweza kubadilisha URL. Amua ni ipi itakayomalizia TLS (terminate TLS), kisha iache nyingine kwenye HTTP ya kawaida iliyofungwa kwenye loopback.
Mtego wa firewall unaofuata chaguo hili
Lengo la reverse proxy ni kuhakikisha kuwa port 80 na 443 pekee ndizo zilizo wazi. Docker hufuta mpangilio huo kimyakimya. Kuchapisha port kwa kutumia -p 8080:80 huandika sheria ya DNAT kwenye jedwali la nat, na sheria hiyo huchunguzwa kabla ya sheria za INPUT zinazosimamiwa na ufw. Kwa hivyo, ufw deny 8080 haizuii muunganisho huo na programu yako inakuwa wazi kwenye Internet kando ya proxy uliyoisanidi kwa uangalifu. Funga (bind) port zilizochapishwa kwenye loopback kwa kutumia 127.0.0.1:8080:80, au acha kabisa kutumia ports: na uiruhusu proxy ifikie container kupitia Docker network, jambo ambalo ndilo mfano wa Traefik hapo juu unalofanya. Utaratibu huu na suluhisho lake viko kwenye kwa nini port zilizochapishwa na Docker hupita ufw.
Ijaribu kutoka kwenye mashine ambayo siyo hiyo VPS, kwa sababu ukaguzi unaofanywa ndani ya seva hiyo yenyewe utafaulu kila wakati:
curl --max-time 5 http://your.server.address:8080Connection refused au muda kuisha (timeout) ndiyo matokeo unayotaka. Jibu la HTTP linamaanisha kuwa programu hiyo inafikika bila kupitia proxy yako, na kila kitu ulichosanidi hapo juu ni mapambo tu.
Ni proxy ipi unapaswa kuchagua?
Tovuti tuli nyingi, pamoja na programu moja au mbili: Caddy. HTTPS ya kiotomatiki huondoa kazi kubwa zaidi ya mara kwa mara uliyo nayo. Usanidi hubaki mfupi kiasi cha kusomeka kwenye skrini moja, na tovuti tuli ni mstari wa root na mstari wa file_server ndani ya block moja ya tovuti. Gharama yake ni kuwa na hifadhi ndogo ya majibu ya kunakili na kubandika (copy-paste) wakati kitu kisicho cha kawaida kinapoharibika.
Homelab ya docker-compose unayoendelea kuiongezea huduma: Traefik. Baada ya huduma ya tatu, labels huchukua kazi kidogo kuliko kuhariri faili kuu, na huduma iliyofutwa huondoa njia yake yenyewe. Tenga mchana mzima kwa ajili ya usanidi wa kwanza, kwa sababu entrypoints, routers, services na middlewares ni msamiati mpya. Kosa la kuandika (typo) kwenye label kwa kawaida huonekana kama 404 kutoka kwa Traefik badala ya kushindwa kuanza, kwa hivyo soma docker logs traefik kwa ajili ya kosa la uchanganuzi (parse error) kabla ya kudhani kuwa programu imevunjika.
Usanidi wa Nginx uliopo, au hitaji lolote kutoka kwenye orodha hapo juu: Nginx. Tayari ina jibu kwa ajili ya caching ya majibu na kwa ajili ya vyeti vya mteja (client certificates), na karibu kila mwongozo wa watu wengine huichukulia hiyo. Gharama yake ni kwamba vyeti na usaidizi wa websocket ni vitu unavyosanidi badala ya vitu unavyopata moja kwa moja.
Kanuni moja inatumika bila kujali unachochagua. Mchakato mmoja tu ndio husikiliza kwenye interface ya umma, na kila kitu kingine husikiliza kwenye loopback au kwenye mtandao wa kibinafsi wa Docker.
FAQ
Ni reverse proxy ipi iliyo bora kwa programu chache za Docker kwenye VPS moja?
Kwa huduma tatu au nne unazoongeza mara kwa mara, Traefik inafaa zaidi kwa sababu kila programu hubeba lebo zake za routing na haihitaji kuhariri faili kuu. Ikiwa huduma ni thabiti na unataka tu HTTPS isikuletee shida, Caddy ni rahisi kujifunza na haiharibiki haraka. Chagua Nginx ikiwa tayari unaifahamu, au unapohitaji kipengele ambacho zingine hazina, kama vile response caching au TCP listener ya kawaida.
Je, Caddy haihitaji usanidi wowote wa cheti?
Kwa matumizi ya kawaida, ndiyo. Kutaja hostname ya umma kama anwani ya tovuti ndio usanidi mzima: Caddy huomba cheti kupitia ACME, hutoa redirect kutoka port 80, na kusasisha cheti kabla ya muda wake kuisha. Mambo mawili lazima yawe kweli. Port 80 lazima iweze kufikiwa kutoka Internet kwa ajili ya HTTP-01 challenge, na DNS A au AAAA record ya hostname lazima ielekeze kwenye VPS, kwa sababu mamlaka ya vyeti hutatua jina hilo na kuunganisha nyuma kwenye seva hiyo.
Je, ninaweza kuendesha Nginx na Traefik kwenye VPS moja?
Huwezi kwenye port zilezile. Yoyote itakayoanza ya pili itashindwa kufunga port, na Nginx itatoa bind() to 0.0.0.0:443 failed (98: Address already in use) wakati Traefik itatoa kosa kama hilo la bind na kuzima. Endesha proxy moja kwenye 80 na 443, na uweke kila kitu kingine nyuma yake. Ikiwa unahamisha huduma, hamisha hostname moja baada ya nyingine: acha proxy ya mbele ipeleke maombi kwenye ile ya zamani kupitia loopback port hadi tovuti ya mwisho itakapohamia.
Kwa nini websockets zangu hukatika baada ya sekunde 60 zikiwa nyuma ya Nginx?
proxy_read_timeout ina muda chaguo-msingi wa sekunde 60 na inatumika kwenye tunnel pindi upgrade inapokamilika, kwa hivyo muunganisho usio na trafiki kwa dakika moja hufungwa na proxy badala ya programu yako. Ongeza muda huo kwenye location husika kwa kutumia proxy_read_timeout 3600s;, au fanya programu itume ping frame kila baada ya sekunde 30. Caddy na Traefik hazifungi miunganisho iliyoboreshwa (upgraded) inayokaa bila kazi kwa kipima muda cha dakika moja, ndiyo maana programu hiyo hiyo inaweza kuonekana thabiti nyuma yao na kutokuwa thabiti nyuma ya Nginx.