Caddy Docker Reverse Proxy: ऑटोमैटिक HTTPS के साथ Compose सेटअप
Caddy को Docker reverse proxy के रूप में चलाएँ: एक compose स्टैक, साझा नेटवर्क, सर्विस नामों पर reverse_proxy और ऑटोमैटिक HTTPS, साथ ही caddy-docker-proxy लेबल कब काम आते हैं।
संक्षेप में: Caddy को उसके अपने कंटेनर में चलाएँ जो पोर्ट 80 और 443 पब्लिश करे, उसे और अपने ऐप कंटेनरों को एक साझा Docker नेटवर्क से जोड़ें, और `reverse_proxy` को हर सर्विस नाम और आंतरिक पोर्ट की ओर पॉइंट करें (जैसे `reverse_proxy app:3000`)। Caddy Docker के बिल्ट-इन DNS से नाम resolve करता है और हर साइट एड्रेस के लिए TLS सर्टिफ़िकेट अपने-आप ले लेता है।
यह गाइड पहले सादा Caddyfile तरीका दिखाता है, फिर लेबल-आधारित caddy-docker-proxy वैरिएंट, और समझाता है कि एक VPS पर कौन-सा कब ठीक बैठता है। अगर आप Caddy को Docker के बजाय सीधे होस्ट पर चलाते हैं, तो मूल Caddy reverse proxy गाइड देखें।
हिस्से आपस में कैसे जुड़ते हैं
सिर्फ़ Caddy कंटेनर ही बाहरी दुनिया के लिए पोर्ट पब्लिश करता है। हर बैकएंड कंटेनर एक user-defined bridge नेटवर्क (यहाँ `web`) से जुड़ता है और अपना पोर्ट सिर्फ़ उसी नेटवर्क पर expose करता है। User-defined नेटवर्क पर उपलब्ध Docker का बिल्ट-इन DNS सर्वर Caddy को सर्विस या कंटेनर नाम से `app:3000` तक पहुँचने देता है, इसलिए आपको कभी कंटेनर IP हार्ड-कोड नहीं करने पड़ते जो हर recreate पर बदल जाते हैं।
बैकएंड को अनपब्लिश्ड रखना जितना लगता है उससे ज़्यादा अहम है: Docker अपने iptables नियम ख़ुद लिखता है, इसलिए `ports:` से पब्लिश किया गया पोर्ट इंटरनेट से पहुँच में हो सकता है, भले ही ufw उसे ब्लॉक बताए। जो कुछ भी प्रॉक्सी के पीछे होना चाहिए, उसके लिए `expose:` इस्तेमाल करें या कोई पोर्ट मैपिंग न करें।
| कंपोनेंट | भूमिका | होस्ट पर पब्लिश? |
|---|---|---|
| caddy कंटेनर | TLS टर्मिनेशन, होस्टनेम से रूटिंग, HTTP से HTTPS रीडायरेक्ट | हाँ: 80/tcp, 443/tcp, 443/udp |
| web नेटवर्क | सर्विस नामों के लिए बिल्ट-इन DNS वाला साझा bridge नेटवर्क | नहीं |
| ऐप कंटेनर | आपकी सर्विसें (वेब ऐप, API, डैशबोर्ड) | नहीं, सिर्फ़ Caddy के ज़रिए पहुँच |
| caddy_data वॉल्यूम | सर्टिफ़िकेट, प्राइवेट कीज़, ACME अकाउंट | नहीं, लेकिन स्थायी रहना ज़रूरी |
स्टेप-बाय-स्टेप: docker compose के साथ सादा Caddyfile
- 01.Caddy शुरू करने से पहले हर होस्टनेम का A रिकॉर्ड (और IPv6 इस्तेमाल करते हों तो AAAA रिकॉर्ड) VPS की ओर पॉइंट करें, वरना सर्टिफ़िकेट जारी नहीं होगा।
- 02.साझा नेटवर्क एक बार बनाएँ: `docker network create web`।
- 03.नीचे दिखाए अनुसार `/opt/proxy/compose.yaml` और `/opt/proxy/Caddyfile` बनाएँ, फिर `/opt/proxy` में `docker compose up -d` चलाएँ।
- 04.हर ऐप स्टैक को बाहरी `web` नेटवर्क से जोड़ें और `docker compose up -d` से शुरू करें।
- 05.`/opt/proxy` में `docker compose logs -f caddy` से पहला सर्टिफ़िकेट जारी होते देखें।
- 06.Caddyfile एडिट करने के बाद बिना डाउनटाइम के रीलोड करें: `docker compose exec -w /etc/caddy caddy caddy reload`।
# /opt/proxy/compose.yaml
services:
caddy:
image: caddy:2
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data # certificates and ACME account keys
- caddy_config:/config
networks:
- web
volumes:
caddy_data:
caddy_config:
networks:
web:
external: trueऐप जोड़ें और Caddyfile लिखें
हर ऐप्लिकेशन स्टैक वही बाहरी नेटवर्क घोषित करता है। सर्विस का नाम ही वह होस्टनेम बन जाता है जिस पर Caddy कनेक्ट करता है। `caddy_data` वॉल्यूम वह है जिसे आपको कभी नहीं खोना चाहिए: इसे मिटाने पर Caddy को हर सर्टिफ़िकेट दोबारा माँगना पड़ता है, जिससे ACME रेट लिमिट लग सकती है।
# /opt/app/compose.yaml
services:
app:
image: ghcr.io/example/app:latest
restart: unless-stopped
expose:
- "3000" # reachable on the network, NOT published on the host
networks:
- web
networks:
web:
external: true
# /opt/proxy/Caddyfile
{
email [email protected]
}
app.example.com {
reverse_proxy app:3000
}
grafana.example.com {
reverse_proxy grafana:3000
}
api.example.com {
reverse_proxy api-1:8080 api-2:8080 {
lb_policy round_robin
health_uri /healthz
health_interval 10s
}
}Caddy बैकएंड: upstream, लोड बैलेंसिंग और हेल्थ चेक
Caddy की भाषा में बैकएंड `reverse_proxy` का एक upstream है। आप एक ही डायरेक्टिव में कई upstream लिख सकते हैं, `round_robin`, `least_conn` या `ip_hash` जैसी `lb_policy` चुन सकते हैं, और `health_uri` से active हेल्थ चेक जोड़ सकते हैं ताकि विफल कंटेनर रोटेशन से बाहर हो जाएँ। जब ऐप में हेल्थ एंडपॉइंट न हो, तो passive चेक (`fail_duration`, `max_fails`) भी काम आते हैं।
Caddy डिफ़ॉल्ट रूप से प्रॉक्सी की गई रिक्वेस्ट पर `X-Forwarded-For`, `X-Forwarded-Proto` और `X-Forwarded-Host` सेट करता है। अपने ऐप को प्रॉक्सी के नेटवर्क रेंज पर भरोसा करने के लिए कॉन्फ़िगर करें ताकि वह असली क्लाइंट IP देखे और `https://` लिंक बनाए। WebSockets और gRPC बिना अतिरिक्त सेटिंग के `reverse_proxy` से काम करते हैं; cleartext पर gRPC के लिए `reverse_proxy h2c://service:50051` इस्तेमाल करें।
Caddyfile के बजाय लेबल: caddy-docker-proxy
"Caddy proxy manager" खोजने वाले लोग आमतौर पर वही चाहते हैं जो Nginx Proxy Manager देता है: कंटेनर जोड़ें और किसी केंद्रीय फ़ाइल को एडिट किए बिना होस्टनेम व सर्टिफ़िकेट पाएँ। Caddy का कोई आधिकारिक GUI नहीं है, लेकिन कम्युनिटी प्रोजेक्ट caddy-docker-proxy (github.com/lucaslorentz/caddy-docker-proxy) कंटेनर लेबल से Caddyfile बनाता है और कंटेनर शुरू या बंद होने पर Caddy रीलोड करता है।
इसे Docker socket तक read एक्सेस चाहिए, जो व्यावहारिक रूप से होस्ट पर root के बराबर है। उसे read-only माउंट करें, प्रॉक्सी इमेज अपडेट रखें, और अगर आप सिर्फ़ गिनी-चुनी सर्विसें चलाते हैं तो सादा Caddyfile ही चुनें।
services:
caddy:
image: lucaslorentz/caddy-docker-proxy:ci-alpine
restart: unless-stopped
ports:
- "80:80"
- "443:443"
environment:
- CADDY_INGRESS_NETWORKS=web
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- caddy_data:/data
networks:
- web
whoami:
image: traefik/whoami
networks:
- web
labels:
caddy: whoami.example.com
caddy.reverse_proxy: "{{upstreams 80}}"
volumes:
caddy_data:
networks:
web:
external: trueसादा Caddyfile बनाम caddy-docker-proxy
| सादा Caddyfile | caddy-docker-proxy लेबल | |
|---|---|---|
| कॉन्फ़िगरेशन कहाँ रहता है | एक फ़ाइल जिसे आप git में वर्ज़न करते हैं | compose फ़ाइलों में बिखरे लेबल |
| Docker socket एक्सेस | ज़रूरी नहीं | ज़रूरी (सुरक्षा के लिहाज़ से संवेदनशील) |
| नई सर्विस | Caddyfile एडिट करें, `caddy reload` चलाएँ | लेबल जोड़ें, कंटेनर शुरू करें |
| इमेज | आधिकारिक `caddy:2` | Caddy पर बनी कम्युनिटी इमेज |
| डीबगिंग | फ़ाइल सीधे पढ़ें | लॉग में जनरेट हुआ कॉन्फ़िग देखें |
| सबसे उपयुक्त | छोटे, स्थिर VPS सेटअप | कई अल्पकालिक या बार-बार बदलने वाली सर्विसें |
VPS पर चलाना
NoctisNode KVM VPS पर आपको पूरा root और डेडिकेटेड IPv4 मिलता है, इसलिए एक Caddy कंटेनर से 80 और 443 पब्लिश करना और बाक़ी सब छिपाना आसान है। Caddy और कुछ हल्के कंटेनरों के लिए Wisp (1 vCPU, 1 GB RAM) काफ़ी है; भारी स्टैक Pulse या Umbra पर फ़िट होते हैं। सर्टिफ़िकेट जारी होने का ब्योरा और विफलता के कारण Caddy ऑटोमैटिक HTTPS कैसे काम करता है में हैं, और raw TCP या SSH फ़ॉरवर्डिंग Caddy से TCP और SSH प्रॉक्सी में। होस्ट SSH को SSH हार्डनिंग गाइड से सुरक्षित करें।
अक्सर पूछे जाने वाले सवाल
QCaddy से Docker कंटेनर तक reverse proxy कैसे करें?
ACaddy और कंटेनर को एक ही user-defined Docker नेटवर्क पर रखें और Caddyfile में `reverse_proxy service-name:port` इस्तेमाल करें। `localhost` इस्तेमाल न करें, क्योंकि Caddy कंटेनर के अंदर वह ख़ुद Caddy को दर्शाता है।
Qमेरे कंटेनर के लिए Caddy 502 Bad Gateway क्यों लौटाता है?
Aआमतौर पर कंटेनर साझा नेटवर्क पर नहीं होते, पोर्ट ग़लत होता है (कंटेनर का आंतरिक पोर्ट इस्तेमाल करें, पब्लिश किया होस्ट पोर्ट नहीं), या ऐप अपने कंटेनर में सिर्फ़ 127.0.0.1 पर listen करता है। ऐप को 0.0.0.0 पर bind कराएँ और `docker network inspect web` जाँचें।
Qक्या caddy-docker-proxy इस्तेमाल करना सुरक्षित है?
Aयह अच्छा काम करता है, लेकिन इसे Docker socket चाहिए, जो होस्ट पर root के बराबर नियंत्रण देता है। उसे read-only माउंट करें, इमेज अपडेट रखें और Caddy admin एंडपॉइंट को एक्सपोज़ करने से बचें।
QDocker में Caddy सर्टिफ़िकेट कहाँ स्टोर करता है?
Aआधिकारिक इमेज के अंदर `/data` में, इसलिए वहाँ एक named वॉल्यूम माउंट करें। इसे खोने का मतलब है हर सर्टिफ़िकेट दोबारा जारी करवाना और संभवतः ACME रेट लिमिट तक पहुँचना।
Qक्या वेब UI वाला कोई Caddy proxy manager है?
ACaddy का अपना कोई आधिकारिक वेब UI नहीं है; उसे Caddyfile, JSON या admin API से कॉन्फ़िगर किया जाता है। caddy-docker-proxy जैसे लेबल-आधारित टूल 'कंटेनर जोड़ो और चल पड़ो' जैसा मिलता-जुलता वर्कफ़्लो देते हैं।