• Home
  • Docker on Digitalocean: Installing Traefik – a Modern Reverse Proxy for Microservices

Docker on Digitalocean: Installing Traefik – a Modern Reverse Proxy for Microservices

Traefik is a modern HTTP reverse proxy and load balancer for microservices. Traefik serves as a router for all your microservices applications, routing all client requests to correct microservices destination. In this tutorial, I will show you how to install and configure Traefik modern reverse proxy as a Docker container on Ubuntu 18.04 with Digitalocean. So in my example you need to have installed Digitalocean droplet with Docker and Docker-compose on Ubuntu 18.04. Easiest way to do this to choose One-click apps when you create Droplet on Digitalocean, then click on Docker 18.06.1~ce~3 on 18.04 and finish creating of your new Droplet.

In creation it is essential to create SSH key to improve security so we can easily ssh to our droplet through terminal. How to do this is very well described on this link: https://www.digitalocean.com/docs/droplets/how-to/add-ssh-keys/

Notice. When I first try to setup Traefik on Digitalocean I try to follow this example https://www.digitalocean.com/community/tutorials/how-to-use-traefik-as-a-reverse-proxy-for-docker-containers-on-ubuntu-16-04 but it didn’t work. So here is my example that work for me and hopefully for you.

From your terminal try to login with

ssh root@xxx.xxx.xxx.xxx  "-> replace xxx.xxx.xxx.xxx. with your droplet IP address "

Next we need to be certain that docker is installed

docker version

If everything is alright you will see something like this

root@docker-multi:~# docker version
Client:
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:24:51 2018
 OS/Arch:           linux/amd64
 Experimental:      false

Server:
 Engine:
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:23:15 2018
  OS/Arch:          linux/amd64
  Experimental:     false
root@docker-multi:~#

Next we need to check docker-compose which is already installed in our digitalocean droplet

docker-compose version

If everything is alright you will see something like this

root@docker-multi:~# docker-compose version
docker-compose version 1.22.0, build f46880fe
docker-py version: 3.4.1
CPython version: 3.6.6
OpenSSL version: OpenSSL 1.1.0f  25 May 2017
root@docker-multi:~#

Docker container can be run under the non-root user. We just need to add the user to the docker group.

useradd -m -s /bin/bash kklepac 
passwd kklepac

You will be prompted to add user password

root@docker-multi:~# useradd -m -s /bin/bash kklepac 
root@docker-multi:~# passwd kklepac
Enter new UNIX password:
root@docker-multi:~# useradd -m -s /bin/bash kklepac 
root@docker-multi:~# passwd kklepac
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root@docker-multi:~#

Now add the ‘kristijan’ user to the docker group, then restart the docker service.

root@docker-multi:~# sudo usermod -a -G root kklepac
root@docker-multi:~# sudo usermod -a -G docker kklepac
root@docker-multi:~# systemctl restart docker
root@docker-multi:~#

Now test new user and docker

root@docker-multi:~# su - kklepac
kklepac@docker-multi:~$ docker run -it hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

kklepac@docker-multi:~$

The Traefik project has an official Docker image, so we will use that to run Traefik in a Docker container. But before we get our Traefik container up and running, we need to create a configuration file and set up an encrypted password so we can access the monitoring dashboard. We’ll use the htpasswd utility to create this encrypted password. First, install the utility, which is included in the apache2-utils package:

sudo apt-get install apache2-utils

Then generate the password with htpasswd. Substitute secure_password with the password you’d like to use for the Traefik admin user:

htpasswd -nb kklepac secure_password

The output from the program will look like this:

kklepac:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/

You’ll use this output in the Traefik configuration file to set up HTTP Basic Authentication for the Traefik health check and monitoring dashboard. Copy the entire output line so you can paste it later.

Next you need to create docker network. I name it traefiknet

docker network create traefiknet

Now when you run docker ls command yo will get something like this in your terminal.

kklepac@docker-multi:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
41c856010ecb        bridge              bridge              local
80eae7e01c9c        ghost_internal      bridge              local
1766937562ec        host                host                local
23c344327b2b        none                null                local
ed07bdf14793        traefiknet          bridge              local
kklepac@docker-multi:~$

Now it’s time to set up your domains on Digitalocean network. In my example I set my custom main domain visitcres.com A records, to ghost, and monitor, that each point to the IP address of my server. You can learn how to point domains to DigitalOcean Droplets by reading through DigitalOcean’s Domains and DNS documentation.

My domain monitor.visitcres.com will open traefik monitoring and ghost.visitcres.com will open sample Ghost blog App with dummy data.

You need to create your own custom project directory structure. For example mine is created under home. I have structure like this

home

– kklepac (folder that I create inside home)

– ghost (folder that I create inside kklepac)

acme.json ( file that I need … create empty one inside ghost)

docker-compose.yml ( file that I need … create empty one inside ghost)

traefik.toml ( file that I need … create empty one inside ghost)

First let’s examine traefik.toml file. TOML is a configuration language similar to INI files, but it is standardized. This file lets us configure the Traefik server and various integrations, or providers, we want to use. In this tutorial, we will use three of Traefik’s available providers: apidocker, and acme, which is used to support TLS using Let’s Encrypt.

#Traefik Global Configuration
debug = false
checkNewVersion = true
logLevel = "ERROR"

#Define the EntryPoint for HTTP and HTTPS
defaultEntryPoints = ["https","http"]

#Define the HTTP port 80 and
#HTTPS port 443 EntryPoint
#Enable automatically redirect HTTP to HTTPS
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]

#Enable Traefik Dashboard on port 8080
#with basic authentication method
#kklepac and password
[entryPoints.dash]
address=":8080"
[entryPoints.dash.auth]
[entryPoints.dash.auth.basic]
    users = [
        "kklepac:********************************", 
    ]

[api]
entrypoint="dash"
dashboard = true

#Enable retry sending a request if the network error
[retry]

#Define Docker Backend Configuration
[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "visitcres.com"
watch = true
exposedbydefault = false

#Letsencrypt Registration
#Define the Letsencrypt ACME HTTP challenge
[acme]
email = "kristijan.klepac@gmail.com"
storage = "acme.json"
entryPoint = "https"
OnHostRule = true
  [acme.httpChallenge]
  entryPoint = "http"

So as we see above we must change some things in file according to our environment settings. Change [entryPoints.dash.auth.basic] users = [ “kklepac:********************************”, ] -> user must be your added user and password is password that you create in above section where you use htpaswd command (in my example kklepac:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/ ). Next you need to set main domain that you use ‘domain = “visitcres.com”‘ and in [acme] you need to set your valid email address because this will be used for setting Let’s Encrypt. This section is called acme because ACME is the name of the protocol used to communicate with Let’s Encrypt to manage certificates. To have Traefik generate certificates for your hosts, you must set the email key to your email address. We then specify that we will store the information that we will receive from Let’s Encrypt in a JSON file called acme.json. The entryPoint key needs to point to the entry point handling port 443, which in our case is the https entry point.

After setting traefik.toml file you need to create the blank ‘acme.json’ file and change the permission to 600.

touch acme.json
chmod 600 acme.json

Next, we will edit the ‘docker-compose.yml’ script and add the traefik service configuration.

version: '3.3'

services:

  mysql:
    image: mysql:5.7
    restart: always
    volumes:
      - ./data:/var/lib/mysql
    labels:
      - "traefik.enable=false"
    networks:
      - internal
    environment:
      MYSQL_ROOT_PASSWORD: "HERE PUT YOUR DESIRED PASSWORD"
      MYSQL_USER: ghost
      MYSQL_PASSWORD: "HERE PUT YOUR DESIRED PASSWORD"
      MYSQL_DATABASE: "HERE PUT YOUR DESIRED DATABASE NAME"
    container_name: mysql
  traefik:
    image: traefik:latest
    command: --docker
    ports:
      - 80:80
      - 443:443
    labels:
      - "traefik.enable=true"
      - "traefik.backend=dashboard"
      - "traefik.frontend.rule=Host:monitor.visitcres.com"
      - "traefik.port=8080"
    networks:
      - traefiknet
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./traefik.toml:/traefik.toml
      - ./acme.json:/acme.json
    container_name: traefik
    restart: always
  ghost:
    image: ghost:1-alpine
    restart: always
    ports:
      - 2368
    volumes:
      - ./blog:/var/lib/ghost/content
    labels:
      - "traefik.enabled=true"
      - "traefik.backend=ghost"
      - "traefik.frontend.rule=Host:ghost.visitcres.com"
      - "traefik.docker.network=traefiknet"
      - "traefik.port=2368"
    networks:
      - internal
      - traefiknet
    environment:
      database__client: mysql
      database__connection__host: mysql
      database__connection__user: ghost
      database__connection__password: "HERE PUT YOUR DESIRED PASSWORD"
      database__connection__database: "HERE PUT YOUR DESIRED DATABASE NAME"
    container_name: ghost
    depends_on:
      - mysql
      - traefik

networks:
  traefiknet:
    external: true
  internal:
    external: false

As you see here we use some services and configure them. We use MySql and image that we request is mysql:5.7 ( this image create MySql database which is connected to Ghost Blog), then we use traefik image (latest) and ghost:1-alpine image for creating Ghost Blog. Please examine closely above file and configuration so you can set up everything according your needs. Also don’t forget to set in file your own domains ( my example “traefik.frontend.rule=Host:monitor.visitcres.com” ) and change MySql password and database name.

To build and run all our traefik and ghost stack service, we can use the command below

docker-compose up -d

When it’s complete, check all running services.

docker-compose ps

After few minutes you will be able to visit your urls ( in my example  https://monitor.visitcres.com and https://ghost.visitcres.com ). Your monitor link will prompt you for user and password that you set wit htpaswd. As you see  SSL and Let’s Encrypt certificate is set on the fly for our main domain and our subdomains. That’s very nice. 🙂

Thanks for reading…

 

 

 

 

Tags: , , , ,

Copyright by Kristijan Klepač 2018