SSD Nodes Learn Hosting plans →
गाइड Matt Connorलेखक: Matt Connor · अपडेट किया गया: 2026-08-23

Nginx बनाम Caddy बनाम Traefik: कौन सा Proxy चुनें?

एक VPS और एक public IP पर Nginx, Caddy और Traefik का चुनाव कैसे करें। TLS सर्टिफिकेट प्रबंधन, Docker राउटिंग, Websockets और कॉन्फ़िगरेशन की जटिलता के आधार पर सही टूल चुनें।

Nginx बनाम Caddy बनाम Traefik: संक्षिप्त उत्तर

Nginx, Caddy और Traefik तीनों reverse proxy के रूप में एक ही काम करते हैं: port 443 पर listen करना, प्रत्येक request में hostname को पढ़ना और उसे आपके VPS पर सही service तक पहुँचाना। इन तीनों में से कोई भी एक public IP address के पीछे चार self-hosted apps को व्यवस्थित कर सकता है, और ये सभी इतने तेज हैं कि आपकी apps ही धीमी साबित होंगी। अंतर केवल इस बात में है कि प्रत्येक tool TLS (transport layer security) certificate कैसे प्राप्त करता है और हर नई app को जोड़ने के लिए कितनी configuration करनी पड़ती है। एक और अंतर तब सामने आता है जब आपको किसी ऐसी चीज की आवश्यकता होती है जिसे सामान्य tutorials में छोड़ दिया जाता है।

यदि आप चाहते हैं कि HTTPS का प्रबंधन स्वतः हो जाए और आपकी services सामान्य web apps हैं, तो Caddy चुनें। यदि सब कुछ Docker Compose में चलता है और आप हर कुछ हफ्तों में एक नई service जोड़ते हैं, तो Traefik चुनें। यदि आप पहले से ही Nginx का उपयोग कर रहे हैं, या आपको response caching, client certificates, raw TCP forwarding, या किसी ऐसी बड़ी existing configuration की आवश्यकता है जिसे आप फिर से नहीं लिखना चाहते, तो Nginx चुनें।

प्रत्येक को TLS certificate कैसे मिलता है?

यह आधार अधिकांश लोगों के लिए निर्णय लेने का मुख्य बिंदु है, इसलिए यहीं से शुरुआत करें। अंत में तीनों ही एक ही authority से एक ही certificate प्राप्त करते हैं। लेकिन वहां तक पहुँचने के लिए किया जाने वाला कार्य अलग-अलग है।

Caddy certificate के लिए अनुरोध करता है क्योंकि आपने hostname का नाम दिया है। app.example.com को site address के रूप में लिखें और Caddy Let's Encrypt से ACME (automatic certificate management environment) के माध्यम से certificate का अनुरोध करता है। यदि वह विफल रहता है, तो यह ZeroSSL पर वापस आ जाता है, port 80 पर HTTP-to-HTTPS redirect प्रदान करता है, और स्वयं ही renew करता है। इसके लिए किसी दूसरे टूल या जाँच करने के लिए किसी timer की आवश्यकता नहीं होती है। Certificates caddy user की data directory में रहते हैं, जो package install होने पर /var/lib/caddy/.local/share/caddy होती है, इसलिए उस path को अपने backups में जोड़ें या rebuild के बाद नया issuance स्वीकार करें। जो hostname public नहीं है, उसके लिए tls internal Caddy की अपनी local certificate authority के साथ sign करता है। यह आपको वही परिणाम देता है जो Ubuntu पर self-signed certificate बनाने से मिलता है, जिसमें renewal आपके लिए प्रबंधित होता है।

Nginx में कोई ACME client नहीं होता है। Certbot certificate प्राप्त करता है, और इसका --nginx plugin आपके server block को rewrite करके 443 listener और redirect जोड़ता है। Renewal एक systemd timer से चलता है जिसे package install करता है, इसलिए इसमें दो गतिशील हिस्से और जाँचने के लिए दो चीजें होती हैं: systemctl list-timers | grep certbot दिखाता है कि timer मौजूद है, और sudo certbot renew --dry-run साबित करता है कि renewal path अभी भी काम कर रहा है। चरण-दर-चरण प्रक्रिया Nginx के साथ Ubuntu 24.04 पर Certbot में दी गई है, और वही टूल DNS-01 challenge के माध्यम से wildcard certificate को भी कवर करता है जब आपके पास सूचीबद्ध करने की इच्छा से अधिक subdomains हों।

Traefik का अपना ACME client होता है। आप static configuration में एक certificate resolver कॉन्फ़िगर करते हैं, और फिर प्रत्येक router इसका उपयोग कर सकता है। सारी स्थिति, जिसमें account key और certificates शामिल हैं, एक ही acme.json file में रहती है। यदि वह file स्वामी के अलावा किसी और के लिए पढ़ने योग्य है, तो Traefik उसका उपयोग करने से मना कर देता है, और 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 600

एक directory mount करें और Traefik को स्वयं file बनाने दें। यदि आप इसे पहले touch के साथ बनाते हैं, तो यह आपके umask को inherit कर लेता है, और अधिकांश लोग इसी तरह इस त्रुटि का सामना करते हैं।

तीनों के लिए एक बात समान है। HTTP-01 challenge के लिए internet से port 80 तक पहुँच आवश्यक है, क्योंकि certificate authority वापस उसी से जुड़ती है। केवल 443 open करने पर issuance इस तरह विफल हो जाता है जैसे कि यह DNS की कोई त्रुटि हो।

तीन अलग-अलग configs में एक ही दो-app routing कार्य

कार्य: app.example.com को 127.0.0.1:8080 पर स्थित एक service पर भेजना, files.example.com को 127.0.0.1:8081 पर स्थित service पर भेजना, दोनों HTTPS के माध्यम से। यहाँ प्रत्येक proxy के लिए पूरी प्रक्रिया दी गई है, ताकि verbosity का अंतर स्पष्ट रूप से दिखाई दे।

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;
    }
}

इसके बाद इसे link करें, test करें, reload करें और certificate जोड़ें।

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.com

nginx -t के साथ syntax is ok और test is successful को print करना वह जांच है जिसे हर reload से पहले चलाना चाहिए। दूसरा app वही block है जिसमें hostname और port बदल दिए गए हैं। proxy_set_header lines केवल सजावट नहीं हैं: जब proxy_pass किसी address का नाम देता है, तो nginx डिफ़ॉल्ट रूप से Host: 127.0.0.1:8080 को upstream भेजता है। इसलिए, जो app Host header से absolute URLs बनाता है, वह आपके users को localhost पर भेज देगा। उन चार headers में से प्रत्येक का क्या उद्देश्य है, और proxy_pass पर trailing slash चुपचाप उस path को कैसे बदल देता है जो आपके app को प्राप्त होता है, इसे nginx server block के इस walkthrough में directive-दर-directive समझाया गया है।

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 caddy

यह पूरी file है। reverse_proxy स्वयं X-Forwarded-For, X-Forwarded-Proto और X-Forwarded-Host को set करता है। डिफ़ॉल्ट रूप से, यह उन headers में client द्वारा भेजी गई किसी भी जानकारी को अनदेखा कर देता है, ताकि कोई request आपके backend को यह झूठ न बोल सके कि वह कहाँ से आई है। Certificates, port 80 redirect और renewal सभी दो site addresses से स्वतः हो जाते हैं। file में इनके लिए कुछ और लिखने की आवश्यकता नहीं है।

Traefik

Traefik को कुछ भी route करने से पहले static configuration की आवश्यकता होती है। एक Compose service के रूप में, अगस्त 2026 तक के current image tag के साथ:

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:/letsencrypt

इसके बाद प्रत्येक application अपनी routing को अपनी compose file में labels पर रखती है:

    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 container के अंदर का port है, न कि published port, क्योंकि Traefik एक shared Docker network के माध्यम से container तक पहुँचता है। App को किसी भी ports: line की आवश्यकता नहीं होती है, और यही इसका वास्तविक लाभ है: केवल Traefik ही published होता है। Shared network और redirect middleware सहित पूरा build, Traefik और Docker Compose के साथ कई apps को route करने के लेख में उपलब्ध है।

प्रत्येक अतिरिक्त app के लिए configuration की लागत कितनी है?

ChartNon-blank config lines for the same two-app routing job
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
  }
]

ऊपर दिए गए blocks से गणना करें। Nginx server block में 11 non-blank lines होती हैं, और आपको हर hostname के लिए इसे फिर से लिखना पड़ता है। Caddy site block में 3 lines होती हैं। Traefik को पहली request serve करने से पहले 17 lines की static configuration चाहिए होती है, और उसके बाद प्रत्येक app के लिए 5 labels की आवश्यकता होती है।

तुलना के लाभ और हानि को समझें, न कि केवल विजेता को। Traefik की लागत पहले app से पहले सबसे अधिक होती है और उसके बाद प्रत्येक app के लिए सबसे कम, और ये दोनों कुल योग लगभग तीसरी site पर बराबर हो जाते हैं। उससे कम sites के लिए, static configuration एक अनावश्यक overhead है। उससे अधिक sites के लिए, labels बेहतर साबित होते हैं क्योंकि routing उस service के साथ ही रहती है जिसे वह route करती है। service को delete करने पर उसका route भी हट जाता है, जो कि एक केंद्रीय configuration file की सबसे बड़ी कमी है: उन apps के लिए पुराने server blocks का पड़े रहना जो महीनों पहले बंद हो चुके हैं।

line count Nginx के पक्ष में दिखती है, लेकिन यह पूरी सच्चाई नहीं है। उन blocks में से प्रत्येक के लिए एक symlink, एक nginx -t, एक reload और एक certbot run की आवश्यकता होती है, जबकि Caddy के बदलाव के लिए केवल एक reload और Traefik के बदलाव के लिए किसी command की आवश्यकता नहीं होती। तीनों ही live connections को drop किए बिना reload हो जाते हैं। असली अंतर उन अलग-अलग steps की संख्या में है जिन्हें आपको रात के एक बजे याद रखना पड़ता है।

आपके containers के बारे में किसे जानकारी होती है?

Traefik Docker socket को monitor करता है और containers के start या stop होने पर उनके labels से routers बनाता है। यहाँ कोई अन्य tool ऐसा नहीं करता है। Nginx और Caddy दोनों को नए container के आने पर configuration edit और reload की आवश्यकता होती है, और उन्हें एक ऐसे address की जरूरत होती है जहाँ तक वे पहुँच सकें: या तो loopback पर published कोई port, या proxy से जुड़ा एक shared Docker network।

इस feature की एक कीमत है, और इसे स्पष्ट रूप से बताना आवश्यक है। Traefik /var/run/docker.sock को read करता है। जो कोई भी उस socket से बात कर सकता है, वह host filesystem को अंदर mount करके एक container start कर सकता है, जो host पर root access के बराबर है। इसे read-only mount करने से जोखिम कम हो जाता है, लेकिन पूरी तरह खत्म नहीं होता। यदि यह आपके threat model के लिए महत्वपूर्ण है, तो बीच में एक socket proxy लगाएँ जो केवल उन container list endpoints को expose करे जिनकी Traefik को आवश्यकता है।

Caddy एक community plugin के माध्यम से label-based discovery कर सकता है, लेकिन Caddy plugins को compile किया जाता है, इसलिए आपको एक custom binary या xcaddy के साथ एक custom image बनानी होगी और फिर उस build व उसके updates की जिम्मेदारी आपकी होगी। तीन या चार services के लिए, Caddyfile को edit करना कम मेहनत का काम है।

Websockets और स्ट्रीमिंग: क्या खराब होता है और क्यों

Nginx को सहायता की आवश्यकता होती है। एक WebSocket कनेक्शन HTTP अनुरोध के रूप में शुरू होता है जिसमें Upgrade: websocket होता है, और जब तक आप निर्देश न दें, nginx hop-by-hop हेडर को अपस्ट्रीम नहीं भेजता है।

# /etc/nginx/conf.d/upgrade-map.conf
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

इसके बाद, location ब्लॉक के अंदर, तीन लाइनें होनी अनिवार्य हैं:

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;

यदि आप इन्हें छोड़ देते हैं, तो ब्राउज़र कंसोल WebSocket connection to 'wss://app.example.com/ws' failed प्रिंट करता है जबकि आपका बैकएंड लॉग एक सामान्य GET दिखाता है। map इसलिए मौजूद है क्योंकि एक हार्डकोडेड Connection: upgrade हर अनुरोध पर भेजा जाएगा, जिसमें वे सामान्य अनुरोध भी शामिल हैं जिन्हें close कहना चाहिए।

Nginx की दो और डिफॉल्ट सेटिंग्स समस्या पैदा करती हैं। proxy_read_timeout 60 सेकंड है और यह अपग्रेड के बाद टनल पर लागू होता है, इसलिए बिना ट्रैफिक वाला वेबसॉकेट एक मिनट बाद प्रॉक्सी द्वारा बंद कर दिया जाता है। और सर्वर-सेंट इवेंट्स (SSE) तब तक देर से या टुकड़ों में आते हैं जब तक आप उस लोकेशन पर proxy_buffering off; सेट नहीं करते, क्योंकि जब तक आपका पेज रिस्पॉन्स का इंतज़ार करता है, nginx उसे अपने बफर में रोक कर रखता है।

Caddy अपग्रेड को निष्पादित करता है और बिना किसी निर्देश के कनेक्शन को टू-वे टनल में बदल देता है। यह रिस्पॉन्स के text/event-stream होने या उसकी लंबाई ज्ञात न होने पर तुरंत डेटा भेज देता है, इसलिए स्ट्रीमिंग बिना किसी बदलाव के काम करती है। Traefik अपग्रेड्स को पास करता है और रिस्पॉन्स को बफर नहीं करता, जब तक कि आप स्वयं उसका buffering मिडलवेयर न जोड़ें। यदि आपकी सेवाओं में चैट, वेब टर्मिनल, लॉग टेल्स या लाइव डैशबोर्ड शामिल हैं, तो यह एक बड़ा अंतर है कि आपको कितनी कॉन्फ़िगरेशन लिखनी और डीबग करनी होगी।

पूर्ण Nginx सर्वर ब्लॉक, वेबसॉकेट और 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 को http संदर्भ में होना चाहिए, न कि server के अंदर, इसलिए इसे /etc/nginx/conf.d/ के तहत अपनी फाइल में रखें। proxy_buffering को केवल उन लोकेशन्स पर बंद करें जो स्ट्रीम करते हैं, क्योंकि बफरिंग ही वह सुविधा है जो nginx को सामान्य रिस्पॉन्स पर बैकएंड वर्कर को जल्दी रिलीज करने की अनुमति देती है। जब आप Certbot चलाते हैं तो वह इस ब्लॉक को फिर से लिखता है, इसलिए बाद में फाइल को दोबारा पढ़ें।

जब आपको कुछ असामान्य चाहिए हो तो क्या होता है?

यहीं पर Nginx अपनी अतिरिक्त लाइनों की सार्थकता सिद्ध करता है।

  • Client certificates, जिन्हें mTLS (mutual TLS) भी कहा जाता है, जहाँ client को भी एक certificate प्रस्तुत करना होता है। Nginx के लिए server block में ssl_client_certificate /etc/ssl/ca.pem; और ssl_verify_client on; की आवश्यकता होती है। Caddy के लिए tls के भीतर एक client_auth block चाहिए। Traefik labels इसे पूरी तरह से व्यक्त नहीं कर सकते: आपको file provider में एक TLS option परिभाषित करना होगा और traefik.http.routers.app.tls.options=mtls@file के साथ router को उसकी ओर निर्देशित करना होगा। जब आपको पहली बार इसकी आवश्यकता होती है, तो 'सब कुछ labels में' वाला मॉडल एक अपवाद बन जाता है।
  • Large uploads. Nginx डिफ़ॉल्ट रूप से request bodies को 1 MB पर सीमित करता है। बड़ा upload होने पर 413 Request Entity Too Large error मिलता है, और error log में client intended to send too large body दिखाई देता है। client_max_body_size को बढ़ाएं। Caddy और Traefik डिफ़ॉल्ट रूप से कोई body limit सेट नहीं करते हैं, इसलिए request सीधे आपके app तक पहुँचती है और limit का निर्णय आपका app ही करता है।
  • Response caching. Nginx में proxy_cache है, और यह काफी परिपक्व है। Caddy के लिए एक plugin को compile करना पड़ता है। Traefik के open source build में कोई HTTP cache नहीं होता है, जो उन लोगों को हैरान करता है जो यह मान लेते हैं कि हर proxy caching करता है।
  • Raw TCP या UDP, database port या game server के लिए। Nginx में stream module है। Traefik के पास अपने स्वयं के entrypoints पर TCP और UDP routers हैं। Caddy को एक और plugin की आवश्यकता होती है, जिसके लिए एक और custom build चाहिए।
  • Proxy के पीछे पहले से मौजूद web server. यदि service एक classic PHP application है, तो Ubuntu 24.04 पर LAMP stack में पहले से ही Apache शामिल है। इसके आगे proxy लगाने से आपको दो ऐसे स्थान मिल जाते हैं जहाँ headers सेट किए जा सकते हैं और URL rewrite किया जा सकता है। तय करें कि TLS termination कहाँ करना है, और दूसरे को loopback पर bound plain HTTP पर रखें।

इस विकल्प के बाद आने वाली फायरवॉल की समस्या

रिवर्स प्रॉक्सी का मुख्य उद्देश्य केवल 80 और 443 पोर्ट को खुला रखना है। Docker चुपचाप इसे निष्प्रभावी कर देता है। -p 8080:80 के साथ पोर्ट पब्लिश करने पर यह nat टेबल में एक DNAT नियम लिख देता है। यह नियम ufw द्वारा प्रबंधित INPUT नियमों से पहले लागू होता है, इसलिए ufw deny 8080 इसे ब्लॉक नहीं करता है। परिणामस्वरूप, आपका ऐप उस प्रॉक्सी के साथ सार्वजनिक इंटरनेट पर खुला रहता है जिसे आपने बहुत सावधानी से कॉन्फ़िगर किया था। पब्लिश किए गए पोर्ट्स को 127.0.0.1:8080:80 के साथ लूपबैक पर बाइंड करें, या ports: का उपयोग पूरी तरह बंद कर दें और प्रॉक्सी को Docker नेटवर्क के माध्यम से कंटेनर तक पहुँचने दें, जैसा कि ऊपर दिए गए Traefik उदाहरण में किया गया है। इसकी कार्यप्रणाली और समाधान Docker द्वारा पब्लिश किए गए पोर्ट्स ufw को क्यों बायपास करते हैं में दिए गए हैं।

इसे किसी ऐसी मशीन से टेस्ट करें जो VPS न हो, क्योंकि सर्वर पर ही किया गया चेक हमेशा सफल रहता है:

curl --max-time 5 http://your.server.address:8080

Connection refused या टाइमआउट ही वह परिणाम है जो आप चाहते हैं। HTTP रिस्पॉन्स का मतलब है कि ऐप आपकी प्रॉक्सी से गुजरे बिना ही एक्सेस किया जा सकता है, और ऊपर कॉन्फ़िगर की गई सभी चीजें केवल दिखावा हैं।

आपको कौन सा प्रॉक्सी चुनना चाहिए?

ज्यादातर स्टैटिक साइट्स, और साथ में एक या दो ऐप्स: Caddy। Automatic HTTPS आपके सबसे बड़े आवर्ती काम को खत्म कर देता है। इसका कॉन्फ़िगरेशन इतना छोटा रहता है कि एक स्क्रीन में पढ़ा जा सकता है, और एक स्टैटिक साइट के लिए एक ही साइट ब्लॉक के अंदर एक root लाइन और एक file_server लाइन काफी होती है। इसकी कीमत यह है कि जब कुछ अजीब समस्या आती है, तो इंटरनेट पर कॉपी-पेस्ट करने के लिए समाधान कम मिलते हैं।

एक docker-compose होमलैब जिसमें आप लगातार नई चीजें जोड़ते हैं: Traefik। तीसरी सर्विस के बाद, एक केंद्रीय फ़ाइल को एडिट करने की तुलना में labels का उपयोग करना कम मेहनत का काम है, और एक डिलीट की गई सर्विस अपने रूट को भी साथ ले जाती है। पहले सेटअप के लिए एक दोपहर का समय रखें, क्योंकि entrypoints, routers, services और middlewares सभी नई शब्दावली हैं। लेबल में टाइपिंग की गलती होने पर Traefik आमतौर पर 404 एरर दिखाता है, न कि सर्विस स्टार्ट होने में विफलता, इसलिए यह मानने से पहले कि ऐप खराब है, पार्स एरर के लिए docker logs traefik को पढ़ें।

मौजूदा Nginx कॉन्फ़िगरेशन, या ऊपर दी गई सूची में से कोई भी आवश्यकता: Nginx। इसमें रिस्पॉन्स कैशिंग और क्लाइंट सर्टिफिकेट के लिए पहले से ही समाधान मौजूद हैं, और लगभग हर थर्ड-पार्टी गाइड इसी को आधार मानकर लिखी गई है। इसकी कीमत यह है कि सर्टिफिकेट और वेबसॉकेट सपोर्ट ऐसी चीजें हैं जिन्हें आपको खुद कॉन्फ़िगर करना पड़ता है, वे अपने आप नहीं मिलते।

आप जो भी चुनें, एक नियम हमेशा लागू होता है। पब्लिक इंटरफ़ेस पर केवल एक ही प्रोसेस लिसन (listen) करनी चाहिए, और बाकी सब कुछ लूपबैक या प्राइवेट Docker नेटवर्क पर लिसन करना चाहिए।

FAQ

एक VPS पर कुछ Docker apps के लिए कौन सा reverse proxy सबसे अच्छा है?

तीन या चार ऐसी services के लिए जिन्हें आप कभी-कभार जोड़ते हैं, Traefik सबसे उपयुक्त है, क्योंकि प्रत्येक app में उसकी अपनी routing labels होती हैं और किसी केंद्रीय फाइल को edit करने की आवश्यकता नहीं होती। यदि services स्थिर हैं और आप मुख्य रूप से HTTPS की जटिलता से बचना चाहते हैं, तो Caddy को सीखना आसान है और इसमें गड़बड़ी की संभावना कम है। Nginx तब चुनें जब आप पहले से ही इसे जानते हों, या जब आपको किसी ऐसे feature की आवश्यकता हो जो अन्य दो में नहीं है, जैसे कि response caching या plain TCP listener।

क्या Caddy को वास्तव में किसी certificate configuration की आवश्यकता नहीं है?

सामान्य मामलों में, हाँ। एक public hostname को site address के रूप में लिखना ही पूरी configuration है: Caddy ACME के माध्यम से certificate का अनुरोध करता है, port 80 से redirect serve करता है, और expiry से पहले उसे renew कर देता है। दो शर्तें पूरी होनी चाहिए। HTTP-01 challenge के लिए internet से port 80 तक पहुँच होनी चाहिए, और hostname का DNS A या AAAA record पहले से ही VPS पर point करना चाहिए, क्योंकि certificate authority नाम को resolve करती है और वापस उसी पर connect करती है।

क्या मैं एक ही VPS पर Nginx और Traefik चला सकता हूँ?

एक ही ports पर नहीं। जो भी बाद में start होगा वह bind होने में विफल हो जाएगा, और Nginx bind() to 0.0.0.0:443 failed (98: Address already in use) error देगा, जबकि Traefik भी इसी तरह का bind error लॉग करेगा और बंद हो जाएगा। एक proxy को 80 और 443 पर चलाएं, और बाकी सब कुछ उसके पीछे रखें। यदि आप migrate कर रहे हैं, तो hostnames को एक-एक करके move करें: जब तक आखिरी site move न हो जाए, तब तक front proxy को loopback port पर पुरानी service तक traffic forward करने दें।

Nginx के पीछे मेरे websockets 60 seconds के बाद क्यों बंद हो जाते हैं?

proxy_read_timeout का default मान 60 seconds है और यह upgrade पूरा होने के बाद tunnel पर लागू होता है, इसलिए एक मिनट तक traffic न होने पर connection को आपके app के बजाय proxy द्वारा बंद कर दिया जाता है। इसे उस location पर proxy_read_timeout 3600s; के साथ बढ़ाएं, या application से हर 30 seconds में एक ping frame भेजें। Caddy और Traefik एक मिनट के timer पर idle upgraded connections को बंद नहीं करते हैं, यही कारण है कि वही app उनके पीछे स्थिर रह सकता है और Nginx के पीछे अस्थिर हो जाता है।