DEV Community

Abdullah Sheikh
Abdullah Sheikh

Posted on

How to Set Up Traefik as a Reverse Proxy with Docker in Minutes

Step‑by‑step guide to install, configure, and run Traefik in Docker so you can route traffic to multiple containers effortlessly

Before We Start: What You'll Walk Away With

When you finish this guide you’ll have a live Traefik reverse proxy Docker setup that starts with a single docker‑compose up command.

Adding another micro‑service will be as simple as dropping a label on its container—Traefik will instantly discover it and route traffic, just like a new restaurant appearing on Google Maps when you open the app.

You’ll also walk away with a clear picture of the three core pieces—entrypoints, routers, and services—without drowning in terminology.

  • Working container: A ready‑to‑go Traefik instance defined in docker-compose.yml, listening on ports 80 and 443, and serving a dashboard you can reach at http://localhost:8080.

  • One‑label addition: Any new Docker service gets a traefik.http.routers... label, and Traefik automatically creates the route—think of it as handing a suitcase to a conveyor belt that knows exactly where to send it.

Core concepts simplified:

  • Entrypoint – the door (port) where traffic enters.

  • Router – the map that decides which door leads to which service.

  • Service – the final destination, the container that handles the request.

Cheat sheet:

  • docker compose up -d – launch everything.

  • docker compose logs traefik – watch routing in real time.

  • docker inspect – verify labels are applied.

Tools & tips:

  • Use docker network create traefik-public so all services share the same network.

  • Keep the traefik.yml file minimal; defaults cover most needs.

  • Enable the dashboard only on localhost for security.

Now you’re set to spin up Traefik and let it do the heavy lifting for your Docker stack.

What Traefik Actually Is (No Jargon)

Traefik is a cloud‑native reverse proxy that lives next to your Docker containers and rewrites its routing table the moment a new service appears or disappears. It talks directly to the Docker daemon, reads labels you add to each container, and instantly knows which hostname or path should point at which container.

Imagine a busy downtown intersection with a traffic officer who never sleeps. Cars (incoming HTTP requests) pull up, and the officer flashes a sign directing each driver to the right lane (the right container) based on the destination they typed into their GPS. If a new lane opens, the officer updates the signs on the fly; if a lane closes, the signs disappear. That officer is Traefik, and the intersection is your Docker‑compose network.

  • It detects containers automatically—no manual IP hunting.

  • It respects the rules you define in Docker labels, so you control routing where you write your docker-compose.yml.

  • It handles TLS certificates for you, pulling them from Let’s Encrypt without extra steps.

Because Traefik updates in real time, you can spin up a new microservice, tag it with traefik.http.routers.myapp.rule=Host(app.example.com), and the traffic starts flowing instantly. No restarts, no fiddling with nginx configs, just a single source of truth that lives alongside your containers.

Bottom line: think of Traefik reverse proxy Docker as the ever‑watchful traffic controller that keeps your services reachable and your network tidy.

The 3 Mistakes Everyone Makes With Traefik

Most people hit a wall with Traefik reverse proxy Docker before they even see a single request hit their service.

  • Forgetting to expose the right entrypoint ports. It’s like ordering a pizza and never opening the delivery door – the driver can’t get the food in. If ports for 80:80 or 443:443 aren’t listed in docker‑compose.yml, Traefik has nowhere to listen and you’ll get 502 errors. Double‑check the expose and ports sections match the entrypoints you defined.

  • Mislabeling services or using the wrong label prefix. Think of labels as the street signs that tell Google Maps where to go. Using traefik.http.routers... when you’ve set --providers.docker to expect traefik.docker.* makes Traefik blind to your containers. One typo and the whole stack disappears from the dashboard.

  • Over‑complicating TLS with self‑signed certs. It’s like packing a suitcase with every gadget you own, then forgetting the charger. Instead of generating a maze of certificatesResolvers, start with the built‑in Let’s Encrypt starter: add --certificatesresolvers.myresolver.acme.email and --certificatesresolvers.myresolver.acme.storage. Traefik will handle renewals automatically.

Quick cheat sheet:

  • Expose ports: ports: - "80:80" - "443:443"

  • Label prefix: traefik.http. for routers, services, middlewares

  • Let’s Encrypt starter: --certificatesresolvers.myresolver.acme.email=you@example.com

Fix these three, and Traefik will stop being the mystery box in your Docker stack.

How to Set Up Traefik: Step‑By‑Step

Grab a folder, drop a docker-compose.yml inside, and you’re ready to start.

  • Create a project directory and touch docker-compose.yml. This is like opening a new notebook for a recipe you’ll follow step‑by‑step.

  • Paste the Traefik service definition into the file. Use the official image, turn on the Docker provider, and expose ports 80 and 443. It’s the same as telling a delivery driver which streets are open for traffic.

  • Write a static config file named traefik.yml. Define entryPoints for web (port 80) and websecure (port 443) and enable Let’s Encrypt. Think of this as setting up the highway signs before the cars arrive.

  • Mount both traefik.yml and the Docker socket into the container:

services:
  traefik:
    image: traefik:v2.10
    command:
      - --providers.docker
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
      - --certificatesresolvers.myresolver.acme.email=you@example.com
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - ./traefik.yml:/etc/traefik/traefik.yml
      - /var/run/docker.sock:/var/run/docker.sock
      - ./letsencrypt:/letsencrypt
Enter fullscreen mode Exit fullscreen mode
  • Add a simple web service, for example an nginx container, and tag it with Traefik labels that specify the host rule and TLS resolver.
nginx:
    image: nginx:alpine
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.rule=Host(`yourdomain.test`)"
      - "traefik.http.routers.nginx.entrypoints=websecure"
      - "traefik.http.routers.nginx.tls=true"
      - "traefik.http.routers.nginx.tls.certresolver=myresolver"
Enter fullscreen mode Exit fullscreen mode
  • Spin everything up with docker compose up -d and visit http://localhost:8080 to see the Traefik dashboard.

  • Open https://yourdomain.test in a browser. If the page loads with a valid certificate, the reverse proxy is working.

That’s the whole setup—quick, clean, and ready for production.

A Real Example: Deploying a Blog and API Behind Traefik

Maya wants her new Hugo blog and Node API reachable at https URLs without fiddling with certificates.

She creates a docker-compose.yml that defines three services.

services:
  traefik:
    image: traefik:v2.10
    command:
      - --providers.docker=true
      - --providers.file.directory=/etc/traefik
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.le.acme.email=maya@example.com
      - --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
      - --certificatesresolvers.le.acme.tlschallenge=true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./config:/etc/traefik
      - traefik-letsencrypt:/letsencrypt
    labels:
      - traefik.enable=true

  blog:
    image: nginx:alpine
    volumes:
      - ./blog/public:/usr/share/nginx/html:ro
    labels:
      - traefik.http.routers.blog.rule=Host(`blog.example.com`)
      - traefik.http.routers.blog.tls=true
      - traefik.http.routers.blog.tls.certresolver=le

  api:
    image: node:14
    working_dir: /app
    command: ["node", "server.js"]
    volumes:
      - ./api:/app
    labels:
      - traefik.http.routers.api.rule=Host(`api.example.com`)
      - traefik.http.routers.api.tls=true
      - traefik.http.routers.api.tls.certresolver=le

volumes:
  traefik-letsencrypt:
Enter fullscreen mode Exit fullscreen mode

She drops a tiny traefik.yml into config/ to tell Traefik where to look for dynamic configs.

log:
  level: INFO
api:
  dashboard: true
Enter fullscreen mode Exit fullscreen mode
  • Running docker compose up -d is like handing the keys to a valet; Traefik immediately grabs the TLS certificates from Let’s Encrypt and routes traffic.

  • Now https://blog.example.com serves Maya’s static site, and https://api.example.com handles her Node endpoints, both protected by a Traefik reverse proxy Docker stack.

  • Tip: Keep the acme.json file readable only by root ( chmod 600 ) to protect private keys.

  • Tip: Use the Traefik dashboard (http://localhost:8080/dashboard/) to verify routers are live.

The Tools That Make This Easier

Grab the right helpers and the whole Traefik reverse proxy Docker setup feels like ordering a pizza with a clear menu.

  • Docker Desktop (2025 edition) – The visual dashboard is your restaurant’s order board. You can see containers, volumes, and networks at a glance, start or stop services with a click, and drag‑and‑drop a docker‑compose.yml into the UI to spin everything up instantly.

  • VS Code with the Docker extension – Think of it as a chef’s knife that’s always sharp. It highlights YAML syntax, offers autocomplete for labels, and lets you tail logs from the sidebar, so you spot mis‑typed routers before they bite.

  • Portainer Community Edition – This is the Google Maps for your Docker world. The visual Compose editor lets you tweak services, and the health dashboard flags containers that restart or report errors, saving you from hunting through terminal output.

  • Traefik Pilot (free tier) – Consider it a real‑time kitchen monitor. It displays every router, service, and TLS certificate on a single page, so you instantly know if a rule isn’t matching or a certificate has expired.

  • mkcert – The fast‑track to trusted TLS for local dev, like a passport office that prints a visa on demand. Run mkcert "*.local" and you get a cert that browsers accept without warnings.

With these tools in your toolbox, wiring Traefik into Docker becomes a smooth, repeatable process.

Quick Reference: Traefik Reverse Proxy Cheat Sheet

Grab this cheat sheet and keep it open while you spin up Traefik – every line maps to a concrete action.

  • Docker‑Compose file: define a traefik service, publish 80:80 and 443:443, mount /var/run/docker.sock:/var/run/docker.sock. Think of it as ordering a pizza with both crust and cheese sides ready.

  • traefik.yml: set entrypoints web (port 80) and websecure (port 443), plus ACME block for Let’s Encrypt. It’s like giving Google Maps the start and destination points before the route is drawn.

  • Labels on each app: add traefik.http.routers.myapp.rule=Host(myapp.example.com) and traefik.http.routers.myapp.tls=true. Labels are the luggage tags that tell the suitcase (your container) which carousel (router) to go to.

Bring it online: run

docker compose up -d
Enter fullscreen mode Exit fullscreen mode

then visit http://localhost:8080 for the dashboard. If the UI pops up, you’ve just turned the key in the ignition.
Common pitfalls:

  • Forgot to expose ports – Traefik stays hidden like a shop without a sign.

  • Used label: instead of labels: or missed the traefik. prefix – the router can’t read the address.

  • Mixed up TLS: set tls=true but left entryPoints on web only – you’ll get a “connection not secure” warning.

  • Example fix from Alice, a backend engineer: she added traefik.http.routers.myapp.tls.certresolver=myresolver and the HTTPS site worked instantly.

Keep this list handy; it’s the shortcut you’ll reach for every time you deploy a new service behind Traefik.

What to Do Next

Ready to get more mileage out of your Traefik reverse proxy Docker setup? Here are three steps you can take right now.

  • Easy – add a new service. Think of it like ordering a side dish at a restaurant: you just copy the existing label pattern and specify the new container. For example, to expose a Redis admin UI, drop these labels into the service definition:
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.redis-admin.rule=Host(`redis.local`)"
  - "traefik.http.services.redis-admin.loadbalancer.server.port=80"
Enter fullscreen mode Exit fullscreen mode
  • Restart docker-compose up -d and the UI appears at http://redis.local.

  • Medium – enable middleware. Middleware is like adding a traffic cop to a busy intersection. You can limit request bursts or require a password before anyone reaches your internal tools.

labels:
  - "traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$H6uskkkW$$IgXLP6ewTrSuA1u5cG3c41"
  - "traefik.http.routers.redis-admin.middlewares=auth"
Enter fullscreen mode Exit fullscreen mode
  • Swap basicauth for ratelimit if you just need to curb traffic spikes.

  • Hard – scale with Swarm or Kubernetes. Picture packing a suitcase for a long trip: you need compartments, weight limits, and a plan for adding more items later. In a Swarm, define a traefik service with --providers.docker.swarmMode=true; in Kubernetes, deploy the Helm chart and annotate pods with traefik.ingress.kubernetes.io/router.entrypoints.

docker service create \
  --name traefik \
  --publish 80:80 \
  --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
  traefik:latest \
  --providers.docker.swarmMode=true \
  --entrypoints.web.address=:80
Enter fullscreen mode Exit fullscreen mode
  • After the service is up, add the same label syntax to any Swarm stack to have Traefik route it automatically.

Got stuck or have a creative use‑case? Drop a comment below – I love hearing how you’re using Traefik!



About the Author

Abdullah Sheikh is the Founder & CEO at Exteed, where he leads a team of skilled developers specializing in Web2 and Web3 applications, Custom Smart Contracts, and Blockchain solutions.

With 6+ years of experience, Abdullah has built CRMs, Crypto Wallets, DeFi Exchanges, E-Commerce Stores, HIPAA Compliant EMR Systems, and AI-powered systems that drive business efficiency and innovation.

His expertise spans Blockchain, Crypto & Tokenomics, Artificial Intelligence, and Web Applications; building reliable and smooth web apps that fit the client’s goals and requirements.

📧 info@abdullah-sheikh.com · 🔗 LinkedIn · 🌐 abdullah-sheikh.com

Top comments (0)