instruction: Explain HTTP routing with Traefik
output: Back
  Ask AI
  Start typing to search or try
  Contact support
  Guides
  Get started
  Manuals
  HTTP routing with Traefik
  Use Traefik to easily route traffic between multiple containers or non-containerized workloads
  Networking
  20 minutes
  Â« Back to all guides
  HTTP routing with Traefik
  Page options
  Copy page as Markdown for LLMs
  View page as plain text
  Ask questions with Docs AI
  Claude
  Open in Claude
  Introduction
  During local development, itâs quite common to need to run multiple HTTP services. You might have both an API and a frontend app, a WireMock service to mock data endpoints, or a database visualizer (such as phpMyAdmin or pgAdmin). In many development setups, these services are exposed on different ports, which then requires you to remember whatâs on what port but can also introduce other problems (such as CORS).
  A reverse proxy can dramatically simplify this setup by being the single exposed service and then routing requests to the appropriate service based on the request URL (either by path or hostname).
  Traefik
  is a modern, cloud-native reverse proxy and load balancer that makes developing and deploying multi-service applications easier. This guide will show you how to use Traefik with Docker to enhance your development environment.
  In this guide, you will learn how to:
  Start Traefik with Docker
  Configure routing rules to split traffic between two containers
  Use Traefik in a containerized development environment
  Use Traefik to send requests to non-containerized workloads
  Prerequisites
  The following prerequisites are required to follow along with this how-to guide:
  Docker Desktop
  Node.js
  yarn
  Basic of Docker
  Using Traefik with Docker
  One of the unique features of Traefik is its ability to be configured in many ways. When using the Docker provider, Traefik gets its configuration from other running containers using
  labels
  . Traefik will watch engine events (for container starts and stops), extract the labels, and update its configuration.
  While there are
  many Traefik-monitored labels
  , the two most common will be:
  traefik.http.routers.<service-name>.rule
  - used to indicate the routing rule (
  view all of the available rules here
  traefik.http.services.<service-name>.loadbalancer.server.port
  - indicates the port Traefik should forward the request to. Note that this container port does not need to be exposed on your host machine (
  read about port detection here
  Letâs do a quick demo of starting Traefik and then configuring two additional containers to be accessible using different hostnames.
  In order for two containers to be able to communicate with each other, they need to be on the same network. Create a network named
  traefik-demo
  using the
  docker network create
  command:
  docker network create traefik-demo
  Start a Traefik container using the following command. The command exposes Traefik on port 80, mounts the Docker socket (which is used to monitor containers to update configuration), and passes the
  --providers.docker
  argument to configure Traefik to use the Docker provider.
  docker run -d --network
  traefik-demo -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock traefik:v3.1.2 --providers.docker
  Now, start a simple Nginx container and define the labels Traefik is watching for to configure the HTTP routing. Note that the Nginx container is not exposing any ports.
  docker run -d --network
  traefik-demo --label
  'traefik.http.routers.nginx.rule=Host(`nginx.localhost`)'
  nginx
  Once the container starts, open your browser to
  http://nginx.localhost
  to see the app (all Chromium-based browsers route *.localhost requests locally with no additional setup).
  Start a second application that will use a different hostname.
  docker run -d --network
  traefik-demo --label
  'traefik.http.routers.welcome.rule=Host(`welcome.localhost`)'
  docker/welcome-to-docker
  Once the container starts, open your browser to
  http://welcome.localhost
  . You should see a âWelcome to Dockerâ website.
  Using Traefik in development
  Now that youâve experienced Traefik, itâs time to try using it in a development environment. In this example, you will use a sample application that has a split frontend and backend. This app stack has the following configuration:
  All requests to /api to go to the API service
  All other requests to localhost go to the frontend client
  Since the app uses MySQL, db.localhost should provide phpMyAdmin to make it easy to access the database during development
  The application can be accessed on GitHub at
  dockersamples/easy-http-routing-with-traefik
  In the
  compose.yaml
  file, Traefik is using the following configuration:
  services
  proxy
  image
  traefik:v3.1.2
  command
  providers.docker
  ports
  volumes
  /var/run/docker.sock:/var/run/docker.sock
  Note that this is essentially the same configuration as used earlier, but now in a Compose syntax.
  The client service has the following configuration, which will start the container and provide it with the labels to receive requests at localhost.
  services
  # â¦
  client
  image
  nginx:alpine
  volumes
  "./client:/usr/share/nginx/html"
  labels
  traefik.http.routers.client.rule
  "Host(`localhost`)"
  The api service has a similar configuration, but youâll notice the routing rule has two conditions - the host must be âlocalhostâ and the URL path must have a prefix of â/apiâ. Since this rule is more specific, Traefik will evaluate it first compared to the client rule.
  services
  # â¦
  build
  ./dev/api
  volumes
  "./api:/var/www/html/api"
  labels
  traefik.http.routers.api.rule
  "Host(`localhost`) && PathPrefix(`/api`)"
  And finally, the
  phpmyadmin
  service is configured to receive requests for the hostname âdb.localhostâ. The service also has environment variables defined to automatically log in, making it a little easier to get into the app.
  services
  # â¦
  phpmyadmin
  image
  phpmyadmin:5.2.1
  labels
  traefik.http.routers.db.rule
  "Host(`db.localhost`)"
  environment
  PMA_USER
  root
  PMA_PASSWORD
  password
  Before starting the stack, stop the Nginx container if it is still running.
  And thatâs it. Now, you only need to spin up the Compose stack with a
  docker compose up
  and all of the services and applications will be ready for development.
  Sending traffic to non-containerized workloads
  In some situations, you may want to forward requests to applications not running in containers. In the following architecture diagram, the same application from before is used, but the API and React apps are now running natively on the host machine.
  To accomplish this, Traefik will need to use another method to configure itself. The
  File provider
  lets you define the routing rules in a YAML document. Here is an example file:
  http
  routers
  native-api
  rule
  "Host(`localhost`) && PathPrefix(`/api`)"
  service
  native-api
  native-client
  rule
  "Host(`localhost`)"
  service
  native-client
  services
  native-api
  loadBalancer
  servers
  "http://host.docker.internal:3000/"
  native-client
  loadBalancer
  servers
  "http://host.docker.internal:5173/"
  This configuration indicates that requests that for
  localhost/api
  will be forwarded to a service named
  native-api
  , which then forwards the request to
  http://host.docker.internal:3000
  . The hostname
  host.docker.internal
  is a name that Docker Desktop provides to send requests to the host machine.
  With this file, the only change is to the Compose configuration for Traefik. There are specifically two things that have changed:
  The configuration file is mounted into the Traefik container (the exact destination path is up to you)
  command
  is updated to add the file provider and point to the location of the configuration file
  services
  proxy
  image
  traefik:v3.1.2
  command
  providers.docker --providers.file.filename=/config/traefik-config.yaml --api.insecure
  ports
  volumes
  /var/run/docker.sock:/var/run/docker.sock
  ./dev/traefik-config.yaml:/config/traefik-config.yaml
  Starting the example app
  To run the example app that forwards requests from Traefik to native-running apps, use the following steps:
  If you have the Compose stack still running, stop it with the following command:
  docker compose down
  Start the application using the provided
  compose-native.yaml
  file:
  docker compose -f compose-native.yaml up
  Opening
  http://localhost
  will return a 502 Bad Gateway because the other apps arenât running yet.
  Start the API by running the following steps:
  cd api
  yarn install
  yarn dev
  Start the frontend by running the following steps in a new terminal (starting from the root of the project):
  cd client
  yarn install
  yarn dev
  Open the app at
  http://localhost
  . You should see an app that fetches a message from
  http://localhost/api/messages
  . You can also open
  http://db.localhost
  to view or adjust the available messages directly from the Mongo database. Traefik will ensure the requests are properly routed to the correct container or application.
  When youâre done, run
  docker compose down
  to stop the containers and stop the Yarn apps by hitting
  ctrl+c
  Recap
  Running multiple services doesnât have to require tricky port configuration and a good memory. With tools like Traefik, itâs easy to launch the services you need and easily access them - whether theyâre for the app itself (such as the frontend and backend) or for additional development tooling (such as phpMyAdmin).