Ravindra BagaleCourses & study guides मराठी

Chapter 51: Docker Networking: Port Publishing, Bridge, Host, None, Overlay, Macvlan, DNS and Every Network Command

51.9 Traefik: route many sites by labels with automatic HTTPS (Let's Encrypt)

Friends, this is the last lesson of the networking chapter. One server, many websites, one port 443. Today Traefik reads container labels, sends each domain to the right container, and gets free HTTPS certificates by itself.

1. Start from a story

Rohit runs a small agency in Nagpur. He hosts websites for a bakery, a dentist and a coaching class, all on one cheap server.

Only one program can listen on port 443. So who decides that bakery.example.com goes to the bakery container and dentist.example.com goes to the dentist container? Earlier Rohit edited an nginx file by hand for every new client and renewed certificates by hand every three months. Twice he forgot, and a client's site showed a red warning.

Then he moved to Traefik. Traefik watches Docker. When a new container starts with the right labels, Traefik adds a route at once, and asks Let's Encrypt for a certificate. No config file to edit, no reload, no forgotten renewals.

In this lesson we build Rohit's setup: Traefik in front, two sites behind it, labels for routing, a redirect from HTTP to HTTPS, and automatic certificates. We use example.com names; on your own server use your real domains.

Internetports 80 and 443Traefikreads Host headerbakerybakery.example.comdentistdentist.example.comcoachingcoaching.example.com
Picture 1: one door, many shops

2. Start Traefik

Step 1: A shared network for the proxy

Why: Traefik and the sites must share a network.

What: We create one external network named proxy and attach every site to it.

Example 1: Create

Type this:

docker network create proxy

You will see:

e7f1a2...

What it means: Shared by all stacks.

Example 2: Check

Type this:

docker network ls --filter name=proxy --format '{{.Name}} {{.Driver}}'

You will see:

proxy bridge

What it means: Ready.

Example 3: Why

Type this:

docker network inspect proxy -f '{{len .Containers}}'

You will see:

0

What it means: Empty now; sites join later.

Step 2: Run Traefik with the Docker provider

Why: Traefik learns about containers from the Docker socket.

What: Mount the socket read-only and turn off auto-exposing every container.

Example 4: Run

Type this:

docker run -d --name traefik --network proxy -p 80:80 -p 443:443 -v /var/run/docker.sock:/var/run/docker.sock:ro traefik:v3.1 --providers.docker=true --providers.docker.exposedbydefault=false --entrypoints.web.address=:80 --entrypoints.websecure.address=:443

You will see:

9a8b...

What it means: Traefik is the front door.

Example 5: Logs

Type this:

docker logs traefik 2>&1 | tail -1

You will see:

level=info msg="Starting provider *docker.Provider"

What it means: Watching Docker.

Example 6: Version

Type this:

docker exec traefik traefik version | head -1

You will see:

Version:      3.1.2

What it means: Running v3.

Step 3: The dashboard (local only)

Why: See routes while you learn.

What: Enable the API and publish it only on 127.0.0.1.

Example 7: Flag

Type this:

--api.dashboard=true --api.insecure=true and -p 127.0.0.1:8081:8080

You will see:

(added to the run line)

What it means: Never open this to the internet.

Example 8: Open

Type this:

curl -s 127.0.0.1:8081/api/http/routers | head -c 60

You will see:

[{"entryPoints":["web"],"service":"api@internal"

What it means: Routers listed as JSON.

Example 9: From outside

Type this:

curl -s -m3 http://SERVER_IP:8081

You will see:

curl: (28) Connection timed out

What it means: Correctly hidden.

3. Route by labels

Step 4: traefik.enable

Why: Opt in each container.

What: Because exposedbydefault is false, only labelled containers get routes.

Example 10: Plain container

Type this:

docker run -d --name hidden --network proxy traefik/whoami:v1.10

You will see:

3c4d...

What it means: No labels, no route.

Example 11: Check

Type this:

curl -s 127.0.0.1:8081/api/http/routers | grep -c hidden

You will see:

0

What it means: Not exposed.

Example 12: Opt in

Type this:

docker run -d --name bakery --network proxy -l traefik.enable=true traefik/whoami:v1.10

You will see:

5e6f...

What it means: Now Traefik sees it.

Step 5: Host rule

Why: Send a domain to a container.

What: The router rule matches the Host header of the request.

Example 13: Run with rule

Type this:

docker run -d --name bakery --network proxy -l traefik.enable=true -l 'traefik.http.routers.bakery.rule=Host(`bakery.example.com`)' -l traefik.http.routers.bakery.entrypoints=web traefik/whoami:v1.10

You will see:

7a8b...

What it means: Domain to container.

Example 14: Test

Type this:

curl -s -H 'Host: bakery.example.com' localhost | head -1

You will see:

Hostname: 7a8b9c0d1e2f

What it means: The bakery answered.

Example 15: Unknown host

Type this:

curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: nobody.example.com' localhost

You will see:

404

What it means: No route, no site.

Step 6: Second site, zero config edits

Why: Adding a client is just starting a container.

What: Same labels, new name and new domain.

Example 16: Dentist

Type this:

docker run -d --name dentist --network proxy -l traefik.enable=true -l 'traefik.http.routers.dentist.rule=Host(`dentist.example.com`)' traefik/whoami:v1.10

You will see:

1f2e...

What it means: Live in a second.

Example 17: Test

Type this:

curl -s -H 'Host: dentist.example.com' localhost | head -1

You will see:

Hostname: 1f2e3d4c5b6a

What it means: Right site.

Example 18: Routers

Type this:

curl -s 127.0.0.1:8081/api/http/routers | grep -o '"name":"[a-z]*@docker' 

You will see:

"name":"bakery@docker
"name":"dentist@docker

What it means: Both routes exist.

Step 7: Path rules and the service port

Why: More rules, and which port to use.

What: PathPrefix routes by URL path. loadbalancer.server.port tells Traefik the app port.

Example 19: Path

Type this:

-l 'traefik.http.routers.api.rule=Host(`coaching.example.com`) && PathPrefix(`/api`)'

You will see:

(label)

What it means: Only /api goes here.

Example 20: Port

Type this:

-l traefik.http.services.api.loadbalancer.server.port=3000

You will see:

(label)

What it means: The app listens on 3000.

Example 21: Test

Type this:

curl -s -o /dev/null -w '%{http_code}\n' -H 'Host: coaching.example.com' localhost/api/health

You will see:

200

What it means: Path route works.

1. New routerwith certresolver label2. Traefik asksLet's Encrypt3. HTTP challengeLE calls port 804. Certificatesaved in acme.json5. Renewautomatically before expiry
Picture 2: how a certificate is issued

4. Automatic HTTPS

Step 8: A certificate resolver

Why: Tell Traefik how to get certificates.

What: Use the HTTP challenge on port 80 and store certificates in a volume.

Example 22: Flags

Type this:

--certificatesresolvers.le.acme.email=admin@example.com --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json --certificatesresolvers.le.acme.httpchallenge.entrypoint=web

You will see:

(added to the run line)

What it means: Use your own email.

Example 23: Volume

Type this:

-v traefik-certs:/letsencrypt

You will see:

(added to the run line)

What it means: Certificates survive restarts.

Example 24: File mode

Type this:

docker exec traefik ls -l /letsencrypt/acme.json

You will see:

-rw------- 1 root root 3412 acme.json

What it means: 600 permissions; Traefik insists.

Step 9: Use the resolver on a site

Why: Two labels turn on HTTPS.

What: Point the router to websecure and the le resolver.

Example 25: Labels

Type this:

-l traefik.http.routers.bakery.entrypoints=websecure -l traefik.http.routers.bakery.tls.certresolver=le

You will see:

(labels)

What it means: HTTPS for the bakery.

Example 26: Logs

Type this:

docker logs traefik 2>&1 | grep -i 'certificate obtained'

You will see:

level=info msg="Certificate obtained for domains [bakery.example.com]"

What it means: Issued in seconds.

Example 27: Check

Type this:

curl -sI https://bakery.example.com | head -1

You will see:

HTTP/2 200

What it means: Green lock in the browser.

Step 10: Redirect HTTP to HTTPS

Why: Never serve the plain site.

What: One entrypoint setting redirects every site.

Example 28: Flags

Type this:

--entrypoints.web.http.redirections.entrypoint.to=websecure --entrypoints.web.http.redirections.entrypoint.scheme=https

You will see:

(added to the run line)

What it means: Global redirect.

Example 29: Test

Type this:

curl -sI http://bakery.example.com | head -2

You will see:

HTTP/1.1 308 Permanent Redirect
Location: https://bakery.example.com/

What it means: Sent to HTTPS.

Example 30: Staging first

Type this:

--certificatesresolvers.le.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory

You will see:

(for testing)

What it means: Avoids rate limits while learning.

Step 11: Everything in Compose

Why: Keep it in one file per site.

What: Traefik in its own stack, each site in its own stack, joined by the external proxy network.

Example 31: Site file

Type this:

printf 'services:\n  web:\n    image: nginx:1.27\n    networks: [proxy]\n    labels:\n      - traefik.enable=true\n      - traefik.http.routers.bakery.rule=Host(`bakery.example.com`)\n      - traefik.http.routers.bakery.tls.certresolver=le\nnetworks:\n  proxy:\n    external: true\n' > compose.yaml

You will see:

(no output)

What it means: Labels live with the site.

Example 32: Up

Type this:

docker compose up -d

You will see:

Container bakery-web-1  Started

What it means: Route and certificate appear.

Example 33: Remove

Type this:

docker compose down

You will see:

Container bakery-web-1  Removed

What it means: Route disappears by itself.

Step 12: Middlewares

Why: Small add-ons that change requests on the way.

What: Labels can add basic auth, security headers or rate limits to a router.

Example 34: Rate limit

Type this:

-l traefik.http.middlewares.slow.ratelimit.average=20 -l traefik.http.routers.bakery.middlewares=slow

You will see:

(labels)

What it means: About 20 requests per second per client.

Example 35: Headers

Type this:

-l traefik.http.middlewares.sec.headers.stsSeconds=31536000

You will see:

(label)

What it means: Browsers remember to use HTTPS.

Example 36: Test

Type this:

for i in $(seq 40); do curl -s -o /dev/null -w '%{http_code}\n' https://bakery.example.com; done | sort | uniq -c

You will see:

22 200
18 429

What it means: Extra requests get 429 Too Many Requests.

Step 13: Troubleshooting Traefik

Why: Know the usual suspects.

What: Most problems are a missing network, a wrong port or DNS not pointing to the server.

Example 37: Wrong network

Type this:

docker inspect bakery -f '{{range $k,$v := .NetworkSettings.Networks}}{{$k}} {{end}}'

You will see:

bridge

What it means: Not on proxy; Traefik gives 504 Gateway Timeout.

Example 38: DNS

Type this:

dig +short bakery.example.com

You will see:

203.0.113.10

What it means: Must be this server for the challenge.

Example 39: Errors

Type this:

docker logs traefik 2>&1 | grep -i error | tail -1

You will see:

level=error msg="Unable to obtain ACME certificate" error="... timeout during connect"

What it means: Port 80 blocked in the security group.

5. Safety notes

The Docker socket gives full control of the host. Mount it read-only, never publish the dashboard to the internet, and for stricter setups put a socket proxy between Traefik and Docker.

Keep acme.json in a volume and back it up; losing it means asking for all certificates again, and Let's Encrypt has weekly limits. Practise against the staging server first, then switch to production.

Finally, keep Traefik itself updated and pin a version tag such as v3.1 instead of latest, so an upgrade happens when you choose, not on a random restart.

Check yourself

Q1. Which label makes Traefik route a container when exposedbydefault is false?

traefik.enable=true.

Q2. Which rule sends a domain to a container?

Host(`name`).

Q3. Why is port 80 needed for Let's Encrypt?

For the HTTP challenge.

Q4. What does a 504 from Traefik usually mean?

The container is not on the shared network.

Friends, Traefik is the smart receptionist: it reads the labels, sends each visitor to the right shop and keeps every lock fresh. Did you understand? Let us try it once more. The networking chapter is complete; in the next chapter we move to Docker Compose in depth.

Ravindra Bagale's Tip

Always test with the Let's Encrypt staging server first. Switch to production only when the staging certificate works.

Lab: try at home

  1. Create the proxy network and start Traefik.
  2. Run two whoami sites with Host rules.
  3. Test both with curl -H Host.
  4. Open the dashboard on 127.0.0.1 only.
  5. Add the staging resolver and the HTTP to HTTPS redirect.
  6. Move one site into its own compose.yaml.

Recap

  • Traefik routes by labels; no config file per site.
  • exposedbydefault=false plus traefik.enable=true.
  • Host and PathPrefix rules pick the container.
  • certresolver gives automatic HTTPS.
  • Port 80 must be open for the HTTP challenge.
  • Mount the socket read-only and hide the dashboard.

Lab

  1. Publish nginx on 8080 and on 127.0.0.1 only.
  2. Connect API and MySQL by name on a user-defined bridge.
  3. Run a job with --network none.
  4. Debug a network with netshoot.

Practice task

Build a frontend network and an --internal backend network. Put nginx on both, the API on both and MySQL only on backend. Prove MySQL cannot reach the internet and nginx cannot be skipped.

Ravindra Bagale's Tip

First check that the app inside the container listens on 0.0.0.0. Listening on 127.0.0.1 is the mistake we find every day.

In short

  • -p publishes; EXPOSE only documents.
  • User-defined bridges give DNS by name.
  • host shares the host stack; none has no network.
  • Overlay spans Swarm hosts.
  • macvlan puts containers on the real LAN.
  • Debug with netshoot in the same namespace.

Ravi Sir's Cards for this lesson

मराठी cards