SSD Nodes Learn Hosting plans →
मार्गदर्शक Matt Connorद्वारे Matt Connor · अपडेटेड 2026-08-30

Traefik सह Docker Compose मध्ये 5 अॅप्स चालवा

Traefik v3 आणि Docker Compose वापरून एकाच IP मागे 5 अॅप्स चालवा. Host नियमांनी routing, स्वयंचलित Let's Encrypt TLS आणि startup रोखणारा acme.json त्रुटीचा उपाय जाणून घ्या.

एक IP, पाच अॅप्स, एक पोर्ट 443

तुमच्या VPS कडे एकच सार्वजनिक IPv4 पत्ता आणि एकच TCP पोर्ट 443 आहे. त्यावर Gitea, तुमच्या अॅपची staging प्रत, अंतर्गत dashboard, status page आणि webhook receiver चालवायचे आहेत. म्हणजे पाच hostnames आणि एकच सर्व्हर. Reverse proxy ही :80 आणि :443 चे नियंत्रण ठेवणारी प्रक्रिया आहे. ती प्रत्येक विनंतीमधील Host header वाचते आणि ती योग्य container कडे पाठवते. Traefik हे काम करते. तसेच तुम्हाला certbot स्वतः चालवण्याची गरज न पडता ते प्रत्येक hostname साठी certificate मिळवते आणि त्याचे renewal करते. Nginx आणि Caddy देखील याच पाच hostnames साठी योग्यरीत्या TLS termination करू शकतात. त्यामुळे निवड अजून निश्चित नसेल, तर सर्वकाही एका proxy शी जोडण्यापूर्वी certificate हाताळणी आणि प्रत्येक अॅपच्या configuration खर्चाच्या आधारावर या तीन proxies ची तुलना करणे उपयुक्त ठरेल.

Traefik आणि nginx मधील server {} block यांच्यातील मुख्य फरक म्हणजे configuration कुठून येते. nginx मध्ये तुम्ही फाइल संपादित करून reload करता. Certificate lifecycle हे स्वतंत्र काम राहते. तुम्ही nginx वर certbot वापरून Let's Encrypt certificates जारी करता तेव्हा हाच workflow वापरला जातो. त्यात renewal timer web server च्या पूर्णपणे बाहेर असतो. Traefik चा Docker provider Docker event stream वर लक्ष ठेवतो आणि तुमच्या containers मधील labels वाचतो. Host() rule label असलेला container सुरू केला की तो एका सेकंदाच्या आत routing साठी उपलब्ध होतो. तो थांबवला की route नाहीसा होतो. हाच त्यातील धोका आहे. Labels मध्ये असलेली configuration एकाच वेळी पाच ठिकाणी विखुरलेली असते. चुकीचा label असल्यास कोणतीही स्पष्ट त्रुटी दिसत नाही. Container कडे फक्त routing होत नाही आणि Traefik काहीही सांगत नाही.

चार संज्ञा

  • Entrypoints म्हणजे listening sockets. तुम्ही दोन निश्चित कराल: web हे :80 वर आणि websecure हे :443 वर.
  • Routers विनंती (Host(...)) जुळवतात आणि ती service शी जोडतात. प्रत्येक router साठी tls.certresolver द्वारे प्रमाणपत्राची विनंती केली जाते.
  • Services म्हणजे backend, एक container आणि Docker network च्या आतील बाजूस तो ऐकत असलेला port.
  • Middlewares router आणि service यांच्या मध्ये कार्य करतात: basic auth, IP allow-lists, header rewrites, redirects.

ही चार संज्ञा Traefik मध्ये अशा कामांसाठी वापरली जातात, जी अन्यथा तुम्हाला स्वतः लिहावी लागली असती: router हा server_name असतो, service हा proxy_pass target असतो आणि middlewares म्हणजे तुम्ही nginx reverse proxy server block ओळीनुसार तयार करताना स्वतः निश्चित केलेले header आणि auth directives असतात.

Static configuration (entrypoints, providers, ACME) Traefik च्या command line वरून किंवा traefik.yml मध्ये दिले जाते. त्यात बदल केल्यास Traefik पुन्हा सुरू करावा लागतो. Dynamic configuration (routers, services, middlewares) container labels मधून येते आणि hot-reload होते. या दोन्ही प्रकारांमध्ये गोंधळ होणे हे "my flag does nothing" याचे नेहमीचे कारण आहे.

Compose फाइल

proxy नावाचे एक सामायिक Docker network हा या रचनेचा आधार आहे. Traefik आणि container दोन्ही या network वर असतील, तरच Traefik त्या container पर्यंत पोहोचू शकतो.

name: edge

networks:
  proxy:
    name: proxy

services:
  traefik:
    image: traefik:v3.5
    restart: unless-stopped
    command:
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --providers.docker.network=proxy
      - --entryPoints.web.address=:80
      - --entryPoints.websecure.address=:443
      - --entryPoints.web.http.redirections.entryPoint.to=websecure
      - --entryPoints.web.http.redirections.entryPoint.scheme=https
      - --certificatesresolvers.le.acme.email=you@example.com
      - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.le.acme.tlschallenge=true
      # while you iterate, point at staging so a mistake costs nothing:
      # - --certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory
      - --api.dashboard=true
      - --log.level=INFO
      - --accesslog=true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.dashboard.rule=Host(`traefik.example.com`)
      - traefik.http.routers.dashboard.entrypoints=websecure
      - traefik.http.routers.dashboard.tls.certresolver=le
      - traefik.http.routers.dashboard.service=api@internal
      - traefik.http.routers.dashboard.middlewares=dashboard-auth
      - traefik.http.middlewares.dashboard-auth.basicauth.users=admin:$$apr1$$REPLACE$$THIS

  gitea:
    image: gitea/gitea:1  # major-only pin keeps this demo copy-pasteable; pin an exact release in production
    restart: unless-stopped
    volumes:
      - ./gitea:/data
    networks:
      - proxy
    labels:
      - traefik.enable=true
      - traefik.http.routers.gitea.rule=Host(`git.example.com`)
      - traefik.http.routers.gitea.entrypoints=websecure
      - traefik.http.routers.gitea.tls.certresolver=le
      - traefik.http.services.gitea.loadbalancer.server.port=3000

docker compose up -d, त्यानंतर docker compose logs -f traefik. प्रत्येक अतिरिक्त अॅपसाठी gitea block ची प्रत तयार करा. त्याला स्वतंत्र router name, स्वतंत्र Host() आणि स्वतंत्र अंतर्गत port द्या. TLS आणि backups सह Docker मध्ये चालणारे Nextcloud install याच पद्धतीने जोडा. त्याचे published ports काढून टाका, ते proxy शी जोडा आणि hostname व certificate हाताळण्यासाठी router labels वापरा.

या रचनेतील पाच तपशील महत्त्वाचे आहेत.

exposedByDefault=false असल्यामुळे traefik.enable=true असलेला container येईपर्यंत तो Traefik साठी अदृश्य राहतो. हे वगळल्यास, तुम्ही नंतर सुरू केलेल्या प्रत्येक container साठी, एखादी गोष्ट तपासण्यासाठी सुरू केलेल्या तात्पुरत्या postgres सहित, route तयार होईल.

Container अनेक networks शी जोडलेला असल्यास providers.docker.network=proxy Traefik ला कोणते network वापरायचे ते सांगते. हे वगळल्यास Traefik चुकीचा container IP निवडू शकतो. त्याचा परिणाम application fault सारखा दिसणारा 502 होतो.

loadbalancer.server.port=3000 हा container च्या आतील port साठी आहे; Gitea तिथे 3000 वर ऐकते. कोणताही app container port publish करत नाही, हे लक्षात घ्या. फक्त Traefik port publish करतो.

web entrypoint वरील redirect plaintext विनंत्यांना HTTPS कडे 308 मध्ये रूपांतरित करतो. Port 80 तरीही सुरू ठेवावा लागतो: ACME HTTP challenge साठी तो आवश्यक आहे आणि bare hostname टाइप करणाऱ्या वापरकर्त्यांसाठीही तो आवश्यक आहे.

Basic-auth hash मधील दुहेरी $$ हे Compose escaping आहे; ती चूक नाही. ते htpasswd -nbB admin 'your-password' ने तयार करा (package apache2-utils), त्यानंतर प्रत्येक $ दुप्पट करा.

प्रमाणपत्र आणि acme.json चा सापळा

tlschallenge=true TLS-ALPN-01 निवडते: Let's Encrypt तुमच्या box वरील 443 पोर्टशी जोडते आणि TLS handshake दरम्यान Traefik challenge चे उत्तर देतो. दुसरा पर्याय HTTP-01 आहे. तो port 80 वर चालतो. Traefik च्या command: यादीतील tlschallenge ओळ या दोन ओळींनी बदला:

      - --certificatesresolvers.le.acme.httpchallenge=true
      - --certificatesresolvers.le.acme.httpchallenge.entrypoint=web

दोन्ही पर्याय कार्य करतात. दोन्हींसाठी hostname साठीचा public DNS आधीच तुमच्या VPS कडे निर्देशित असणे आवश्यक आहे. Certificate authority ने हे नाव resolve करून बाहेरून जोडले पाहिजे. प्रथम A (आणि AAAA) record तयार करा. dig +short git.example.com ने पडताळणी करा. त्यानंतर Traefik सुरू करा.

आता लोकांचा संपूर्ण संध्याकाळचा वेळ घेणारा सापळा पाहू. Traefik त्याची ACME account key आणि जारी केलेली प्रत्येक प्रमाणपत्रे एका acme.json मध्ये ठेवतो. या फाइलला group किंवा world read permission असल्यास Traefik यासारखी ओळ दाखवतो आणि थांबतो:

error: unable to get ACME account: permissions 644 for /letsencrypt/acme.json are too open, please use 600

वर दिलेला उपायच योग्य आहे: directory bind-mount करा आणि योग्य mode सह फाइल Traefik ला स्वतः तयार करू द्या. touch वापरून acme.json तयार केले असल्यास, तुमच्या umask मुळे त्याचा mode 644 झाला. Host वर तो दुरुस्त करा:

chmod 600 ./letsencrypt/acme.json
docker compose restart traefik

त्या directory चा backup तुमच्या app volumes सोबत घ्या. ती गमावल्यास पुनर्प्राप्ती शक्य आहे आणि प्रमाणपत्रे पुन्हा जारी करता येतात. मात्र एकाच वेळी पाच hostname साठी प्रमाणपत्रे पुन्हा जारी केल्यास rate limits लागू होऊ शकतात.

तुम्ही configuration बदलत असताना staging CA वापरा. caserver ओळ uncomment करा. सर्व route कार्यरत झाल्यावर ती पुन्हा comment करा आणि acme.json हटवा, जेणेकरून production प्रमाणपत्रांसाठी नव्याने विनंती केली जाईल. Production Let's Encrypt समान hostname संचासाठी दर आठवड्याला पाच duplicate प्रमाणपत्रांना परवानगी देते. तसेच त्याच नावासाठी वारंवार अयशस्वी validation झाल्यास विनंत्यांवर मर्यादा आणते. Staging अविश्वसनीय प्रमाणपत्रे जारी करते. तुमचा browser warning दाखवतो. ही warning प्रक्रिया यशस्वी झाल्याचे संकेत देते आणि staging च्या मर्यादा तुलनेने खूप सैल असतात.

डॅशबोर्ड हे नियंत्रणाचे साधन आहे, डेमो नाही

बहुतेक quickstart मध्ये --api.insecure=true सेट केले जाते. त्यामुळे authentication शिवाय डॅशबोर्ड port 8080 वर उपलब्ध होतो. सार्वजनिक IP असलेल्या सर्व्हरवरून कोणीही scan केल्यास तुमची routing topology, hostnames, middleware names आणि backend ports त्याला दिसतात.

वरील traefik सेवेवरील labels हा पर्याय दाखवतात: डॅशबोर्ड इतर कोणत्याही अॅपप्रमाणे, वास्तविक hostname वर, TLS द्वारे आणि basicauth च्या मागे route केला जातो. service=api@internal router ला Traefik च्या built-in API शी जोडते. IP allow-list डावीकडून उजवीकडे लागू करून सुरक्षा आणखी कडक करा. तुमचा office address dynamic असल्यास, त्याच VPS वर self-host केलेल्या WireGuard VPN ने दिलेल्या subnet ची range सेट करा आणि डॅशबोर्डपर्यंत फक्त tunnel द्वारे पोहोचा:

- traefik.http.middlewares.office.ipallowlist.sourcerange=10.0.0.7/32
- traefik.http.routers.dashboard.middlewares=office,dashboard-auth

पाच अॅप्सना स्वतंत्र accounts आवश्यक असताना एकच basicauth password वापरणे योग्य ठरत नाही. त्याच middleware slot मध्ये forwardauth वापरता येते. ते authentication चा निर्णय Authentik या self-hosted single sign-on server कडे सोपवते. त्यामुळे डॅशबोर्ड आणि त्याच्या शेजारील प्रत्येक route एका login मागे राहतो. हा login तुम्ही एका ठिकाणाहून revoke करू शकता.

Docker socket म्हणजे root प्रवेश

/var/run/docker.sock हे असे API आहे की त्याद्वारे host वरून / mount करणारा container तयार करता येतो. त्याला प्रवेश मिळणे म्हणजे मशीनवर root प्रवेश मिळण्यासारखेच आहे. Traefik ला labels वाचण्यासाठी त्याची आवश्यकता असते.

Mount वर :ro कायम ठेवा. मात्र त्याचा परिणाम स्पष्टपणे समजून घ्या: यामुळे socket file read-only होते. त्यावरून Docker API कडे जाणाऱ्या POST विनंत्या थांबत नाहीत. वास्तविक प्रतिबंध म्हणजे Traefik ला socket कधीही न देणे आणि मध्ये filtering proxy ठेवणे:

  dockerproxy:
    image: tecnativa/docker-socket-proxy   # pin the current tag
    restart: unless-stopped
    environment:
      CONTAINERS: 1
      NETWORKS: 1
      POST: 0
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - proxy

Traefik मधून socket volume काढा आणि provider ला proxy कडे निर्देशित करा:

--providers.docker.endpoint=tcp://dockerproxy:2375

Traefik कडे containers आणि networks वाचण्याचा प्रवेश राहतो. मात्र काहीही तयार करण्याची क्षमता त्याच्याकडून काढून घेतली जाते.

Firewall, पोर्ट आणि सर्वजण चुकीचे समजत असलेला नियम

दोन पोर्ट खुले, तसेच SSH:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Docker ने प्रकाशित केलेले पोर्ट ufw चे नियम वगळतात. Docker स्वतःचे iptables नियम समाविष्ट करतो. हे नियम ufw च्या chains पेक्षा आधी लागू होतात. त्यामुळे ports: ["3000:3000"] वापरून सुरू केलेला container, ufw deny नियम तिथे असतानाही, इंटरनेटवरून पोहोचण्यायोग्य राहतो. यावरील उपाय firewall configuration मध्ये नाही, तर रचनेत आहे: पोर्ट फक्त Traefik मधून publish करा आणि इतर प्रत्येक container ला केवळ networks: [proxy] द्या. दुसरे कोणतेही पोर्ट देऊ नका. एखाद्या सेवेला प्रत्यक्षात host पर्यंत पोहोचणे आवश्यक असल्यास, तिला loopback वर bind करा: "127.0.0.1:3000:3000".

समस्यानिवारण: प्रत्यक्षात दिसणाऱ्या त्रुटी

404 page not found, Traefik कडून दिलेले. कोणताही router जुळला नाही. संभाव्य कारणे, अधिक संभाव्यतेपासून क्रमाने: कंटेनरमध्ये traefik.enable=true नाही आणि exposedByDefault=false सेट आहे; Host() नियमात तुम्ही टाइप केलेल्या नावाशी जुळत नाही; एखाद्या label मधील router चे नाव दुसऱ्या label मधील router नावापेक्षा वेगळे आहे (routers.gitea.rule आणि routers.gitea.entrypoints हे एकच शब्द असणे आवश्यक आहे); किंवा hostname भोवती backticks ऐवजी quotes वापरले आहेत. Traefik v3 मध्ये matchers मध्ये backticks आवश्यक आहेत.

502 Bad Gateway. Router जुळला, परंतु backend उपलब्ध नव्हता. जवळजवळ नेहमी कंटेनर proxy network वर नसतो; docker inspect -f '{{json .NetworkSettings.Networks}}' gitea तपासा. दुसरी शक्यता म्हणजे loadbalancer.server.port चुकीचा आहे: तुम्ही published port दिला आहे किंवा अॅप दुसऱ्या ठिकाणी listen करते. प्रयत्नाचा तपशील log मध्ये असतो: dial tcp 172.18.0.5:8080: connect: connection refused.

ब्राउझर इशारा दाखवतो आणि प्रमाणपत्र TRAEFIK DEFAULT CERT ला जारी झालेले आहे. त्या hostname साठी कोणतेही प्रमाणपत्र उपलब्ध नाही आणि Traefik ने self-signed placeholder दिला आहे. ACME ओळी वाचा:

unable to obtain ACME certificate for domains "git.example.com" ...
acme: error: 400 ... DNS problem: NXDOMAIN looking up A for git.example.com

DNS अद्याप त्या box कडे निर्देश करत नाही. Record दुरुस्त करा, TTL संपेपर्यंत प्रतीक्षा करा आणि Traefik पुन्हा सुरू करा.

Invalid response from http://git.example.com/.well-known/acme-challenge/... HTTP challenge वर: port 80 बाहेरून Traefik पर्यंत पोहोचत नाही. याचे सामान्य कारण VPS च्या पुढील provider-level firewall असते; ufw नाही.

प्रमाणपत्रे कधीही जारी होत नाहीत आणि तुमचा DNS Cloudflare वर असून orange cloud सुरू आहे. Cloudflare त्याच्या edge वर TLS termination करते आणि TLS-ALPN-01 त्यामधून पूर्ण होऊ शकत नाही. प्रमाणपत्र जारी करताना record DNS-only करा किंवा API token वापरून DNS-01 challenge वर बदला. Wildcard प्रमाणपत्रे जारी करणारे एकमेव challenge देखील DNS-01 आहे.

Redirect loop. Traefik च्या पुढे असलेली एखादी सेवा आधीच TLS termination करते आणि plaintext ला :80 वर forward करते; entrypoint redirect ते पुन्हा HTTPS कडे पाठवते. दोन्हीपैकी एक redirect काढा.

ते सुरू ठेवणे

Docker चे unit boot वेळी enable केलेले असणे आवश्यक आहे (systemctl is-enabled docker), आणि रीबूटनंतर stack पुन्हा सुरू करण्याचे काम restart: unless-stopped करते. स्पष्ट नियंत्रणासाठी, docker compose -f /srv/edge/compose.yml up -d चालवणारे आणि RemainAfterExit=yes वापरणारे छोटे systemd unit तयार करा. त्यामुळे systemctl status edge आणि सेवा सुरू करण्याच्या क्रमावर नियंत्रण मिळते.

Traefik चा tag निश्चित करा (traefik:v3.5; latest कधीही वापरू नका). v2 ते v3 upgrade मध्ये rule syntax आणि provider names बदलले. त्यामुळे unattended latest आता समजत नसलेली configuration देखील सहजपणे पुन्हा load करू शकतो. Upgrade जाणीवपूर्वक करा: migration notes वाचा, tag बदला, docker compose up -d traefik करा आणि log चे निरीक्षण करा. तुम्ही अजूनही v2 tag वापरत असल्यास, Traefik v2 ते v3 migration guide मध्ये प्रत्येक rename, compatibility mode आणि certificates सुरक्षित ठेवणारी rollback पद्धत दिली आहे.

./letsencrypt आणि प्रत्येक अॅपच्या data volume चा backup घ्या. compose file मधून पुन्हा तयार करता येणार नाही अशी इतर कोणतीही state Traefik कडे साठवलेली नसते.

प्रमाण वाढल्यावर काय बिघडते

पहिली मर्यादा throughput ची नसते; ती single box ची असते: एका VPS वर चालणारा एक Traefik पाच अॅप्ससाठी single point of failure ठरतो आणि acme.json हे flat-file storage असल्यामुळे दोन Traefik instances त्यात लिहिल्यास data corrupt होईल. Scaling out करण्यासाठी certificate storage file मधून बाहेर हलवावे लागते किंवा TLS termination दुसरीकडे करावी लागते.

दुसरी समस्या long-lived connections ची असते. Server-sent events, मोठे uploads आणि slow clients यांना entrypoint चे response timeouts लागू होतात; --entryPoints.websecure.transport.respondingTimeouts.readTimeout आणि त्याचे writeTimeoutidleTimeout siblings हे त्यासाठीचे knobs आहेत. WebSockets कोणत्याही अतिरिक्त configuration शिवाय pass through होतात.

तिसरी समस्या disk ची असते. --accesslog=true stdout वर लिहिते आणि Docker चा json-file driver मर्यादा न घातल्यास ते कायम ठेवतो. Traefik service वर logging.options.max-size सेट करा किंवा access log file मध्ये लिहून त्याचे rotation करा.

यापैकी कोणत्याही गोष्टीसाठी orchestrator आवश्यक नाही. मात्र तुमच्या नियंत्रणाखालील server आवश्यक आहे. त्याला real IP असावा आणि ports 80 व 443 जगासाठी खुले असावेत. एक single small VPS ही संपूर्ण dependency list आहे.

FAQ

Traefik चालवत असताना certbot ची अजूनही गरज आहे का?

नाही. Traefik चा ACME resolver तो ज्या प्रत्येक hostname साठी routing करतो, त्यासाठी प्रमाणपत्राची विनंती करतो आणि त्याचे नूतनीकरण करतो. तसेच तो सर्व प्रमाणपत्रे acme.json मध्ये साठवतो. nginx किंवा इतर server कडूनच TLS termination होत असल्यास certbot हे योग्य साधन राहते. मात्र समान hostnames साठी दोन्ही साधने चालवल्यास Let's Encrypt च्या rate limits व्यर्थ वापरल्या जातात.

माझा container Traefik मार्फत 404 का देतो?

Traefik कडून दिलेला 404 म्हणजे विनंतीशी कोणताही router जुळलेला नाही. container वर traefik.enable=true आहे का ते तपासा. exposedByDefault=false सेट केल्यानंतर ते अनिवार्य असते. Host() मधील value तुम्ही टाइप केलेल्या नावाशी जुळते का ते तपासा. तसेच त्या app साठीच्या प्रत्येक label मध्ये router चे नाव समान आहे का ते पडताळा. Traefik v3 मध्ये matcher च्या आत quotes ऐवजी backticks आवश्यक आहेत.

येथे 404 आणि 502 मध्ये काय फरक आहे?

404 म्हणजे routing झालेले नाही. 502 म्हणजे router जुळला, पण backend ने connection नाकारले. 502 ची नेहमीची कारणे म्हणजे container proxy network ला जोडलेला नसणे आणि loadbalancer.server.port मध्ये app container च्या आत ज्या port वर ऐकते त्या port ऐवजी published port दिलेला असणे. Traefik ने ज्या अचूक address शी connection करण्याचा प्रयत्न केला, तो access log मध्ये दिसतो.

Docker socket read-only पद्धतीने mount करणे पुरेसे आहे का?

:ro flag मुळे socket file read-only होते; त्यामागील API read-only होत नाही. POST requests त्यातून अद्याप पाठवता येतात. Docker API ला access मिळणे म्हणजे host वर root इतके अधिकार मिळणे होय. यापेक्षा सुरक्षित रचना म्हणजे वर दाखवलेला docker-socket-proxy container. तो Traefik ला केवळ container आणि network वाचण्याची परवानगी देतो आणि write operations पूर्णपणे रोखतो.

Traefik wildcard certificate जारी करू शकतो का?

होय, परंतु केवळ DNS-01 challenge द्वारे आणि तुमच्या DNS provider साठीच्या API token सह. TLS-ALPN-01 आणि HTTP-01 प्रत्येकी एका hostname ची पडताळणी करतात; त्यामुळे ते wildcard certificate तयार करू शकत नाहीत. तुमच्या VPS समोर Cloudflare सारखा CDN TLS termination करत असल्यास आणि इतर दोन challenges पूर्ण होत नसल्यास DNS-01 हाच योग्य पर्याय आहे.