Jinsi ya kuendesha programu tano kwenye Traefik v3
Sanidi programu tano kwenye IP moja kwa kutumia Traefik v3 na Docker Compose. Jifunze kutumia sheria za Host, TLS ya Let's Encrypt, na kuepuka hitilafu ya acme.json inayozuia huduma.
IP moja, programu tano, port moja 443
VPS yako ina anwani moja ya umma ya IPv4 na port moja ya TCP 443. Unataka kuweka Gitea, nakala ya staging ya programu yako, dashibodi ya ndani, ukurasa wa hali (status page), na mpokeaji wa webhook juu yake; majina ya host matano, seva moja. Reverse proxy ndiyo mchakato unaomiliki :80 na :443, husoma header ya Host kwenye kila ombi na kulipeleka kwenye container sahihi. Traefik hufanya hivyo, na hupata pamoja na kuhuisha cheti kwa kila jina la host bila wewe kuendesha certbot kwa mkono. Nginx na Caddy zingeterminate majina hayo matano ya host vizuri kabisa, kwa hivyo kama bado hujachagua, inafaa kupima proxies hizo tatu kwa kuzingatia usimamizi wa vyeti na gharama ya usanidi kwa kila programu kabla ya kuunganisha kila kitu kwenye mojawapo.
Kinachotofautisha Traefik na block ya server {} ya nginx ni mahali ambapo usanidi wake hutoka. Kwa nginx, unahariri faili na kufanya reload, na mzunguko wa maisha wa cheti hubaki kuwa kazi ya ziada, mtiririko wa kazi unaofuata unapokuwa unatoa vyeti vya Let's Encrypt kwa kutumia certbot kwenye nginx, ambapo kipima muda cha kuhuisha (renewal timer) kipo nje ya seva ya wavuti kabisa. Docker provider ya Traefik hufuatilia mtiririko wa matukio ya Docker na kusoma labels kutoka kwenye containers zako: anzisha container yenye label ya sheria ya Host() na itakuwa routable ndani ya sekunde moja; iache na njia hiyo itatoweka. Hilo pia ndilo tatizo. Usanidi uliopo kwenye labels unapatikana katika sehemu tano kwa wakati mmoja, na label isiyo sahihi huwa kimya, container haipelekewi trafiki, na Traefik haisemi chochote.
Nomino nne
- Entrypoints ni soketi zinazosikiliza. Utafafanua mbili:
webkwenye:80nawebsecurekwenye:443. - Routers hulinganisha ombi (
Host(...)) na kuliunganisha na huduma. Vyeti huombwa kwa kila router, kupitiatls.certresolver. - Services ni backend, kontena na port inayosikiliza ndani ya mtandao wa Docker.
- Middlewares hukaa kati ya router na service: basic auth, IP allow-lists, header rewrites, na redirects.
Nomino hizo nne ni majina ya Traefik kwa kazi ambazo ungeziandika kwa mkono: router ni server_name, service ni lengo la proxy_pass, na middlewares ni maelekezo ya header na auth unayojiwekea unapokuwa unajenga block ya server ya nginx reverse proxy mstari kwa mstari.
Usanidi tuli (entrypoints, providers, ACME) hupitishwa kwenye mstari wa amri wa Traefik au katika traefik.yml, na kuubadilisha kunamaanisha kuanzisha upya Traefik. Usanidi wa nguvu (routers, services, middlewares) hutoka kwenye lebo za kontena na hupakiwa upya papo hapo. Kuchanganya haya mawili ndiyo chanzo cha kawaida cha tatizo la "flag yangu haifanyi kazi".
Faili la compose
Mtandao mmoja wa Docker ulioshirikiwa unaoitwa proxy ndio uti wa mgongo. Traefik hufikia container ikiwa zote mbili zimeunganishwa kwenye mtandao huo.
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=3000docker compose up -d, kisha docker compose logs -f traefik. Kila programu ya ziada ni nakala ya block ya gitea ikiwa na jina lake la router, Host() yake yenyewe, na port yake ya ndani. Ufungaji wa Nextcloud unaoendeshwa kwenye Docker na TLS pamoja na backups huingia kwa njia hiyo hiyo; ondoa port zake zilizochapishwa, iunganishe kwenye proxy, na uruhusu lebo za router zishughulikie hostname na cheti.
Maelezo matano hapo yana umuhimu wake.
exposedByDefault=false hufanya container isionekane na Traefik hadi pale itakapobeba traefik.enable=true. Iache nje na kila container unayoianzisha, ikiwemo postgres ya muda uliyoiendesha ili kukagua kitu, itatengenezewa route.
providers.docker.network=proxy huambia Traefik mtandao upi utumike wakati container imeunganishwa kwenye mitandao kadhaa. Ukiiondoa, Traefik inaweza kuchagua IP isiyo sahihi ya container, jambo linalojitokeza kama 502 inayoonekana kama hitilafu ya programu.
loadbalancer.server.port=3000 ni port iliyo ndani ya container; Gitea husikiliza kwenye 3000 huko. Kumbuka kuwa hakuna container ya programu inayochapisha port yoyote, ni Traefik pekee inayofanya hivyo.
Redirect kwenye entrypoint ya web hubadilisha maombi ya maandishi ya kawaida (plaintext) kuwa 308 kwenda HTTPS. Port 80 hubaki wazi hata hivyo: changamoto ya ACME HTTP inaihitaji, na vilevile wanadamu wanaochapa hostname bila itifaki.
$$ iliyoongezwa mara mbili kwenye hash ya basic-auth ni njia ya Compose ya kufanya escaping, si kosa la uchapaji. Itengeneze kwa kutumia htpasswd -nbB admin 'your-password' (kifurushi cha apache2-utils), kisha ongeza mara mbili kila $.
Cheti, na mtego wa acme.json
tlschallenge=true huchagua TLS-ALPN-01: Let's Encrypt huunganisha kwenye seva yako kupitia 443 na Traefik hujibu changamoto hiyo ndani ya TLS handshake. Njia mbadala ni HTTP-01, kwenye port 80, badilisha mstari wa tlschallenge katika orodha ya command: ya Traefik na mistari hii miwili:
- --certificatesresolvers.le.acme.httpchallenge=true
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=webZote hufanya kazi. Zote zinahitaji DNS ya umma ya hostname hiyo ielekeze kwenye VPS yako, ili mamlaka ya vyeti (certificate authority) iweze kutatua jina hilo na kuunganisha kutoka nje. Unda rekodi ya A (na AAAA) kwanza, thibitisha na dig +short git.example.com, kisha uanzishe Traefik.
Sasa mtego unaowagharimu watu jioni nzima. Traefik huhifadhi ufunguo wa akaunti yake ya ACME na kila cheti kilichotolewa ndani ya acme.json moja. Ikiwa faili hiyo inaweza kusomwa na kundi au dunia nzima, Traefik huchapisha mstari unaofanana na huu na kusimama:
error: unable to get ACME account: permissions 644 for /letsencrypt/acme.json are too open, please use 600Suluhisho sahihi ni lile la hapo juu: fanya bind-mount ya directory na uiruhusu Traefik yenyewe itengeneze faili hiyo kwa mode sahihi. Ikiwa uliunda acme.json kwa kutumia touch, umask yako ilifanya iwe 644. Irekebishe kwenye host:
chmod 600 ./letsencrypt/acme.json
docker compose restart traefikHifadhi nakala (backup) ya directory hiyo pamoja na volumes za programu yako. Kupoteza faili hiyo si mwisho wa dunia, vyeti vinaweza kuombwa upya, lakini kuomba upya vyeti vya hostnames tano kwa wakati mmoja kutakuingiza kwenye vikwazo vya rate limits.
Tumia staging CA wakati unafanya majaribio. Ondoa komenti kwenye mstari wa caserver, hakikisha kila route inafanya kazi, kisha rudisha komenti na ufute acme.json ili vyeti vya production viombwe upya. Let's Encrypt ya production inaruhusu vyeti vitano vinavyofanana kwa wiki kwa seti moja ya hostnames, na huzuia uthibitishaji unaofeli mara kwa mara kwa jina lilelile. Staging hutoa vyeti visivyoaminika, kivinjari chako kitatoa onyo, na onyo hilo ni ishara kwamba imefanya kazi, huku ikiwa na vikwazo vidogo zaidi.
Dashboard ni sehemu ya kudhibiti, si onyesho la majaribio
Quickstarts nyingi huweka --api.insecure=true, ambayo huonyesha dashboard kwenye port 8080 bila uthibitisho wowote. Kwenye seva yenye IP ya umma, hii hufichua topolojia yako ya routing, majina ya host, majina ya middleware, na port za backend kwa yeyote anayechanganua seva hiyo.
Lebels kwenye huduma ya traefik hapo juu ni njia mbadala: dashboard hupitishwa kama programu nyingine yoyote, kwenye hostname halisi, kupitia TLS, nyuma ya basicauth. service=api@internal ndiyo inayounganisha router na API iliyojengwa ndani ya Traefik. Imarisha usalama zaidi kwa kuweka IP allow-list, inayotekelezwa kuanzia kushoto kwenda kulia. Ikiwa anwani ya ofisi yako inabadilika, weka range kwenye subnet inayotolewa na WireGuard VPN unayojiendeshea kwenye VPS hiyo hiyo na ufikie dashboard kupitia tunnel pekee:
- traefik.http.middlewares.office.ipallowlist.sourcerange=10.0.0.7/32
- traefik.http.routers.dashboard.middlewares=office,dashboard-authNenosiri moja la basicauth linapoteza ufanisi pindi programu tano zinapohitaji akaunti zao binafsi, na nafasi hiyo hiyo ya middleware inaweza kuchukua forwardauth inayokabidhi uamuzi kwa Authentik, seva ya single sign-on unayojiendeshea, ili dashboard na kila njia nyingine iwe nyuma ya login moja unayoweza kuifuta katika sehemu moja.
Docker socket ni root
/var/run/docker.sock ni API inayoweza kuunda container inayopachika / kutoka kwenye host. Upatikanaji wa socket hii ni sawa na kuwa na ruhusa za root kwenye mashine, na Traefik inaihitaji ili kusoma labels.
Weka :ro kwenye mount hiyo, lakini uwe wazi kuhusu faida yake: inafanya socket file kuwa ya kusoma pekee (read-only). Haizuii maombi ya POST kwenda kwenye Docker API kupitia socket hiyo. Njia sahihi ya kujilinda ni kutompa Traefik socket hiyo moja kwa moja, na kuweka proxy ya kuchuja (filtering proxy) katikati:
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:
- proxyOndoa volume ya socket kutoka kwa Traefik na uelekeze provider kwenye proxy hiyo:
--providers.docker.endpoint=tcp://dockerproxy:2375Traefik inabaki na uwezo wa kusoma containers na networks, lakini inapoteza uwezo wa kuunda kitu chochote.
Firewall, porti, na sheria ambayo kila mtu hukosea
Porti mbili ziko wazi, pamoja na SSH:
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enablePorti zilizochapishwa na Docker hupita ufw. Docker huweka sheria zake za iptables, ambazo hupitiwa kabla ya chains za ufw. Kwa hivyo, container iliyoanzishwa kwa ports: ["3000:3000"] inaweza kufikiwa kutoka Internet hata kama ufw imewekwa kuzuia (deny). Kinga yake ni ya kimuundo, si ya usanidi wa firewall: chapisha porti kutoka Traefik pekee, na upe kila container nyingine networks: [proxy] na si kitu kingine. Ikiwa kuna kitu lazima kifike kwenye host, kibanike (bind) kwenye loopback, "127.0.0.1:3000:3000".
Utatuzi wa matatizo: makosa utakayokutana nayo
404 page not found, inayotolewa na Traefik. Hakuna router iliyolingana. Kwa mpangilio wa uwezekano: container haina traefik.enable=true (pamoja na exposedByDefault=false kuwekwa); sheria ya Host() hailingani na jina uliloandika; jina la router katika label moja linatofautiana na jina la router katika nyingine (routers.gitea.rule na routers.gitea.entrypoints lazima yawe neno moja); au uliweka hostname kwenye alama za kunukuu badala ya backticks. Traefik v3 inahitaji backticks ndani ya matchers.
502 Bad Gateway. Router ililingana lakini backend haikufikika. Mara nyingi container haipo kwenye mtandao wa proxy, kagua docker inspect -f '{{json .NetworkSettings.Networks}}' gitea. Sababu nyingine ni loadbalancer.server.port isiyo sahihi: uliweka port iliyochapishwa, au programu inasikiliza kwingine. Log inataja jaribio hilo: dial tcp 172.18.0.5:8080: connect: connection refused.
Kivinjari kinatoa onyo, na cheti kimetolewa kwa TRAEFIK DEFAULT CERT. Hakuna cheti kilichopo kwa hostname hiyo na Traefik imetoa cheti chake cha muda (self-signed placeholder). Soma mistari ya ACME:
unable to obtain ACME certificate for domains "git.example.com" ...
acme: error: 400 ... DNS problem: NXDOMAIN looking up A for git.example.comDNS haijaelekeza kwenye seva bado. Rekebisha rekodi, subiri muda wa TTL uishe, kisha uanzishe upya Traefik.
Invalid response from http://git.example.com/.well-known/acme-challenge/... kwenye changamoto ya HTTP: port 80 haifikii Traefik kutoka nje, kwa kawaida ni firewall ya mtoa huduma iliyo mbele ya VPS, si ufw.
Vyeti havitolewi kamwe, na DNS yako iko kwenye Cloudflare ikiwa na wingu la rangi ya chungwa (orange cloud). Cloudflare inamalizia TLS kwenye edge yake na TLS-ALPN-01 haiwezi kukamilika kupitia hapo. Weka rekodi iwe DNS-only wakati wa kutoa cheti, au badilisha utumie changamoto ya DNS-01 kwa kutumia API token. DNS-01 pia ndiyo changamoto pekee inayotoa wildcards.
Redirect loop. Kitu kilicho mbele ya Traefik tayari kinamalizia TLS na kusambaza plaintext kwenye :80; redirect ya entrypoint inairudisha kwenye HTTPS. Ondoa moja kati ya hizo redirect mbili.
Kudumisha utendaji
Unit ya Docker lazima iwezeshwe kuanza wakati wa boot (systemctl is-enabled docker), na restart: unless-stopped huirejesha stack baada ya reboot. Kwa udhibiti wa moja kwa moja, unit ndogo ya systemd inayoendesha docker compose -f /srv/edge/compose.yml up -d ikiwa na RemainAfterExit=yes inakupa systemctl status edge na udhibiti wa mpangilio.
Funga tag ya Traefik (traefik:v3.5, kamwe usitumie latest). Uboreshaji kutoka v2 kwenda v3 ulibadilisha sintaksia ya sheria na majina ya provider, na latest isiyosimamiwa itapakia upya configuration ambayo haielewi tena. Fanya uboreshaji kwa makini: soma maelezo ya uhamiaji, badilisha tag, docker compose up -d traefik, na ufuatilie log. Ikiwa bado unatumia tag ya v2, mwongozo wa uhamiaji wa Traefik v2 kwenda v3 unaelezea kila badiliko la jina, hali ya utangamano (compatibility mode), na njia ya kurudi kwenye toleo la awali inayohifadhi vyeti vyako.
Hifadhi nakala ya ./letsencrypt na volume ya data ya kila app. Traefik haihifadhi hali nyingine yoyote ambayo huwezi kuijenga upya kutoka kwenye faili ya compose.
Nini kinachofeli unapoongeza ukubwa wa mfumo
Kikwazo cha kwanza si kasi ya upitishaji data, bali ni seva moja: Traefik moja kwenye VPS moja ni sehemu moja ya kufeli kwa programu tano, na acme.json ni hifadhi ya faili bapa (flat-file), hivyo matukio mawili ya Traefik yanayoandika humo yataiharibu. Kuongeza uwezo wa mfumo (scaling out) kunamaanisha kuhamisha hifadhi ya cheti nje ya faili, au kumalizia TLS (TLS termination) mahali pengine.
Kikwazo cha pili ni miunganisho ya muda mrefu. Matukio yanayotumwa na seva (Server-sent events), upakiaji wa faili kubwa, na wateja wa polepole hukutana na muda wa kusubiri (timeouts) wa sehemu ya kuingilia (entrypoint); --entryPoints.websecure.transport.respondingTimeouts.readTimeout pamoja na ndugu zake writeTimeout na idleTimeout ndizo sehemu za kurekebisha hili. WebSockets hupita bila kuhitaji usanidi wa ziada.
Kikwazo cha tatu ni diski. --accesslog=true huandika kwenye stdout, na dereva wa json-file wa Docker huweka data hiyo milele isipokuwa kama imewekewa kikomo. Weka logging.options.max-size kwenye huduma ya Traefik, au andika access log kwenye faili na uifanye mzunguko (rotate).
Hakuna hata moja kati ya haya linalohitaji orchestrator. Inahitaji seva unayoimiliki, yenye IP halisi na milango 80 na 443 iliyo wazi kwa ulimwengu; VPS moja ndogo ndiyo orodha nzima ya utegemezi.
FAQ
Je, bado nahitaji certbot nikitumia Traefik?
Hapana. ACME resolver ya Traefik huomba na kusasisha cheti kwa kila hostname inayoielekeza, na kuhifadhi vyote kwenye acme.json. Certbot inabaki kuwa zana sahihi wakati nginx au seva nyingine inashughulikia TLS yenyewe; kutumia zote mbili kwa hostname zilezile kutamaliza tu limit za Let's Encrypt.
Kwa nini container yangu inarudisha 404 kupitia Traefik?
404 inayotolewa na Traefik inamaanisha hakuna router iliyolingana na ombi hilo. Hakikisha container ina traefik.enable=true (ni lazima mara tu exposedByDefault=false inapowekwa), kwamba thamani ya Host() inalingana na jina uliloandika, na kwamba jina la router ni sawa katika kila label ya programu hiyo. Traefik v3 pia inahitaji backticks ndani ya matcher, si alama za kunukuu (quotes).
Kuna tofauti gani kati ya 404 na 502 hapa?
404 inamaanisha uelekezaji (routing) haukufanyika; 502 inamaanisha router ililingana na ombi lakini backend ilikataa muunganisho. Visababishi vya kawaida vya 502 ni container ambayo haijaunganishwa kwenye mtandao wa proxy, na loadbalancer.server.port inayoelekeza kwenye port iliyochapishwa badala ya port ambayo programu inasikiliza ndani ya container. Access log inaonyesha anwani kamili ambayo Traefik ilijaribu kuipigia.
Je, ku-mount Docker socket kwa hali ya read-only inatosha?
Flag ya :ro hufanya faili ya socket kuwa read-only, si API iliyo nyuma yake; maombi ya POST bado hupita humo, na ufikiaji wa Docker API ni sawa na kuwa root kwenye seva mwenyeji. Mpangilio imara zaidi ni container ya docker-socket-proxy iliyoonyeshwa hapo juu, ambayo inaruhusu Traefik kusoma tu taarifa za container na mtandao na kuzuia uandishi wowote.
Je, Traefik inaweza kutoa wildcard certificate?
Inawezekana tu kupitia DNS-01 challenge, kwa kutumia API token ya mtoa huduma wako wa DNS. TLS-ALPN-01 na HTTP-01 kila moja inathibitisha hostname moja na haiwezi kutoa wildcard. DNS-01 pia ndiyo jibu wakati CDN kama Cloudflare inashughulikia TLS mbele ya VPS yako na zile changamoto nyingine mbili hazikamiliki.