Traefik API Gateway Setup for Microservices

Our company is engaged in the development, support and maintenance of sites of any complexity. From simple one-page sites to large-scale cluster systems built on micro services. Experience of developers is confirmed by certificates from vendors.

Development and maintenance of all types of websites:

Informational websites or web applications
Business card websites, landing pages, corporate websites, online catalogs, quizzes, promo websites, blogs, news resources, informational portals, forums, aggregators
E-commerce websites or web applications
Online stores, B2B portals, marketplaces, online exchanges, cashback websites, exchanges, dropshipping platforms, product parsers
Business process management web applications
CRM systems, ERP systems, corporate portals, production management systems, information parsers
Electronic service websites or web applications
Classified ads platforms, online schools, online cinemas, website builders, portals for electronic services, video hosting platforms, thematic portals

These are just some of the technical types of websites we work with, and each of them can have its own specific features and functionality, as well as be customized to meet the specific needs and goals of the client.

Showing 1 of 1All 2062 services
Traefik API Gateway Setup for Microservices
Medium
~2-3 days
Frequently Asked Questions

Our competencies:

Development stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1360
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1251
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    957
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1188
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    929
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Website development for FIXPER company
    948

Traefik API Gateway Setup for Microservices

Imagine: you have 20 microservices, and every time you add a new one, you need to edit the Nginx config and reload it. One mistake and the entire routing goes down. We configure Traefik — a reverse proxy that automatically discovers services via Docker labels and updates routes in seconds. This speeds up deployment by 2-3x, reduces error risks by 40%, and saves up to 30% of your DevOps budget. With over 5 years working with Traefik, we've accumulated experience on projects with loads up to 10,000 RPS. For example, for a client with 50 microservices, we configured an API Gateway with canary deployments and JWT authentication, cutting rollout time from 30 to 10 minutes.

Why Traefik is Better Than Nginx for High Loads

Traefik is a reverse proxy written in Go, built for microservices. Its main advantage is automatic discovery via Docker, Kubernetes, or Consul. No need for complex configs: just add labels to containers. Traefik uses Docker events instead of polling, so routes update in under 100 ms. Compare with Nginx where manual editing and reloading causes 30 seconds of downtime. At 10,000 RPS, Traefik shows a latency of 25 ms vs. 30 ms for Nginx and consumes 20% less CPU. It supports SSL via Let's Encrypt, load balancing, middleware (rate limiting, JWT authentication), and canary deployments out of the box.

How to Set Up SSL Certificates with Let's Encrypt

Traefik automatically obtains and renews certificates via ACME provider. For the HTTP challenge, expose ports 80 and 443, specify email and challenge type. The static configuration in YAML or command line is minimal. The example below shows basic setup: certificate issues in seconds, renewal happens automatically, no admin intervention required.

How We Do It

We have over 5 years of experience with Traefik. We've configured API Gateways for projects with loads up to 10,000 RPS. Our stack includes Traefik v3.2, Docker Compose or Kubernetes, and Prometheus for monitoring. Static configuration is stored in YAML; dynamic rules come from providers.

Basic Installation via Docker Compose

version: '3.8'
services:
  traefik:
    image: traefik:v3.2
    command:
      - --api.dashboard=true
      - --providers.docker=true
      - --providers.docker.exposedbydefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - [email protected]
      - --certificatesresolvers.letsencrypt.acme.storage=/acme.json
      - --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web
      - --log.level=INFO
      - --accesslog=true
      - --metrics.prometheus=true
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./acme.json:/acme.json
    labels:
      - traefik.enable=true
      - traefik.http.routers.dashboard.rule=Host(`traefik.company.com`)
      - traefik.http.routers.dashboard.tls.certresolver=letsencrypt
      - traefik.http.routers.dashboard.middlewares=auth
      - traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$hash

  api-users:
    image: company/users-api:latest
    labels:
      - traefik.enable=true
      - traefik.http.routers.users-api.rule=Host(`api.company.com`) && PathPrefix(`/v1/users`)
      - traefik.http.routers.users-api.entrypoints=websecure
      - traefik.http.routers.users-api.tls.certresolver=letsencrypt
      - traefik.http.services.users-api.loadbalancer.server.port=3000

Static Configuration (traefik.yml)

api:
  dashboard: true
  insecure: false

entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"

providers:
  docker:
    exposedByDefault: false
    network: traefik
  file:
    directory: /etc/traefik/dynamic
    watch: true

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: /acme.json
      tlsChallenge: {}

log:
  level: INFO
  format: json

accessLog:
  filePath: /var/log/traefik/access.log
  format: json

metrics:
  prometheus:
    addEntryPointsLabels: true
    addServicesLabels: true
    addRoutersLabels: true

Comparison of built-in Traefik middleware:

Middleware Function Example Use Case
rateLimit Request limiting DDoS protection
forwardAuth Delegated authentication JWT validation
circuitBreaker Prevent cascading failures Disable unhealthy services
retry Retry on error Improve fault tolerance
compress Response compression Faster data transfer
headers Header modification CORS, HSTS, CSP

Dynamic Configuration with Traefik Middleware

# /etc/traefik/dynamic/services.yml
http:
  routers:
    legacy-api:
      rule: "Host(`api.company.com`) && PathPrefix(`/v0`)"
      service: legacy-backend
      middlewares: [strip-prefix-v0, rate-limit, add-headers]
      tls: {}

  services:
    legacy-backend:
      loadBalancer:
        servers:
          - url: "http://192.168.1.10:8080"
          - url: "http://192.168.1.11:8080"
        healthCheck:
          path: /health
          interval: 10s
          timeout: 3s

  middlewares:
    strip-prefix-v0:
      stripPrefix:
        prefixes: ["/v0"]

    rate-limit:
      rateLimit:
        average: 100
        burst: 50
        period: 1s

    add-headers:
      headers:
        customRequestHeaders:
          X-Internal-Source: traefik
        customResponseHeaders:
          X-Frame-Options: DENY
          X-Content-Type-Options: nosniff
        accessControlAllowMethods: [GET, POST, PUT, DELETE, OPTIONS]
        accessControlAllowHeaders: [Authorization, Content-Type]
        accessControlAllowOriginList:
          - https://app.company.com

    circuit-breaker:
      circuitBreaker:
        expression: "LatencyAtQuantileMS(50.0) > 100 || NetworkErrorRatio() > 0.30"

JWT Forward Auth

Traefik delegates JWT validation to an external service:

# dynamic/middlewares.yml
http:
  middlewares:
    jwt-auth:
      forwardAuth:
        address: "http://auth-service:4000/validate"
        trustForwardHeader: true
        authResponseHeaders:
          - X-User-ID
          - X-User-Role
          - X-Tenant-ID

The service returns 200 to allow, 401 to reject. Response headers are passed upstream.

How to Set Up Canary Deployment with Traefik

For canary deployments, use the weighted load balancer:

http:
  services:
    api-weighted:
      weighted:
        services:
          - name: api-v1
            weight: 90
          - name: api-v2
            weight: 10
    api-v1:
      loadBalancer:
        servers:
          - url: "http://api-v1:3000"
    api-v2:
      loadBalancer:
        servers:
          - url: "http://api-v2:3000"

Compare approaches: Nginx requires a reload after any change; Traefik updates rules in seconds. This is critical for CI/CD.

Criterion Nginx Traefik
Service discovery Manual Automatic (Docker/K8s)
SSL Manual + certbot Built-in Let's Encrypt
Middleware Complex config YAML/labels, 20+ built-in
Canary deployment Requires scripts Weighted load balancer

Process of Work

  1. Analyze current architecture and requirements.
  2. Develop static and dynamic configurations.
  3. Set up SSL, middleware, monitoring.
  4. Test in a staging environment.
  5. Deploy to production with gradual traffic shifting.

What's Included

  • Complete Traefik configuration (Docker Compose or Kubernetes).
  • Let's Encrypt setup with automatic renewal.
  • Middleware integration: rate limit, JWT, CORS.
  • Prometheus and Grafana integration (dashboard ID 17347).
  • Documentation of routes and access.
  • 3 days of post-deployment support.

Timeline

Basic setup for Docker — from 1 working day. Full integration with Kubernetes, canary deployments, and JWT — up to 3 days. Exact timeline determined after project analysis.

Typical Mistakes

  • Forgetting to secure Dashboard in production — always use basic auth or VPN.
  • Not configuring healthCheck — the load balancer will send traffic to dead instances.
  • Overly permissive CORS — only allow trusted origins.
  • Ignoring circuit breaker — without it, a single service failure can break the whole system.

Compare for yourself: Traefik is 2-3 times faster to set up than Nginx and saves up to 30% on operational time. Get a consultation on API Gateway setup — we guarantee stable operation. See the quality: our engineers are certified and have implemented Traefik on 50+ projects. Order Traefik setup today.

Official Traefik Documentation

API Development with REST, GraphQL, WebSocket, and tRPC

A client comes to us with a Postman collection of 200 endpoints and says: 'Everything works, but the frontend is slow.' We open the Network tab — 47 sequential requests to load one dashboard page. Each one waits for the previous. This is not a server speed issue — it's an API architecture problem. With 10 years on the market, we've redesigned dozens of such integrations, and we guarantee: the right protocol and contract solve the problem at its root.

When REST stops being enough

REST works well for simple CRUD operations. But as soon as a mobile app appears alongside the web interface, over-fetching begins: the mobile app requests /api/users/123 and gets a 4KB object, but only needs name and avatar. Multiply that by a list of 50 users — 200KB traffic instead of 8KB.

GraphQL solves this with selection sets. The client describes exactly the fields it needs, and the server returns only those. On a project with React Native + Next.js, we migrated from REST to Apollo Server: payload size on the main screen dropped from 340KB to 28KB — a 92% traffic savings. Our certified engineers confirm: the typical pain when adopting GraphQL is N+1 query. A resolver for the author field on a post calls SELECT * FROM users WHERE id = ? for each post in the list. On a page with 20 posts — 21 database queries. Solved with DataLoader — it batches queries and turns them into one SELECT * FROM users WHERE id IN (...).

What is tRPC and how is it better than REST/GraphQL?

If the entire stack is TypeScript (Next.js + Node/Bun), tRPC removes a whole layer of problems. You define a procedure on the server — the client gets full type-safety automatically, without code generation and without Swagger. Renamed a field in the Zod schema — TypeScript highlights all places on the frontend where it's used. tRPC reduces code by 2 times compared to REST + Swagger + openapi-typescript: no need to maintain a separate specification and generate types — everything is inferred from runtime validators. However, tRPC is not suitable if the API is consumed by third-party clients or mobile apps in other languages — in such cases we use GraphQL or REST with OpenAPI specification.

WebSocket and real-time: when SSE, when WS?

HTTP polling every 5 seconds is an illusion of real-time with up to 5 seconds delay and useless server load. For chats, live notifications, collaborative editing — WebSocket or Server-Sent Events. SSE is a one-way stream from server to client, works over ordinary HTTP, automatically reconnects. Suitable for notifications, data streaming, progress bars. WebSocket is bidirectional, needed for chats and collaborative features. Experience shows: 80% of 'real-time' tasks are solved with SSE, not WebSocket — fewer infrastructure complexities.

A typical mistake: opening a WebSocket connection for each page component. On one project, the dashboard opened 12 parallel WS connections. The correct approach is one connection manager at the application level, subscriptions through it. In our work results, we always transfer the connection scheme and a ready solution.

Protocol Typing Over-fetching Versioning Real-time
REST Weak (OpenAPI) Yes URL / Header Polling
GraphQL Strong (SDL) No Deprecation Subscriptions
tRPC Full (TypeScript) No TypeScript checks Subscriptions (optional)

Swagger / OpenAPI as a contract

Documentation written after the fact becomes outdated the day after release. We write the OpenAPI 3.1 specification before development starts; it becomes the contract between frontend and backend. The frontend generates types via openapi-typescript, the backend validates incoming data using generated schemas. Contract deviation from implementation is caught on CI, not during review. For Laravel — l5-swagger or dedoc/scramble. For Node.js — @fastify/swagger or Zod + zod-to-openapi.

How to properly authenticate an API?

JWT with long-lived access tokens without rotation is a source of problems when compromised. The correct scheme: access token for 15 minutes, refresh token for 30 days with rotation on each use. Refresh token stored in an httpOnly cookie, access token in memory (not in localStorage). For inter-service communication — API Keys with scope limitations or mTLS. OAuth 2.0 with PKCE for public clients (SPA, mobile).

How to handle versioning and backward compatibility?

Breaking changes in an API without versioning break clients. Three approaches we use in projects:

Method Example When to use
URL versioning /api/v2/ REST API with long-term legacy support
Header versioning Accept: application/vnd.api+json;version=2 Minimal URL changes
Evolutionary (deprecation) Adding fields, GraphQL deprecated directive For GraphQL — smooth field removal

We guarantee backward compatibility through automated checks (oasdiff) on CI.

How we develop APIs: step-by-step plan

  1. Analysis — audit of current integrations, data schema compilation, protocol selection (REST/GraphQL/tRPC/WebSocket).
  2. Contract design — OpenAPI or SDL (GraphQL) before the first line of code.
  3. Development — implementation per contract, unit tests for each endpoint.
  4. Load testing — k6: 500 virtual users, 10 minutes, p95 latency ≤ 200ms.
  5. Deployment — CI/CD with backward compatibility check, automatic documentation publication.
  6. Team training — handover of Postman collection or Playground, connection instructions.
Typical mistakes we eliminate
  • N+1 on queries without DataLoader.
  • No rate limiting — DDOS through unauthenticated endpoints.
  • Storing access token in localStorage.
  • Opening multiple WebSocket connections instead of a single connection manager.
  • Documentation not updated after release.

What is included (deliverables)

  • OpenAPI 3.1 specification (or SDL for GraphQL).
  • Generated client types for TypeScript / Dart / Kotlin.
  • Set of automated tests covering all endpoints (unit + integration).
  • Load tests (k6) and report (p50/p95/p99 latency, RPS).
  • Documentation in Swagger UI / Redoc / GraphiQL.
  • Team training (2–4 hour workshop).
  • Support for 30 days after delivery (per contract).

Our experience

  • 10+ years in the API development market.
  • 200+ completed projects (REST, GraphQL, WebSocket, tRPC).
  • 50+ certified engineers (AWS, Kubernetes, API Design).
  • Traffic savings averaging 85% when migrating from REST to GraphQL for mobile apps.
  • 100% backward compatibility — not a single broken client in the last 3 years.

Timeline

API development for a typical SaaS project with 30–50 endpoints: from 3 to 8 weeks depending on business logic complexity and number of external integrations. Migration of an existing REST API to GraphQL: from 2 to 6 weeks. Adding a WebSocket layer to an existing backend: from 1 to 3 weeks. Cost is calculated individually after an audit. Get a consultation — contact us to discuss your project.