Supercharging Your Microservices Architecture with Traefik and Cloudflare

Managing and securing access to a modern microservices-based application can be a daunting task. You need a way to route incoming requests to the right backend services, handle load balancing, provide SSL encryption, and protect against threats like DDoS attacks. Luckily, the open source Traefik reverse proxy makes it easy to tackle these challenges. And when combined with the power of Cloudflare, you get a robust and highly-secure entry point for your application.

In this in-depth guide, we‘ll walk through everything you need to know to get Traefik up and running on your own infrastructure, complete with automatic SSL certificate management using Let‘s Encrypt and integration with Cloudflare. Whether you‘re looking to expose just a couple services or dozens of them, by the end of this tutorial you‘ll have a production-ready Traefik setup that can grow with your application.

What is Traefik?

At its core, Traefik is a Layer 7 reverse proxy and load balancer. It sits in front of your backend services (which are often running in Docker containers) and routes incoming HTTP requests to the appropriate service based on the hostname or path. Some of the key features that make Traefik so powerful include:

  • Continuously updates its configuration to match your deployed services in real-time (no restarts needed!)
  • Integrates with Docker, Kubernetes, and other orchestrators to automatically discover services
  • Supports circuit breakers, rate limiting, and A/B testing via middlewares
  • Provides a beautiful, real-time web UI dashboard for viewing service health and metrics
  • Securely handles SSL termination and obtains/renews certificates automatically with Let‘s Encrypt

Traefik architecture diagram

Prerequisites

Before diving into the installation, let‘s review a few things you‘ll need:

  1. Registered domain name – Traefik uses this to automatically configure SSL certificates and serve the dashboard
  2. Cloudflare account – We‘ll use Cloudflare as the DNS provider and proxy service in front of Traefik
  3. Docker and docker-compose installed on your server – The server needs to be publicly accessible on ports 80 and 443

I recommend starting with a virtual private server from a provider like DigitalOcean, Linode, or Vultr if you don‘t already have infrastructure ready to use. For this demo, I‘ll be using Ubuntu 20.04 LTS.

Got everything ready? Let‘s get started with the fun part!

Installing Traefik

The first step is to create a directory on your server where we‘ll store the configuration files, certificates, and access control list:

mkdir -p /opt/traefik
cd /opt/traefik
touch acme.json traefik.yml
chmod 600 acme.json

We need to create a docker-compose.yml file to define our Traefik service and how the Docker containers will be run:

version: ‘3‘

services:
  traefik:
    image: traefik:v2.4
    restart: always
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.yml:/traefik.yml
      - ./acme.json:/acme.json
    container_name: traefik
    networks:
      - web
      - default

networks:
  web:
    external: true

This configuration tells Docker to pull the official Traefik image, bind the required ports, mount the Docker socket and config files as volumes, and attach the container to an external Docker network named "web" (which we‘ll create shortly).

Next, we need to populate the main Traefik config file at traefik.yml:

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
  websecure:
    address: :443
    http:
      tls:
        certResolver: letsencrypt
        domains:
          - main: example.com
            sans: 
              - ‘*.example.com‘

providers:
  docker:
    endpoint: unix:///var/run/docker.sock
    exposedByDefault: false

certificatesResolvers:
  letsencrypt:
    acme:
      email: [email protected]
      storage: acme.json
      httpChallenge:
        entryPoint: web

api:
  dashboard: true

There are a few important parts to this config:

  1. We define two entrypoints, web on port 80 and websecure on 443. All HTTP traffic is automatically redirected to HTTPS.
  2. The Docker provider is configured to look for containers on the local Docker socket. We disable the exposedByDefault flag so that we can selectively choose which containers are exposed via Traefik.
  3. We set up Let‘s Encrypt as the automatic certificate resolver using the HTTP challenge on port 80. Be sure to replace the email with your own address.
  4. The API section enables the dashboard interface which we‘ll look at later.

Now it‘s time to create that "web" network we specified in the compose file:

docker network create web

And ask Docker Compose to pull the Traefik image and start our container:

docker-compose up -d

After a few seconds, you should see the Traefik container running:

$ docker ps
CONTAINER ID   IMAGE         COMMAND                  PORTS                                      NAMES
6b8a6b4929d4   traefik:v2.4  "/entrypoint.sh trae…"  0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   traefik

We have Traefik installed and running now, but there are still a few more steps before it‘s ready to use. We need to configure Cloudflare to proxy requests to our server, and update some DNS records.

Configuring Cloudflare

Cloudflare provides a fantastic DNS hosting service with a global anycast network, DDoS protection, and many other features that supercharge Traefik and help secure your application.

If you don‘t already have your domain set up on Cloudflare, follow this guide to add your site and configure the nameservers.

Once your domain is active on Cloudflare, navigate to the "DNS" tab in the dashboard. We need to create a few DNS records:

  1. An A record for the root domain (example.com) that points to your server‘s public IP address
  2. A CNAME record for the Traefik dashboard subdomain (traefik.example.com) that points to the root domain

But instead of using a normal DNS query to resolve the IP address when a user hits your domain, we want Cloudflare to proxy the request through their network first. This allows Cloudflare to filter malicious traffic, cache content, inject security headers, and more.

To enable the proxy functionality, simply turn on the "proxy status" for each DNS record via the orange cloud icon. It should look like this when you‘re done:

Cloudflare DNS settings

The last step is to configure SSL/TLS encryption mode. Under the "SSL/TLS" tab, change the encryption mode from "Flexible" to "Full (strict)". This informs Cloudflare to connect to our origin server over HTTPS instead of HTTP. With our current Traefik configuration, this means Cloudflare will always use the HTTP to HTTPS redirect, which then allows Traefik to provision the Let‘s Encrypt SSL certificate when it sees the ACME challenge.

It can take a bit of time for the DNS changes to propagate, but after a few minutes you should be able to successfully access the Traefik dashboard at traefik.example.com! (Replace example.com with your actual domain of course.)

Traefik dashboard

If you see a "404 Page Not Found" error, try holding Shift and refreshing the page a few times. It can take a couple requests before Let‘s Encrypt provisions the certificate.

Securing the Dashboard

Right now the dashboard is open to the public, which is quite dangerous. An attacker could easily discover it and wreakle havoc on your system. Let‘s lock it down so only authenticated users can access it.

Traefik provides a simple basic auth middleware that can protect access to any router. To use it, first generate an encrypted password using the command:

echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g

You‘ll be prompted to enter a password and the output will look something like:

user:$$2y$05$bQjElV5mH5NU3TFgNPx1K..RsknMbjts3bD00w.vLqm

Copy that output and add it as a label to the Traefik service in docker-compose.yml:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.api.rule=Host(`traefik.example.com`)"
  - "traefik.http.routers.api.entrypoints=websecure"
  - "traefik.http.routers.api.tls=true"
  - "traefik.http.routers.api.middlewares=auth"
  - "traefik.http.middlewares.auth.basicauth.users=user:$$2y$05$bQjElV5mH5NU.TFgNPx1K..RsknMbjts3bD00w.vLqm"

Redeploy the Traefik service for the changes to take effect:

docker-compose up -d

Now when you access the dashboard, you‘ll be prompted for login credentials.

Exposing a Service

We‘ve got Traefik all set up now, so let‘s see how we can use it to securely expose a service to the internet with just a few labels.

For this example, we‘ll create a whoami service that just returns information about the HTTP request:

whoami:
  image: containous/whoami
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)"
    - "traefik.http.routers.whoami.entrypoints=websecure"
    - "traefik.http.routers.whoami.tls=true"
  networks:
    - web

Append that service definition to the end of your docker-compose.yml and run docker-compose up -d one more time.

The traefik.enable=true label tells Traefik to expose this service, and the traefik.http.routers.whoami.rule specifies the hostname criteria for routing requests to this service. Since we‘re using the websecure entrypoint, Traefik will automatically provision and use an SSL certificate from Let‘s Encrypt!

To actually reach the service, we need to update our Cloudflare DNS one more time to create an A record for whoami.example.com that proxies to the root domain:

Cloudflare DNS record for whoami subdomain

Give it a minute to update, then check out https://whoami.example.com (replace with your own domain name). You should see a JSON response with details about the HTTP request and the Traefik backend:

{
  "host": "whoami.example.com",
  "url": "/",
  "proto": "HTTP/1.1",
  ...
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
    "Accept-Encoding": "gzip",
    "Cf-Connecting-Ip": "71.56.321.105",
    ...
  }
} 

Congratulations, you‘ve successfully deployed your first service with Traefik! You can repeat the process of adding a service definition to docker-compose.yml and creating the corresponding DNS record for each microservice you want to expose through your Traefik proxy.

Further Enhancements

This tutorial covered the basics of getting Traefik up and running with Docker Compose and Cloudflare. Here are some ideas for additional features you may want to implement:

I hope this guide has been helpful in getting you started with Traefik and Cloudflare! Let me know if you have any other questions.

Similar Posts