একটি Docker Compose ফাইলে 5টি অ্যাপ ও Traefik সেটআপ
একটি IP এবং একটি পোর্ট ব্যবহার করে Traefik v3 দিয়ে পাঁচটি অ্যাপ হোস্ট করুন। Host rule কনফিগারেশন, অটোমেটিক Let's Encrypt TLS এবং acme.json পারমিশন এরর সমাধানের উপায় জানুন।
একটি 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 ফাইল
একটি শেয়ারড Docker নেটওয়ার্ক যার নাম proxy হলো এর মূল ভিত্তি। Traefik তখনই একটি কন্টেইনারের সাথে যোগাযোগ করতে পারে যদি উভয়ই একই নেটওয়ার্কে থাকে।
name: edge
networks:
proxy:
name: proxy
services:
traefik:
image: traefik:v3.7
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 ব্লকের একটি কপি, যার নিজস্ব রাউটার নাম, নিজস্ব Host() এবং নিজস্ব ইন্টারনাল পোর্ট থাকে। একটি Nextcloud install running in Docker with TLS and backups একইভাবে যুক্ত করা যায়; এর পাবলিশ করা পোর্টগুলো সরিয়ে ফেলুন, এটিকে proxy-এর সাথে যুক্ত করুন এবং রাউটার লেবেলগুলোকে হোস্টনাম ও সার্টিফিকেটের বিষয়টি সামলাতে দিন।
এখানে পাঁচটি বিষয় গুরুত্বপূর্ণ।
exposedByDefault=false একটি কন্টেইনারকে Traefik-এর কাছে অদৃশ্য রাখে যতক্ষণ না এতে traefik.enable=true যুক্ত করা হয়। এটি বাদ দিলে আপনার চালু করা প্রতিটি কন্টেইনার, এমনকি কোনো কিছু পরীক্ষা করার জন্য চালানো অস্থায়ী postgres কন্টেইনারটির জন্যও একটি রুট তৈরি হয়ে যাবে।
providers.docker.network=proxy Traefik-কে নির্দেশ দেয় কোন নেটওয়ার্ক ব্যবহার করতে হবে যখন একটি কন্টেইনার একাধিক নেটওয়ার্কে যুক্ত থাকে। এটি বাদ দিলে Traefik ভুল কন্টেইনার IP বেছে নিতে পারে, যা 502 এরর হিসেবে দেখা দেয় এবং মনে হয় এটি অ্যাপ্লিকেশনের সমস্যা।
loadbalancer.server.port=3000 হলো কন্টেইনারের ভিতরের পোর্ট; Gitea সেখানে 3000 পোর্টে লিসেন করে। লক্ষ্য করুন যে কোনো অ্যাপ কন্টেইনারই কোনো পোর্ট পাবলিশ করে না, শুধুমাত্র Traefik তা করে।
web এন্ট্রি পয়েন্টে রিডাইরেক্ট ডিফল্টভাবে পার্মানেন্ট থাকে, তাই একটি প্লেইনটেক্সট GET রিকোয়েস্ট (যা ব্রাউজার পাঠায়) HTTPS-এ 301 রিডাইরেক্ট হয়; Traefik অন্যান্য মেথডের জন্য (যেমন POST) শুধুমাত্র 308 রেসপন্স দেয়, যাতে মেথডটি হপ পার হওয়ার পরেও টিকে থাকে। পোর্ট 80 সবসময় খোলা থাকে: ACME HTTP চ্যালেঞ্জের জন্য এটি প্রয়োজন, এবং যারা সরাসরি হোস্টনাম টাইপ করে তাদের জন্যও এটি দরকার।
basic-auth হ্যাশে ডাবল $$ হলো Compose এস্কেপিং, কোনো টাইপো নয়। এটি htpasswd -nbB admin 'your-password' (প্যাকেজ apache2-utils) দিয়ে তৈরি করুন, তারপর প্রতিটি $ ডাবল করে দিন।
সার্টিফিকেট এবং acme.json এর ফাঁদ
tlschallenge=true TLS-ALPN-01 নির্বাচন করে: Let's Encrypt আপনার বক্সে 443 পোর্টে সংযোগ করে এবং Traefik TLS হ্যান্ডশেকের ভেতরেই চ্যালেঞ্জটির উত্তর দেয়। এর বিকল্প হলো HTTP-01, যা 80 নম্বর পোর্টে কাজ করে। Traefik-এর command: তালিকায় থাকা tlschallenge লাইনটি সরিয়ে নিচের দুটি লাইন যোগ করুন:
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=webউভয় পদ্ধতিই কাজ করে। দুটির জন্যই প্রয়োজন যে হোস্টনেমের পাবলিক DNS আগে থেকেই আপনার VPS-এর দিকে নির্দেশ করা আছে, যাতে সার্টিফিকেট অথরিটি নামটি রিজলভ করতে পারে এবং বাইরে থেকে সংযোগ স্থাপন করতে পারে। প্রথমে A (এবং AAAA) রেকর্ড তৈরি করুন, dig +short git.example.com দিয়ে নিশ্চিত করুন, তারপর Traefik চালু করুন।
এখন সেই ফাঁদটি সম্পর্কে জানুন যা অনেকেরই অনেক সময় নষ্ট করে। Traefik তার ACME অ্যাকাউন্ট কি এবং ইস্যু করা প্রতিটি সার্টিফিকেট একটি acme.json ফাইলে জমা রাখে। যদি সেই ফাইলটি গ্রুপ বা অন্য কারো পড়ার যোগ্য (readable) হয়, তবে Traefik এই ধরনের একটি লগ দেখাবে এবং রিজলভার বন্ধ করে দেবে। এটি চলতে থাকবে এবং রাউটিং করবে, কিন্তু কোনো সার্টিফিকেট অনুরোধ করা হবে না, ফলে প্রতিটি হোস্টনেম TRAEFIK DEFAULT CERT হিসেবে সার্ভ হবে:
ERR The ACME resolve is skipped from the resolvers list error="unable to get ACME account: permissions 644 for /letsencrypt/acme.json are too open, please use 600" resolver=leএর সঠিক সমাধান হলো উপরের পদ্ধতিটি: directory-টিকে bind-mount করুন এবং Traefik-কে সঠিক মোডে ফাইলটি নিজে তৈরি করতে দিন। যদি আপনি touch ব্যবহার করে acme.json তৈরি করে থাকেন, তবে আপনার umask এটিকে 644 করে দিয়েছে। হোস্ট মেশিনে এটি ঠিক করুন:
chmod 600 ./letsencrypt/acme.json
docker compose restart traefikআপনার অ্যাপ ভলিউমের সাথে এই ডিরেক্টরিটির ব্যাকআপ রাখুন। এটি একবার হারিয়ে গেলে সামলানো যায়, সার্টিফিকেট পুনরায় ইস্যু করা সম্ভব, কিন্তু প্রতিবার রিডিপ্লয় করার সময় এটি মুছে ফেললে আপনি প্রতি 7 দিনে একই হোস্টনেমের সেটের জন্য পাঁচটি সার্টিফিকেটের সীমাবদ্ধতায় পড়ে যাবেন।
পরীক্ষামূলক কাজের সময় staging CA ব্যবহার করুন। caserver লাইনটি আনকমেন্ট করুন, প্রতিটি রুট কাজ করছে কি না তা নিশ্চিত করুন, তারপর সেটিকে আবার কমেন্ট আউট করুন এবং acme.json মুছে ফেলুন যাতে প্রোডাকশন সার্টিফিকেট নতুন করে অনুরোধ করা হয়। প্রোডাকশন Let's Encrypt প্রতি সপ্তাহে একই হোস্টনেমের সেটের জন্য পাঁচটি ডুপ্লিকেট সার্টিফিকেটের অনুমতি দেয় এবং একই নামের জন্য বারবার ব্যর্থ ভ্যালিডেশন হলে তা সীমিত (throttle) করে দেয়। Staging থেকে ইস্যু করা সার্টিফিকেটগুলো বিশ্বস্ত নয়, আপনার ব্রাউজার সতর্কবার্তা দেখাবে, এবং সেই সতর্কবার্তাই হলো সংকেত যে এটি কাজ করেছে, যেখানে সীমাবদ্ধতা অনেক শিথিল।
ড্যাশবোর্ড একটি নিয়ন্ত্রণ স্তর, ডেমো নয়
বেশিরভাগ 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:
- proxyTraefik থেকে socket volume সরিয়ে provider-কে proxy-র দিকে নির্দেশ করুন:
--providers.docker.endpoint=tcp://dockerproxy:2375Traefik 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 enableDocker-এর 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 থেকে আসে। কোনো রাউটার ম্যাচ করেনি। সম্ভাব্য কারণগুলো হলো: কন্টেইনারটিতে traefik.enable=true নেই (যেখানে exposedByDefault=false সেট করা প্রয়োজন); Host() রুলটি আপনার টাইপ করা নামের সাথে মিলছে না; একটি লেবেলের রাউটারের নাম অন্যটির সাথে অমিল (routers.gitea.rule এবং routers.gitea.entrypoints অবশ্যই একই শব্দ হতে হবে); অথবা আপনি হোস্টনেমটিকে সিঙ্গেল কোট দিয়ে ঘিরে রেখেছেন। Traefik v3 ম্যাচারের ভেতরে ব্যাকটিক বা এস্কেপ করা ডাবল কোট (\") গ্রহণ করে এবং সিঙ্গেল কোট প্রত্যাখ্যান করে।
502 Bad Gateway. একটি রাউটার ম্যাচ করেছে কিন্তু ব্যাকএন্ডে পৌঁছানো সম্ভব হয়নি। প্রায় সব ক্ষেত্রেই কন্টেইনারটি proxy নেটওয়ার্কে নেই, docker inspect -f '{{json .NetworkSettings.Networks}}' gitea চেক করুন। অন্য একটি সম্ভাব্য কারণ হলো ভুল loadbalancer.server.port: আপনি হয়তো একটি পাবলিশড পোর্ট দিয়েছেন, অথবা অ্যাপটি অন্য কোথাও লিসেন করছে। লগ ফাইলটিতে এই প্রচেষ্টার নাম উল্লেখ থাকে: dial tcp 172.18.0.5:8080: connect: connection refused।
ব্রাউজার সতর্কবার্তা দিচ্ছে এবং সার্টিফিকেটটি TRAEFIK DEFAULT CERT-এর নামে ইস্যু করা হয়েছে। ওই হোস্টনেমের জন্য কোনো সার্টিফিকেট নেই এবং Traefik তার নিজস্ব self-signed প্লেসহোল্ডার সার্ভ করেছে। ACME লাইনগুলো পড়ুন:
unable to obtain ACME certificate for domains "git.example.com" ...
acme: error: 400 ... DNS problem: NXDOMAIN looking up A for git.example.comDNS এখনো সার্ভারের দিকে পয়েন্ট করছে না। রেকর্ডটি ঠিক করুন, TTL শেষ হওয়া পর্যন্ত অপেক্ষা করুন এবং Traefik রিস্টার্ট করুন।
HTTP চ্যালেঞ্জে Invalid response from http://git.example.com/.well-known/acme-challenge/...: পোর্ট 80 বাইরের দিক থেকে Traefik-এ পৌঁছাতে পারছে না। সাধারণত এটি ufw নয়, বরং VPS-এর সামনে থাকা কোনো প্রোভাইডার-লেভেল ফায়ারওয়ালের সমস্যা।
সার্টিফিকেট ইস্যু হচ্ছে না এবং আপনার DNS ক্লাউডফ্লেয়ারে অরেঞ্জ ক্লাউড মোডে আছে। ক্লাউডফ্লেয়ার তার এজ-এ TLS টার্মিনেট করে, ফলে TLS-ALPN-01 এর মাধ্যমে সম্পন্ন হতে পারে না। ইস্যু করার সময় রেকর্ডটি DNS-only মোডে সেট করুন, অথবা API টোকেন ব্যবহার করে DNS-01 চ্যালেঞ্জে সুইচ করুন। DNS-01 হলো একমাত্র চ্যালেঞ্জ যা ওয়াইল্ডকার্ড সার্টিফিকেট ইস্যু করতে পারে।
Redirect loop. Traefik-এর সামনে থাকা অন্য কিছু ইতিমধ্যে TLS টার্মিনেট করছে এবং প্লেইনটেক্সট :80-তে ফরোয়ার্ড করছে; এন্ট্রি পয়েন্ট রিডাইরেক্ট এটিকে আবার HTTPS-এ পাঠিয়ে দিচ্ছে। এই দুটি রিডাইরেক্টের যেকোনো একটি সরিয়ে ফেলুন।
সচল রাখা
Docker-এর unit অবশ্যই boot-enabled (systemctl is-enabled docker) হতে হবে এবং restart: unless-stopped রিবুটের পরে stack-টিকে পুনরায় চালু করে। সুনির্দিষ্ট নিয়ন্ত্রণের জন্য, RemainAfterExit=yes সহ docker compose -f /srv/edge/compose.yml up -d চালানো একটি ছোট systemd unit আপনাকে systemctl status edge এবং অর্ডারিংয়ের নিয়ন্ত্রণ দেয়।
Traefik tag-টিকে পিন করুন (traefik:v3.7, কখনোই latest নয়), এবং এমন একটি branch পিন করুন যা নিয়মিত নতুন রিলিজ দেয়। 2026-10-12 তারিখ অনুযায়ী, Traefik শুধুমাত্র v3.7-কে সমর্থিত v3 branch হিসেবে তালিকাভুক্ত করে। v3.5 তার শেষ রিলিজ, v3.5.6, 7 নভেম্বর 2025-এ দিয়েছিল এবং এর Docker provider-টি API version 1.24-এ hardcoded করা। Docker Engine 29 এবং পরবর্তী সংস্করণগুলো client version 1.24 is too old দিয়ে এটি প্রত্যাখ্যান করে, ফলে কোনো কন্টেইনার রাউট হয় না। Traefik 3.6.1-এ Docker API version negotiation যুক্ত করা হয়েছে, যে কারণে উপরের compose ফাইলে v3.7 ব্যবহার করা হয়েছে। v2 থেকে v3 আপগ্রেডের সময় rule syntax এবং provider-এর নাম পরিবর্তিত হয়েছে, এবং একটি unattended latest এমন কনফিগারেশন রিলোড করবে যা এটি আর বুঝতে পারে না। সতর্কতার সাথে আপগ্রেড করুন: মাইগ্রেশন নোটগুলো পড়ুন, tag পরিবর্তন করুন, docker compose up -d traefik করুন এবং লগ পর্যবেক্ষণ করুন। আপনি যদি এখনো v2 tag-এ থাকেন, তবে Traefik v2 থেকে v3 মাইগ্রেশন গাইড প্রতিটি রিনেম, কম্প্যাটিবিলিটি মোড এবং আপনার সার্টিফিকেটগুলো অক্ষুণ্ণ রেখে রোলব্যাক করার প্রক্রিয়াটি বিস্তারিত দেখাবে।
./letsencrypt এবং প্রতিটি অ্যাপের ডেটা ভলিউম ব্যাকআপ রাখুন। Traefik-এর কাছে এমন কোনো স্টেট থাকে না যা আপনি compose ফাইল থেকে পুনরায় তৈরি করতে পারবেন না।
স্কেলে কী ভেঙে পড়ে
প্রথম সীমাবদ্ধতা 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 এবং এর writeTimeout ও idleTimeout-এর মতো সংশ্লিষ্ট 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-এর জন্য সার্টিফিকেট অনুরোধ ও রিনিউ করে এবং সেগুলো acme.json-এ জমা রাখে। যখন Nginx বা অন্য কোনো সার্ভার নিজে TLS termination করে, তখন certbot সঠিক টুল হিসেবে কাজ করে; একই hostname-এর জন্য দুটিই ব্যবহার করলে Let's Encrypt-এর rate limit দ্রুত শেষ হয়ে যায়।
Traefik-এর মাধ্যমে আমার কন্টেইনার কেন 404 error দিচ্ছে?
Traefik থেকে 404 পাওয়ার মানে হলো কোনো রাউটারই অনুরোধটির সাথে মেলেনি। নিশ্চিত করুন যে কন্টেইনারটিতে traefik.enable=true আছে (যখন exposedByDefault=false সেট করা থাকে তখন এটি বাধ্যতামূলক), Host()-এর মান আপনার টাইপ করা নামের সাথে মিলছে এবং অ্যাপের প্রতিটি লেবেলে রাউটারের নাম একই আছে। Traefik v3-এর ক্ষেত্রে matcher-এর ভেতরে backtick বা escaped double quote প্রয়োজন; single quote গ্রহণ করা হয় না।
এখানে 404 এবং 502-এর মধ্যে পার্থক্য কী?
404 মানে রাউটিং কখনোই সম্পন্ন হয়নি; 502 মানে রাউটার অনুরোধটি পেয়েছে কিন্তু backend সংযোগটি প্রত্যাখ্যান করেছে। 502-এর সাধারণ কারণগুলো হলো কন্টেইনারটি proxy নেটওয়ার্কের সাথে যুক্ত না থাকা অথবা loadbalancer.server.port-এ এমন একটি পোর্ট উল্লেখ করা যা কন্টেইনারের ভেতরের অ্যাপের লিসেনিং পোর্টের সাথে মেলে না। access log-এ Traefik কোন ঠিকানায় সংযোগ করার চেষ্টা করেছে তা দেখা যায়।
Docker socket-কে read-only হিসেবে মাউন্ট করাই কি যথেষ্ট?
:ro ফ্ল্যাগটি শুধুমাত্র socket ফাইলটিকে read-only করে, এর পেছনের API-কে নয়। POST অনুরোধগুলো এখনও এর মাধ্যমে পাঠানো যায় এবং Docker API-এর অ্যাক্সেস থাকা মানে হোস্টের root অ্যাক্সেস থাকা। আরও শক্তিশালী ব্যবস্থা হলো উপরে দেখানো docker-socket-proxy কন্টেইনার ব্যবহার করা, যা Traefik-এর জন্য শুধুমাত্র কন্টেইনার ও নেটওয়ার্ক রিড করার অনুমতি দেয় এবং রাইট অপারেশন পুরোপুরি ব্লক করে।
Traefik কি wildcard সার্টিফিকেট ইস্যু করতে পারে?
শুধুমাত্র DNS-01 challenge-এর মাধ্যমে, আপনার DNS প্রোভাইডারের API টোকেন ব্যবহার করে এটি সম্ভব। TLS-ALPN-01 এবং HTTP-01 প্রতিটি আলাদা আলাদা hostname যাচাই করে এবং wildcard তৈরি করতে পারে না। যখন Cloudflare-এর মতো কোনো CDN আপনার VPS-এর সামনে TLS termination করে এবং অন্য দুটি challenge সম্পন্ন হয় না, তখন DNS-01-ই একমাত্র সমাধান।