Using Traefik to host multiple SSL websites on your VPS
Suppose you had deployed several microservices using Docker and you want to connect these microservices to the outside world. You will probably use some reverse proxy solution that will act as a frontend for these microservices. Nginx is the most popular and efficient reverse proxy solution, but it was written before before container technology (Docker) became so popular.
Say, for example, you want to remove one of the microservices from the container or change its port, and, as a result, you have to edit the Nginx configuration file to reflect the new container settings. Now, consider another situation where you add, delete, or scale the microservices application several times in a day—now, you’re editing the routes and other settings several times in the reverse proxy configuration file.
There’s a need for new generation of reverse proxy solution. Traefik is a modern reverse proxy solution written in GO to meet new these new containerized challenges.
“Træfik listens to your service registry/orchestrator API and instantly generates the routes so your microservices are connected to the outside world – without further intervention from your part.” Source: https://Traefik.io/
Traefik was developed with containerized technology in mind, which means there’s a lot of new features available in comparison with other reverse proxy solutions. When running, Traefik does the following and more:
- Dynamically updates the configuration and loads it without restart.
- Load balances requests from the outside world using multiple available algorithms.
- Enables HTTPS for microservices using Let’s Encrypt.
- A clean web UI.
- Support for Websocket, HTTP/2, GRPC.
- Provides metrics to Rest, Prometheus, Datadog, Statsd, InfluxDB.
In this article, we will check how to install and configure Traefik in a standalone and Dockerized environment, and then give examples of connecting it to your microservices in the backend.
- A VPS running Ubuntu 16.04.
- A non-root,
sudo-enabled user. If you only have a
rootuser, see our SSH tutorial for details on creating new users.
- A working Docker installation—for information about how to install Docker, check out our getting started with Docker tutorial
To install the Docker use the following command.
$ sudo curl -sS https://get.docker.com/ | sh
The above command will update your system and install the correct version of docker.
Enable the docker service and start it.
$ sudo systemctl enable docker $ sudo systemctl start docker
Our first goal is to route few applications (backend) using Traefik (frontend) without Dockerizing them. To do that, we’ll install Apache and Nginx and configure them to use different ports, as they will act as a backend.
$ sudo apt-get install apache2
Change the port number to
/etc/apache2/ports.conf and restart Apache.
$ sudo vi /etc/apache2/ports.conf $ sudo systemctl restart apache2
Install Nginx and change the port number to
8082 in the following two files. Then, restart Nginx.
$ sudo apt-get install nginx $ sudo vi /etc/nginx/sites-available/default $ sudo vi /etc/nginx/sites-enabled/default $ sudo systemctl restart nginx
Now both Apache and Nginx will be available in the port number
To install Traefik as a standalone environment, we need to download the binary and edit the Traefik configuration file and rules files.
Download the Traefik binary from the releases page and make it executable.
$ mkdir Traefik && cd Traefik $ wget https://github.com/containous/Traefik/releases/download/v1.6.0/Traefik $ chmod u+x Traefik
Next, download the sample Traefik configuration file and use it as a reference for many of the available Traefik options. We will use only a few of the options to get started.
$ wget https://raw.githubusercontent.com/containous/Traefik/master/Traefik.sample.toml $ mv Traefik.sample.toml Traefik.toml $ vi Traefik.toml
Once you have the
Traefik.toml open, you can add the following at the beginning of the file, just beneath the
Global configuration block.
logLevel = "DEBUG" defaultEntryPoints = ["http"] [entryPoints] [entryPoints.http] address = ":80" [file] filename = "./rules.toml" watch = true
Next, create the rules file:
# vi rules.toml
Add the following to this file, replacing
YOURDOMAIN with the domain name you’re going to use for this application:
[entryPoints] [entryPoints.http] address = ":8080" [frontends] [frontends.frontend1] backend = "backend1" [frontends.frontend1.routes.test_1] rule = "Host: Traefik.YOURDOMAIN" [frontends.frontend2] backend = "backend2" [frontends.frontend2.routes.test_1] rule = "Host: apache.YOURDOMAIN" [backends] [backends.backend1] [backends.backend1.servers.server1] url = "http://127.0.0.1:8082" [backends.backend2] [backends.backend2.servers.server1] url = "http://127.0.0.1:8083"
In the above Traefik rules configuration file, we have created two frontends with two domain names, and they will proxy the two backends we created earlier: the Apache and Nginx instances.
Finally, you can start the Traefik binary:
# ./traefik -c Traefik.toml
The subdomains (i.e the frontends) that you defined in the above rules files will now be available on port 80.
With little modification to the above rules file, we can make Traefik to act as a load balancer between both Apache and Nginx instances.
# vi rules.toml
Either delete the file’s contents and replace with the following:
[entryPoints] [entryPoints.http] address = ":8080" [frontends] [frontends.frontend1] backend = "backend1" [frontends.frontend1.routes.test_1] rule = "Host: Traefik.YOURDOMAIN" [backends] [backends.backend1] [backends.backend1.LoadBalancer] method = "drr" [backends.backend1.servers.server1] url = "http://127.0.0.1:8082" weight = 1 [backends.backend1.servers.server2] url = "http://127.0.0.1:8083" weight = 2
Now, you can start Traefik again—but remember you have to kill previous instances of it first.
./traefik -c traefik.toml
Use your browser to visit the domain name that you entered into the
rules.toml file and hit refresh. You’ll find that Traefik is both proxying load balancing the Apache and Nginx backends.
Now, let’s look at this same process, but using Docker, docker-compose, and containerized/Dockerized microservices, which is likely how many of you will end up using Traefik.
First, you should install
docker-compose if you don’t have it already.
curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` > ./docker-compose $ sudo mv ./docker-compose /usr/bin/docker-compose $ sudo chmod +x /usr/bin/docker-compose
To run Traefik using docker-compose, let’s create a
docker-compose.yml file, in which we will define services for Traefik and other two microservices—Apache and Nginx, just like before.
# vi docker-compose.yml
Add the following:
version: '3' services: proxy: image: traefik:latest command: --web --docker --docker.domain=YOURDOMAIN.local --logLevel=DEBUG networks: - traefik ports: - 80:80 - 443:443 - 8080:8080 volumes: - /var/run/docker.sock:/var/run/docker.sock - /root/traefik.toml:/traefik.toml - /root/acme.json:/acme.json apache: image: httpd:latest labels: - "traefik.frontend.rule=Host:apache.YOURDOMAIN" networks: - traefik nginx: image: nginx:latest labels: - "traefik.frontend.rule=Host:Traefik.YOURDOMAIN" networks: - traefik networks: traefik: external: true
Three services have been defined in the above
docker-compose.yml file, and they are
--web option enables the web interface for Traefik, the
--docker option instructs Traefik that you are using docker configuration, and the
--docker.domain sets the default URL for containers to
In the port section,
8080 is the port used by Traefik for its web interface and port
80is used for all default http requests. In the volume section, the Docker socket is accessed by Traefik to route requests to the right container. We need to knit all the three services together so that they can communicate with each other, which is why we created the
Traefik network at the end of the file.
In the Apache/Nginx service section, the
Traefik.frontend.rule is used to route request to the right container. And, at last, we had defined a network that can communicate with other containers with the option
Next we will create a Traefik configuration file:
# vi traefik.toml
Add the following, being sure to change the
domain = "YOURDOMAIN.local" and
email="YOUREMAIL" lines accordingly.
logLevel = "DEBUG" defaultEntryPoints = ["http", "https"] [web] address = ":8080" [docker] domain = "YOURDOMAIN.local" watch = true [entryPoints] [entryPoints.http] address = ":80" [entryPoints.http.redirect] entryPoint = "https" [entryPoints.https] address = ":443" [entryPoints.https.tls] [acme] email="YOUREMAIL" storage="acme.json" entryPoint="https" acmeLogging=true onDemand=false OnHostRule=true [acme.httpChallenge] entryPoint = "http"
The above Traefik configuration file sets the log level to
debug and allows both HTTP and HTTPS requests to the frontend. We then force HTTP (80) traffic to redirect to HTTPS (443) in
entrypoints section. The Traefik web interface is configured on port
8080, and the Docker section instructs Traefik to use Docker as a configuration source.
acme section is used by Traefik to fetch a Let’s Encrypt certificate for the domain that appears in the docker-compose.yml. The great thing about Traefik is that these certificates are dynamic, meaning that if you add a new domain or subdomain to
docker-compose.yml, Traefik will automatically fetch the key/certificate and store them in
onDemand option in
acme section will let Traefik request certificates whenever a web request is received for a domain or subdomain which does not already have a certificate. The
onHostRule only requests new certificates for domain names that are listed in the
Create an empty JSON file to hold Let’s Encrypt data that and make this file readable/writable to only the root user.
# touch /root/acme.json # chmod 600 /root/acme.json
Since we have configured all the three containers to use the network by the name Traefik, we should create it through terminal before starting the container.
# docker network create Traefik
Fire up the containers with the following command in the terminal.
# docker-compose up -d
The two backends you created will be served by Traefik at
http://apache.YOURDOMAIN. You can visit the Traefik dashboard at either
You’re up and running with a proxied, load-balanced, fully Dockerized reverse proxy that’s fully HTTPS-enabled. Congratulations!
Now that you have run Traefik from both the binary and using docker-compose, you’re ready to add more microservices! If you add new Docker images in the
docker-compose.yml, Traefik will recognize newly added backends immediately and route the request to it without any further configuration of Traefik or restarting it.
For more configuration options, see the Traefik documentation.
Now, you might be asking, “What should I install behind this amazing Traefik reverse proxy?”
Well, how about you start with self-hosting an RSS reader? Or, check out these five cool self-hosted apps. Maybe you want to put Alphabet’s Outline VPN behind a reverse proxy? The options are endless—have fun and get more from your VPS at the same time.