SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor · আপডেট করা হয়েছে 2026-08-26

Traefik reverse proxy: এক Compose file-এ 5টি app

Docker Compose-এ Traefik v3 দিয়ে এক IP-তে 5টি app চালান। Host rule-এ routing, স্বয়ংক্রিয় Let's Encrypt TLS এবং startup আটকানো acme.json error এড়ানোর উপায় জানুন।

একটি IP, পাঁচটি অ্যাপ, একটি port 443

আপনার VPS-এ একটি public IPv4 address এবং একটি TCP port 443 আছে। আপনি একই সার্ভারে Gitea, আপনার অ্যাপের একটি staging copy, একটি internal dashboard, একটি status page এবং একটি webhook receiver চালাতে চান—পাঁচটি hostname, একটি সার্ভার। একটি reverse proxy হলো সেই process, যা :80 এবং :443-এর দায়িত্ব নেয়, প্রতিটি request-এর Host header পড়ে এবং সেটিকে সঠিক container-এ পাঠায়। Traefik এটি করে এবং প্রতিটি hostname-এর জন্য certificate সংগ্রহ ও renew করে; আপনাকে কখনো হাতে certbot চালাতে হয় না। Nginx এবং Caddy-ও একই পাঁচটি hostname-এর TLS termination ভালোভাবে করতে পারে। তাই পছন্দ এখনো নির্ধারিত না হলে, সবকিছু একটির সঙ্গে সংযুক্ত করার আগে certificate handling এবং প্রতি অ্যাপের configuration cost-এর ভিত্তিতে তিনটি proxy-এর তুলনা করে সিদ্ধান্ত নেওয়া উপযোগী।

Traefik-কে একটি nginx server {} block থেকে আলাদা করে তার configuration-এর উৎস। nginx-এ আপনি একটি file সম্পাদনা করে reload করেন, আর certificate lifecycle আলাদা কাজ হিসেবেই থাকে। এটি সেই workflow, যা আপনি nginx-এ certbot দিয়ে Let's Encrypt certificate issue করার সময় অনুসরণ করেন; renewal timer web server-এর সম্পূর্ণ বাইরে থাকে। Traefik-এর Docker provider Docker event stream monitor করে এবং আপনার container-এর labels পড়ে। Host() rule label-সহ একটি container start করলে এক সেকেন্ডের মধ্যে সেটিতে route করা যায়। container বন্ধ করলে route-টি অদৃশ্য হয়ে যায়। এখানেই ঝুঁকি। Labels-এ থাকা configuration একসঙ্গে পাঁচটি জায়গায় ছড়িয়ে থাকে। কোনো label ভুল হলে তা নীরবে ব্যর্থ হয়। Container-এ শুধু route করা হয় না, আর Traefik-ও কিছু জানায় না।

চারটি নাম

  • Entrypoints হলো listening socket। আপনি দুটি সংজ্ঞায়িত করবেন: web হবে :80-এ এবং websecure হবে :443-এ।
  • Routers একটি request-এর সঙ্গে মেলে (Host(...)) এবং সেটিকে একটি service-এর সঙ্গে যুক্ত করে। প্রতিটি router-এর জন্য tls.certresolver ব্যবহার করে certificate চাওয়া হয়।
  • Services হলো backend: একটি container এবং Docker network-এর ভেতরে যে port-এ সেটি listening করে।
  • Middlewares router ও service-এর মাঝখানে থাকে: basic auth, IP allow-list, header rewrite এবং redirect।

এই চারটি নাম Traefik সেই কাজগুলোর জন্য ব্যবহার করে, যেগুলো অন্যথায় আপনাকে হাতে লিখতে হতো। Router হলো একটি server_name, service হলো একটি proxy_pass target, আর middleware হলো header ও auth directive, যা আপনি নিজে সেট করেন যখন ধাপে ধাপে একটি nginx reverse proxy server block তৈরি করেন

Static configuration (entrypoints, providers, ACME) Traefik-এর command line-এ অথবা traefik.yml-এ দেওয়া হয়। এটি পরিবর্তন করলে Traefik restart করতে হয়। Dynamic configuration (routers, services, middlewares) container label থেকে আসে এবং hot-reload হয়। এই দুটির মধ্যে বিভ্রান্তিই সাধারণত “আমার flag কোনো কাজ করছে না” সমস্যার কারণ।

Compose ফাইল

proxy নামে একটি shared Docker network পুরো কাঠামোর ভিত্তি। Traefik কোনো container-এ পৌঁছাতে পারে শুধু তখনই, যখন উভয়ই এই network-এ যুক্ত থাকে।

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। প্রতিটি অতিরিক্ত app হলো gitea block-এর একটি অনুলিপি। এতে আলাদা router name, আলাদা Host() এবং আলাদা internal port থাকবে। Docker-এ TLS ও backup-সহ চালানো Nextcloud install একইভাবে যুক্ত করা যায়। এর published port বাদ দিন, এটিকে proxy-এ যুক্ত করুন, এবং hostname ও certificate পরিচালনার কাজ router label-গুলোর ওপর ছেড়ে দিন।

এখানে পাঁচটি বিষয় বিশেষভাবে গুরুত্বপূর্ণ।

exposedByDefault=false নির্ধারণ করে যে কোনো container-এ traefik.enable=true না থাকা পর্যন্ত সেটি Traefik-এর কাছে অদৃশ্য থাকবে। এটি বাদ দিলে আপনি চালু করা প্রতিটি container-এর জন্য route তৈরি হবে, এমনকি কোনো বিষয় যাচাই করার জন্য চালানো সাময়িক postgres container-এর জন্যও।

একাধিক network-এ কোনো container যুক্ত থাকলে Traefik কোন network ব্যবহার করবে, তা providers.docker.network=proxy নির্ধারণ করে। এটি বাদ দিলে Traefik ভুল container IP বেছে নিতে পারে। এর ফলে 502 দেখা দিতে পারে, যা application-এর ত্রুটি বলে মনে হয়।

loadbalancer.server.port=3000 হলো container-এর ভেতরের port। সেখানে Gitea 3000 port-এ listen করে। লক্ষ করুন, কোনো app container-ই port publish করে না; শুধু Traefik করে।

web entrypoint-এ redirect plaintext request-কে HTTPS-এ 308 redirect-এ রূপান্তর করে। Port 80 তবুও খোলা থাকে: ACME HTTP challenge-এর জন্য এটি প্রয়োজন, এবং bare hostname টাইপ করা ব্যবহারকারীদের জন্যও প্রয়োজন।

basic-auth hash-এ দ্বিগুণ $$ হলো Compose-এর escaping, কোনো typo নয়। htpasswd -nbB admin 'your-password' দিয়ে এটি তৈরি করুন (package apache2-utils), তারপর প্রতিটি $ দ্বিগুণ করুন।

সার্টিফিকেট এবং acme.json-এর ফাঁদ

tlschallenge=true TLS-ALPN-01 নির্বাচন করে: Let's Encrypt আপনার VPS-এর 443 port-এ সংযোগ করে এবং TLS handshake-এর মধ্যে Traefik challenge-এর উত্তর দেয়। বিকল্প হলো port 80-এ HTTP-01। Traefik-এর command: তালিকায় থাকা tlschallenge line-টি নিচের দুইটি line দিয়ে প্রতিস্থাপন করুন:

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

দুটির যেকোনোটি কাজ করে। উভয় পদ্ধতির জন্য আগে public DNS-এ hostname-টি আপনার VPS-এর দিকে নির্দেশ করা থাকতে হবে, যাতে certificate authority নামটি resolve করে বাইরে থেকে সংযোগ করতে পারে। প্রথমে A এবং AAAA record তৈরি করুন, dig +short git.example.com দিয়ে যাচাই করুন, তারপর Traefik চালু করুন।

এবার সেই ফাঁদ, যার কারণে অনেকের একটি সন্ধ্যা নষ্ট হয়। Traefik তার ACME account key এবং ইস্যু করা প্রতিটি certificate একটি acme.json-এ সংরক্ষণ করে। ফাইলটি group বা world-readable হলে Traefik প্রায় নিচের মতো একটি line দেখিয়ে বন্ধ হয়ে যায়:

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

সঠিক সমাধান হলো উপরের পদ্ধতিটি: directory-টি bind-mount করুন এবং Traefik-কে সঠিক mode-এ নিজে file তৈরি করতে দিন। touch দিয়ে acme.json তৈরি করে থাকলে আপনার umask-এর কারণে সেটি 644 হয়েছে। host-এ এটি ঠিক করুন:

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

আপনার app volume-গুলোর সঙ্গে ওই directory-টির backup রাখুন। এটি হারালেও ব্যবস্থা নেওয়া যায়, কারণ certificate আবার ইস্যু করা সম্ভব। তবে একসঙ্গে পাঁচটি hostname-এর জন্য পুনরায় ইস্যু করতে গেলে rate limit-এ পড়তে পারেন।

পরীক্ষা চলাকালে staging CA ব্যবহার করুন। caserver line-টির comment সরিয়ে প্রতিটি route কাজ করছে কি না নিশ্চিত করুন। তারপর line-টি আবার comment করে acme.json মুছে দিন, যাতে production certificate নতুন করে চাওয়া হয়। Production Let's Encrypt একই hostname-সমষ্টির জন্য প্রতি সপ্তাহে সর্বোচ্চ পাঁচটি duplicate certificate অনুমোদন করে এবং একই নামের বারবার ব্যর্থ validation সীমিত করে। Staging অবিশ্বস্ত certificate ইস্যু করে। আপনার browser সতর্কবার্তা দেখাবে। এই সতর্কবার্তাই প্রমাণ করে যে পদ্ধতিটি কাজ করেছে, আর staging-এর limit অনেক বেশি শিথিল।

ড্যাশবোর্ড একটি নিয়ন্ত্রণ স্তর, ডেমো নয়

বেশিরভাগ quickstart-এ --api.insecure=true সেট করা থাকে। এতে authentication ছাড়াই port 8080-এ ড্যাশবোর্ড চালু হয়। Public IP-সহ কোনো সার্ভারে এটি আপনার routing topology, hostname, middleware-এর নাম এবং backend port স্ক্যান করা যে কারও কাছে প্রকাশ করে।

উপরের traefik service-এর label-গুলোই বিকল্প পদ্ধতি। এতে ড্যাশবোর্ডকে অন্য যেকোনো অ্যাপের মতো routing করা হয়—একটি প্রকৃত hostname-এ, TLS-এর মাধ্যমে এবং basicauth-এর পেছনে। service=api@internal router-কে Traefik-এর built-in API-এর সঙ্গে সংযুক্ত করে। IP allow-list ধারাবাহিকভাবে যুক্ত করে নিরাপত্তা আরও বাড়ান; নিয়মগুলো বাম থেকে ডানে প্রয়োগ হয়। আপনার office address পরিবর্তনশীল হলে range হিসেবে একই VPS-এ self-host করা WireGuard VPN যে subnet বরাদ্দ করে সেটি ব্যবহার করুন এবং শুধু tunnel-এর মাধ্যমে ড্যাশবোর্ডে প্রবেশ করুন:

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

পাঁচটি অ্যাপের নিজস্ব account প্রয়োজন হলে একটি অভিন্ন basicauth password আর গ্রহণযোগ্য থাকে না। একই middleware slot-এ forwardauth বসিয়ে সিদ্ধান্তের দায়িত্ব Authentik, একটি self-hosted single sign-on server-এর কাছে দেওয়া যায়। এতে ড্যাশবোর্ড এবং এর পাশের প্রতিটি route একটি login-এর পেছনে থাকে, যা এক জায়গা থেকে বাতিল করা যায়।

Docker socket-এ root-স্তরের ক্ষমতা থাকে

/var/run/docker.sock এমন একটি API, যা host থেকে / mount করা container তৈরি করতে পারে। এতে access পাওয়া মানে মেশিনে root-স্তরের ক্ষমতা পাওয়া। Traefik label পড়ার জন্য এটি প্রয়োজন।

Mount-এর উপর :ro রাখুন। তবে এটি কী সুরক্ষা দেয়, তা স্পষ্টভাবে বুঝুন: এতে socket file শুধু read-only হয়। এর মাধ্যমে Docker API-তে পাঠানো POST request বন্ধ হয় না। প্রকৃত mitigation হলো 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 container এবং network-এ read access বজায় রাখে। তবে এটি আর কিছু তৈরি করতে পারে না।

Firewall, port এবং যে rule সবাই ভুল করে

SSH-সহ 2টি port খোলা:

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

Docker-এর published port ufw-এর নিয়ম এড়িয়ে যায়। Docker নিজস্ব iptables rule যোগ করে। এগুলো ufw chain-এর আগে কার্যকর হয়। তাই ports: ["3000:3000"] ব্যবহার করে চালু করা container-এর কাছে Internet থেকে পৌঁছানো যায়, যদিও একই port-এর জন্য ufw deny rule রয়েছে। এর প্রতিকার firewall configuration নয়, কাঠামোগত নিয়ন্ত্রণ। শুধু Traefik থেকে port publish করুন। অন্য প্রতিটি container-কে শুধু networks: [proxy] দিন, আর কিছু নয়। কোনো service-এর সত্যিই host-এ পৌঁছানো দরকার হলে সেটিকে loopback interface-এ bind করুন: "127.0.0.1:3000:3000"

সমস্যা সমাধান: বাস্তবে যে ত্রুটিগুলো দেখা যাবে

404 page not found, Traefik পরিবেশন করেছে। কোনো router মেলেনি। সম্ভাবনার ক্রম অনুযায়ী: container-এ traefik.enable=true নেই, যদিও exposedByDefault=false সেট করা আছে; Host() rule-টি আপনার টাইপ করা নামের সঙ্গে মেলে না; একটি label-এ router-এর নাম অন্য label-এর router-এর নাম থেকে আলাদা (routers.gitea.rule এবং routers.gitea.entrypoints একই শব্দ হতে হবে); অথবা hostname-টি backtick-এর বদলে quotation mark-এর মধ্যে লিখেছেন। Traefik v3 matcher-এর মধ্যে backtick প্রয়োজন।

502 Bad Gateway। একটি router মেলেছে, কিন্তু backend-এ পৌঁছানো যায়নি। প্রায় সব ক্ষেত্রেই container-টি proxy network-এ নেই; docker inspect -f '{{json .NetworkSettings.Networks}}' gitea পরীক্ষা করুন। অন্য সম্ভাবনা হলো ভুল loadbalancer.server.port: আপনি published port দিয়েছেন, অথবা অ্যাপটি অন্য port-এ listen করছে। কোন সংযোগের চেষ্টা করা হয়েছে, তা log-এ দেখা যাবে: dial tcp 172.18.0.5:8080: connect: connection refused

Browser সতর্কবার্তা দেখাচ্ছে এবং certificate-টি TRAEFIK DEFAULT CERT-এর জন্য ইস্যু করা হয়েছে। ওই hostname-এর জন্য কোনো certificate নেই, তাই 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 এখনও ওই সার্ভারের দিকে নির্দেশ করছে না। record ঠিক করুন, TTL শেষ হওয়া পর্যন্ত অপেক্ষা করুন, তারপর Traefik restart করুন।

Invalid response from http://git.example.com/.well-known/acme-challenge/... HTTP challenge-এ: বাইরে থেকে port 80 Traefik-এ পৌঁছাচ্ছে না। সাধারণত VPS-এর সামনে থাকা provider-level firewall এর কারণ, ufw-এর কারণে নয়।

Certificate কখনও ইস্যু হচ্ছে না এবং আপনার DNS Cloudflare-এ, যেখানে orange cloud চালু আছে। Cloudflare তার edge-এ TLS termination করছে, তাই TLS-ALPN-01 challenge সম্পন্ন হতে পারছে না। Certificate ইস্যু করার সময় record-টি DNS-only করুন, অথবা API token ব্যবহার করে DNS-01 challenge-এ পরিবর্তন করুন। Wildcard certificate ইস্যু করতে DNS-01-ই একমাত্র challenge।

Redirect loop। Traefik-এর সামনে থাকা কোনো স্তর ইতিমধ্যে TLS termination করছে এবং plaintext ট্রাফিক :80-এ forward করছে; entrypoint redirect সেটিকে আবার HTTPS-এ পাঠাচ্ছে। দুটি redirect-এর একটি সরিয়ে দিন।

এটি চালু রাখুন

Docker-এর unit-টি boot-এ চালু হওয়ার জন্য enable করা থাকতে হবে (systemctl is-enabled docker), এবং reboot-এর পরে stack পুনরায় চালু করে restart: unless-stopped। স্পষ্ট নিয়ন্ত্রণের জন্য docker compose -f /srv/edge/compose.yml up -d চালানো একটি ছোট systemd unit ব্যবহার করুন। এতে RemainAfterExit=yes আপনাকে systemctl status edge এবং service-এর ক্রম নিয়ন্ত্রণ করতে দেয়।

Traefik-এর tag নির্দিষ্ট করে দিন (traefik:v3.5, কখনো latest নয়)। v2 থেকে v3-এ upgrade করার সময় rule syntax এবং provider-এর নাম পরিবর্তিত হয়েছে। unattended latest এমন configuration পুনরায় load করে ফেলতে পারে, যা এটি আর বুঝতে পারে না। পরিকল্পনা করে upgrade করুন: migration notes পড়ুন, tag পরিবর্তন করুন, docker compose up -d traefik চালান এবং log monitor করুন। আপনি যদি এখনও v2 tag ব্যবহার করেন, Traefik v2 থেকে v3 migration guide-এ প্রতিটি নাম পরিবর্তন, compatibility mode এবং certificate অক্ষুণ্ণ রেখে rollback করার পদ্ধতি দেখানো হয়েছে।

./letsencrypt এবং প্রতিটি app-এর data volume-এর backup নিন। compose file থেকে পুনর্নির্মাণ করা যায় না—এমন অতিরিক্ত কোনো state Traefik সংরক্ষণ করে না।

স্কেলে কী ভেঙে পড়ে

প্রথম সীমাবদ্ধতা throughput নয়, একটি মাত্র server: একটি VPS-এ চলা একটি Traefik পাঁচটি অ্যাপের জন্য single point of failure। আর acme.json flat-file storage হওয়ায় দুটি Traefik instance এতে লিখলে storage নষ্ট হয়ে যাবে। স্কেল বাড়াতে হলে certificate storage-কে file-এর বাইরে নিতে হবে, অথবা অন্য কোথাও TLS termination করতে হবে।

দ্বিতীয় সমস্যা হলো দীর্ঘস্থায়ী connection। Server-sent events, বড় upload এবং ধীর client-গুলো entrypoint-এর response timeout-এর মুখোমুখি হয়; --entryPoints.websecure.transport.respondingTimeouts.readTimeout এবং এর writeTimeoutidleTimeout-এর মতো সংশ্লিষ্ট setting-গুলো নিয়ন্ত্রণের উপায়। WebSocket অতিরিক্ত configuration ছাড়াই pass through করে।

তৃতীয় সমস্যা হলো disk। --accesslog=true stdout-এ লিখে, আর Docker-এর json-file driver সীমা নির্ধারণ না করা পর্যন্ত সেগুলো স্থায়ীভাবে সংরক্ষণ করে। Traefik service-এ logging.options.max-size সেট করুন, অথবা access log file-এ লিখে log rotation চালু করুন।

এসবের জন্য কোনো orchestrator প্রয়োজন নেই। তবে আপনার নিয়ন্ত্রণে থাকা একটি server দরকার, যার একটি public IP আছে এবং 80 ও 443 port Internet-এর জন্য খোলা। একটি ছোট VPS-ই সম্পূর্ণ dependency list।

FAQ

Traefik চালালে কি এখনও certbot প্রয়োজন?

না। Traefik-এর ACME resolver এটি যে প্রতিটি hostname route করে, তার জন্য certificate request ও renewal করে এবং সব certificate acme.json-এ সংরক্ষণ করে। nginx বা অন্য কোনো server নিজে TLS terminate করলে Certbot এখনও উপযুক্ত tool। একই hostname-এর জন্য দুটিকে একসঙ্গে চালালে শুধু Let's Encrypt-এর rate limit দ্রুত শেষ হয়।

Traefik-এর মাধ্যমে container-এ গেলে আমার 404 কেন আসে?

Traefik যে 404 পরিবেশন করে, তার অর্থ কোনো router request-টির সঙ্গে match করেনি। Container-এ traefik.enable=true আছে কি না পরীক্ষা করুন; exposedByDefault=false সেট করা থাকলে এটি বাধ্যতামূলক। Host()-এর value আপনি যে name লিখেছেন তার সঙ্গে মেলে কি না দেখুন। এছাড়া, ওই app-এর প্রতিটি label-এ router name একই কি না যাচাই করুন। Traefik v3 matcher-এর ভিতরে quotes নয়, backticks প্রত্যাশা করে।

এখানে 404 এবং 502-এর মধ্যে পার্থক্য কী?

404-এর অর্থ routing একেবারেই হয়নি। 502-এর অর্থ একটি router match করেছে, কিন্তু backend connection প্রত্যাখ্যান করেছে। 502-এর সাধারণ কারণ হলো container-টি proxy network-এ সংযুক্ত নয়, অথবা loadbalancer.server.port এমন একটি published port নির্দেশ করছে যেটি container-এর ভিতরে app যে port-এ listen করে সেটি নয়। Access log-এ Traefik যে নির্দিষ্ট address-এ connection করার চেষ্টা করেছে, সেটি দেখা যায়।

Docker socket read-only হিসেবে mount করলেই কি যথেষ্ট?

:ro flag socket file-টিকে read-only করে, এর পেছনের API-কে নয়। POST request এখনও এর মাধ্যমে চলাচল করে, এবং Docker API-তে access host-এ root access-এর সমতুল্য। আরও নিরাপদ ব্যবস্থা হলো উপরে দেখানো docker-socket-proxy container। এটি Traefik-এর জন্য শুধু container ও network read operation প্রকাশ করে এবং write operation সম্পূর্ণভাবে বন্ধ রাখে।

Traefik কি wildcard certificate issue করতে পারে?

শুধু DNS-01 challenge-এর মাধ্যমে, এবং এর জন্য আপনার DNS provider-এর API token প্রয়োজন। TLS-ALPN-01 ও HTTP-01 প্রতিটি একটি single hostname validate করে; এগুলো wildcard certificate তৈরি করতে পারে না। আপনার VPS-এর সামনে Cloudflare-এর মতো কোনো CDN TLS terminate করলে এবং অন্য দুটি challenge সম্পন্ন না হলে DNS-01-ই উপযুক্ত পদ্ধতি।