Traefik as a Reverse Proxy for Docker Containers on Ubuntu 18.04 and duckdns.org ip dinamic

Introduction

Docker can be an efficient way to run web applications in production, but you may want to run multiple applications on the same Docker host. In this situation, you’ll need to set up a reverse proxy since you only want to expose ports 80 and 443 to the rest of the world.

Traefik is a Docker-aware reverse proxy that includes its own monitoring dashboard. In this tutorial, you’ll use Traefik to route requests to two different web application containers: a seafile container and an onlyoffice, memcached, phpmyadmin container, each talking to a MySQL database. You’ll configure Traefik to serve everything over HTTPS using Let’s Encrypt.

Prerequisites

You must enter https://www.duckdns.org/ generate your domain to obtain your token to carry out the rest of the tutorial

To follow along with this tutorial, you will need the following:

A domain and four A records, seafile , phpmyadmin , duckdns onlyoffice and monitor , that each point to the IP address of your server. Throughout this tutorial, substitute your domain for your_domain in the configuration files and examples.

Step 1 — Configuring and Running Traefik

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 admin secure_password

The output from the program will look like this:

Output admin:$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.

To configure the Traefik server, we’ll create a new configuration file called traefik.toml using the TOML format. TOML is a configuration language similar to INI files, but 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: api , docker , and acme , which is used to support TLS using Let’s Encrypt.

Open up your new file in nano or your favorite text editor:

nano traefik.toml
debug = false
checkNewVersion = true
logLevel = "INFO"
defaultEntryPoints = ["http", "https"]

[entryPoints]
  [entryPoints.dashboard]
    address = ":8080"
    [entryPoints.dashboard.auth]
      [entryPoints.dashboard.auth.basic]
        users = ["admin:$apr1$ruca84Hq$mbjdMZBAG.KWn7vfN/SNK/"]
  [entryPoints.http]
    address = ":80"
      [entryPoints.http.redirect]
        entryPoint = "https"
  [entryPoints.https]
    address = ":443"
      [entryPoints.https.tls]

[api]
entrypoint="dashboard"

[acme]
email = "your_mail@mail.com"
storage = "acme.json"
entryPoint = "https"
onHostRule = true
  [acme.httpChallenge]
  entryPoint = "http"

[docker]
  endpoint = "unix:///var/run/docker.sock"
  domain = "your_domain.duckdns.org"
  watch = true
  exposedbydefault = false
  network = "traefik_net"

Step 2 – Running the Traefik Container

Next, create a Docker network for the proxy to share with containers. The Docker network is necessary so that we can use it with applications that are run using Docker Compose. Let’s call this network web .

docker network create traefik_net

When the Traefik container starts, we will add it to this network. Then we can add additional containers to this network later for Traefik to proxy to.

Next, create an empty file which will hold our Let’s Encrypt information. We’ll share this into the container so Traefik can use it:

touch acme.json

Traefik will only be able to use this file if the root user inside of the container has unique read and write access to it. To do this, lock down the permissions on acme.json so that only the owner of the file has read and write permission.

chmod 600 acme.json

Once the file gets passed to Docker, the owner will automatically change to the root user inside the container.

Finally, create the Traefik container with this command:

version: '3'
services:
  proxy:
    image: traefik:alpine
    restart: always    
    networks:
      - traefik_net
    ports:
      - "80:80"
      - "443:443"
    labels:
      - traefik.enable=true
      - traefik.frontend.rule=Host:monitor.your_domain.duckdns.org
      - traefik.port=8080
      - traefik.docker.network=traefik_net
      - traefik.default.protocol=http
      - traefik.backend=seafile
    environment:
     - DUCKDNS_TOKEN=XXXXXXXXXXXXXXXXXXXXXXXXX
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/traefik/traefik.toml:/traefik.toml
      - /opt/traefik/acme.json:/acme.json
networks:
  traefik_net:
    external: true

The command is a little long so let’s break it down.

We use the -d flag to run the container in the background as a daemon. We then share our docker.sock file into the container so that the Traefik process can listen for changes to containers. We also share the traefik.toml configuration file and the acme.json file we created into the container.

Next, we map ports :80 and :443 of our Docker host to the same ports in the Traefik container so Traefik receives all HTTP and HTTPS traffic to the server.

Then we set up two Docker labels that tell Traefik to direct traffic to the hostname monitor.your_domain to port :8080 within the Traefik container, exposing the monitoring dashboard.

We set the network of the container to web , and we name the container traefik .

Finally, we use the traefik:alpine image for this container, because it’s small.

A Docker image’s ENTRYPOINT is a command that always runs when a container is created from the image. In this case, the command is the traefik binary within the container. You can pass additional arguments to that command when you launch the container, but we’ve configured all of our settings in the traefik.toml file.

With the container started, you now have a dashboard you can access to see the health of your containers. You can also use this dashboard to visualize the frontends and backends that Traefik has registered. Access the monitoring dashboard by pointing your browser to https://monitor.your_domain . You will be prompted for your username and password, which are admin and the password you configured in Step 1.

Step 3 — Registering Containers with Traefik

With the Traefik container running, you’re ready to run applications behind it. Let’s launch the following cotainers behind Traefik:

A seafile, memched, phpmyadmin, mariadb and onlyoffice.

We’ll manage both of these applications with Docker Compose using a docker-compose.yml file. Open the docker-compose.yml file in your editor:

nano docker-compose.yml

At this point, docker-compose.yml should have the following contents:

version: '3'
services:
  db:
    image: mariadb:10.1
    container_name: mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=your_password
      - MYSQL_LOG_CONSOLE=true
    labels:
      - traefik.enable=false
    volumes:
      - /opt/seafile-mysql/db:/var/lib/mysql
    networks:
      - traefik_net

  phpmyadmin:
    image: phpmyadmin/phpmyadmin:latest
    container_name: phpmyadmin
    restart: always
    labels:
      - traefik.frontend.rule=Host:phpmyadmin.your_domain.duckdns.org
      - traefik.port=80
      - traefik.enable=true´
      - traefik.default.protocol=http
      - traefik.backend=phpmyadmin
    links:
      - db
    environment:
      - "MYSQL_USERNAME=root"
      - "MYSQL_ROOT_PASSWORD=your_password"
    networks:
      - traefik_net

  memcached:
    image: memcached:1.5.6
    container_name: memcached
    restart: always
    labels:
      - traefik.enable=false
    entrypoint: memcached -m 256
    networks:
      - traefik_net

  seafile:
    image: seafileltd/seafile-mc:latest
    container_name: seafile
    restart: always
    labels:
      - traefik.docker.network=traefik_net
      - traefik.enable=true
      - traefik.frontend.rule=Host:seafile.your_domain.duckdns.org
      - traefik.port=80
      - traefik.default.protocol=http
      - traefik.backend=seafile
    volumes:
      - /opt/seafile-data:/shared
    depends_on:
      - db
      - memcached   
    environment:
      - "DB_HOST=db"
      - "DB_ROOT_PASSWD=your_password"
      - "SEAFILE_ADMIN_EMAIL=admin@duckdns.org"
      - "SEAFILE_ADMIN_PASSWORD=your_password"
    networks:
      - traefik_net

  onlyoffice:
    image: onlyoffice/documentserver
    container_name: onlyoffice
    restart: always
    labels:
      - traefik.backend=onlyoffice
      - traefik.frontend.rule=Host:onlyoffice.your_domain.duckdns.org
      - traefik.port=80
      - traefik.enable=true
      - traefik.docker.network=traefik_net
      - traefik.default.protocol=http
    networks:
      - traefik_net

  duckdns:
    image: linuxserver/duckdns
    container_name: duckdns
    restart: always
    environment:
      - PUID=1000 #optional
      - PGID=1000 #optional
      - TZ=America/Argentina/Salta
      - SUBDOMAINS=your_domain
      - TOKEN=XXXXXXXXXXXXXXXXXXXXXX
      - LOG_FILE=true #optional
    volumes:
      - /opt/duckdns:/config #optional
    networks:
      - traefik_net

networks:
  traefik_net:
    external: true

Save the file and exit the text editor.

With these variables set, run the containers using docker-compose :

docker-compose up -d

Start seafile and onlyoffice

After a few minutes, you can open seafile by accessing port 80 of the machine ip, and the 8080 port of the machine will display Document Server is running.

Integrate seafile and onlyoffice
Wait for seafile to start normally, enter the container to modify the configuration file

docker exec -it seafile bash
vim conf/seahub_settings.py
Add the following at the bottom

FILE_SERVER_ROOT = "https://your_domain.duckdns.org/seafhttp"

    # Enable Only Office
    ENABLE_ONLYOFFICE = True
    VERIFY_ONLYOFFICE_CERTIFICATE = False
    ONLYOFFICE_APIJS_URL = 'https://onlyoffice.your_domain.duckdns.org/web-apps/apps/api/documents/api.js' #Change ip to native ip
    ONLYOFFICE_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'odt', 'fodt', 'odp', 'fodp', 'ods', 'fods')
    ONLYOFFICE_EDIT_FILE_EXTENSION = ('doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx')

Restart the container after exiting it

exit
docker restart seafile

## Conclusion

In this tutorial, you configured Traefik to proxy requests to other applications in Docker containers.

Traefik’s declarative configuration at the application container level makes it easy to configure more services, and there’s no need to restart the traefik container when you add new applications to proxy traffic to since Traefik notices the changes immediately through the Docker socket file it’s monitoring.

I hope it helps you with something. If you need it just by running with nginx, you change the image of nginx, remove the labels and it should work the same.
Greetings to all

1 Like

I’ve created almost an identical setup but OnlyOffice doesn’t work.

If I want to open a document an error is displayed that the document couldn’t been saved. A log entry on the OnlyOffice server is generated which says that the POST-Request to the callback URL timed out. The URL is reachable via GET but a POST request with Postman says “Page unavailable, server git a hiccup”

Regards,
Martin

Hi Martin, welcome to the Seafile Community Forum.

I just replied to you via PM.

Hi there, I am curious about a few things:

  • Is this still a working tutorial?
  • Do these images contain Nginx? I have seen many references about the official images using it for the proxy ( I want to use Traefik V2)
  • I have also seen many other tutorials around additional labels for things like WebDAV, etc… are those not needed?

Thanks in advance.