返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
DevOps

Traefik, It's Not Easy to Love You: A Heart-Wrenching Journey with Dynamic Reverse Proxy

If Nginx is the steady, dependable good guy, then Traefik is like a maverick geek. It doesn't play by the rules, shuns complicated configuration files, and declares "automatic discovery, everything is automated"—you can set up a reverse proxy using just Docker labels. Doesn't that sound elegant?

曦远 (DealiAxy)约 21 分钟
目录10 个章节

💡 Foreword: The Original Vision Behind the Technology Choice

In today's era where microservices are prevalent and container deployment is becoming the norm, "dynamic reverse proxy" has become especially crucial.
With its native Docker support, automatic routing generation, integrated Let's Encrypt automatic certificates, Dashboard visualization, and other "advanced features," Traefik once became my top choice.

I was full of anticipation, hoping to use it in a small production project. But who would have thought that this journey would leave me questioning everything.

⚡ Getting to Know Traefik: Everything is Beautiful

Traefik is a modern, high-performance reverse proxy and load balancer designed for cloud-native architectures. It natively supports mainstream service discovery mechanisms like Docker, Kubernetes, Consul, and Etcd, allowing it to automatically detect changes in backend services and dynamically update routing rules. Compared to traditional Nginx or Apache, Traefik places greater emphasis on automation and configuration simplicity. Its declarative configuration and Dashboard visual interface greatly simplify the deployment and maintenance of reverse proxies. Whether it's automatic SSL certificate issuance, support for HTTP/2 and WebSocket, or its built-in middleware system, Traefik embodies the elegance and power of the next-generation gateway with its "less is more" philosophy.

Its configuration is truly elegant:

  • 🧠 Automatically identifies Docker services, eliminating tedious manual configuration
  • 🔐 Automatic HTTPS with a single line of configuration to connect to Let's Encrypt
  • 📈 Built-in Dashboard for an at-a-glance view of routes and service status
  • 🔄 Native support for hot reloading, allowing dynamic configuration loading with zero restarts

I once exclaimed: "Isn't this the ideal form of a reverse proxy?"

Deploying Traefik Service

The scenario this time is for use in internal network services, so HTTPS is not required. Therefore, only port 80 needs to be mapped.

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: always
    ports:
      - "80:80"
      - "8080:8080"  # Traefik dashboard port (optional)
    command:
      - "--api.insecure=true"  # Enable Dashboard
      - "--providers.docker"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

networks:
  default:
    name: traefik
    driver: bridge

Integrating with Traefik

The service to be integrated this time is a Spring Boot application. Other unrelated containers are omitted below.

services:
  app:
    build: .
    container_name: hub_project
    environment:
      - SPRING_PROFILES_ACTIVE=prod
    depends_on:
      - redis
    ports:
      - 13080:13080
    networks:
      - default
      - traefik
    labels:
      - "traefik.http.routers.hub-project.rule=Host(project.hub.example.com)"
      - "traefik.http.services.hub-project.loadbalancer.server.port=13080"
      
networks:
  default:
    name: hub_project
  traefik:
    external: true

As you can see, the integration is very simple. You just need to add a labels configuration to the service and specify the domain name and port within it.

🧱 Reality is Harsh: The Cost of Dynamics is Complexity

One day, my service suddenly started returning 404, and I couldn't figure out why. After investigation, I discovered:

🔍 Another container reused the same routers and services names, causing a conflict!

After fixing that, things returned to normal, but soon Gateway Timeout appeared again — this time because the backend service was only listening on 127.0.0.1, and Traefik couldn't connect at all. Later, after a restart, the service wasn't re-added to the traefik network, so Traefik couldn't detect it.

These issues made me realize:

IssueCause
404 Not FoundLabel conflict, service not loaded, not joined to the network
504 Gateway TimeoutBackend listening on 127.0.0.1 instead of 0.0.0.0
Route disappearingContainer not joined to the Traefik network or Docker event not fired
Anomaly after restartTraefik didn't detect the change in time or state wasn't refreshed

🌀 It's not Traefik's fault, but it's just too easy to fall into these pitfalls.

🔧 Why does this happen? Traefik's "dynamic design" is a double-edged sword

Traefik's core philosophy is:

"You mark the services (labels), and I'll handle the proxy automatically."

While this drastically reduces configuration effort, it also introduces several uncontrollable factors:

  • Network isolation between containers must be correctly configured
  • The naming of each service/router must be unique
  • The application must listen on the correct address (0.0.0.0) for Traefik to access it
  • Container status, restarts, and network changes can all cause Traefik to "lose track of the service"

Coupled with the fact that Traefik itself does not cache state and loads everything dynamically, debugging becomes a mystical art: the service appears perfectly fine, yet access results in timeouts or 404 errors.

😮‍💨 Saying "I Love You" Isn't Easy: Moments That Exhaust My Soul

  • Changed the configuration but the Dashboard showed no changes, forcing me to repeatedly restart the container.
  • The service responds to curl, but Traefik couldn't access it—the issue was the wrong listening address.
  • The dashboard clearly showed the router as active, but in reality, the frontend just kept loading.
  • Forgot to add .entrypoints=web to the configuration labels—half an hour of debugging ensued.

Every troubleshooting session feels like a spiritual practice. I even start to wonder: Is it something I did wrong?

🍃 Final Switch: Caddy, Simple Yet More Reliable

Just when I was nearly driven to the point of giving up, I decided to give Caddy a try.

Its configuration is surprisingly simple:

project.hub.example.com {
    reverse_proxy hub_project:13080
}
  • ✅ Seamless automatic HTTPS setup
  • ✅ No labels or complex network configurations required
  • ✅ Determinism and controllability from static configuration
  • ✅ Easier debugging—configuration is the single source of truth

While its scalability for larger projects might be slightly limited, for lightweight projects like mine, it’s absolutely perfect.

✅ Summary: Traefik is respectable, but not necessarily for everyone

Traefik is a double-edged sword. It is perfectly suited for:

  • Kubernetes environments
  • Team collaboration projects with high complexity and frequent changes in Docker Compose services
  • DevOps teams familiar with Docker network models and service health status

For someone like me, who manages small projects and prefers lightweight deployments with Docker Compose:

❝ Static reverse proxy + explicit configuration can actually be a relief. ❞

If Nginx is the steady and reliable good friend, then Traefik is like an unconventional geek. It plays by its own rules, rejects cumbersome configuration files, and claims “auto-discovery, everything is automatic.” You can set up a reverse proxy just by using Docker labels—doesn’t that sound elegant? But when you actually bring it up, you find the container is clearly online, the Dashboard displays normally, yet the page shows a 404, and there’s no sign of SSL certificate renewal. You restart it, and suddenly it works, with an expression that says, “I’m fine, it’s you who doesn’t understand me.” Traefik is sometimes like a cool-tempered lover—powerful, good-looking, but communicating with it always feels exhausting. Using it is either debugging configurations or achieving “metaphysical fixes” through restarts, making one cannot help but sigh: Traefik, it’s not easy to say I love you.

✍️ Afterword: No Aversion, Maybe We'll Meet Again

I still have respect for Traefik—it embodies so many excellent design philosophies—but this time, I chose to set it aside.

Perhaps in the future, with more mature CI/CD pipelines or in Kubernetes, I will reconsider it.

_EOF_

Traefik, It's Not Easy to Love You: A Heart-Wrenching Journey with Dynamic Reverse Proxy

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…