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:
- One Ubuntu 18.04 server set up by following the Ubuntu 18.04 initial server setup guide, including a sudo non-root user and a firewall.
- Docker installed on your server, which you can do by following How to Install and Use Docker on Ubuntu 18.04.
- Docker Compose installed with the instructions from How to Install Docker Compose on Ubuntu 18.04.
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