VPS Proof of Concept for Docker and Traefik

CSF Docker Configuration

Disable Docker daemon automatic iptable rules with an override at the ExecStart section of the main docker.service. This prevents the Docker daemon from configuring iptables.

sudo nano /etc/systemd/system/multi-user.target.wants/docker.service

Append --iptables=false to ExecStart=/usr/bin/dockerd -H fd://. For example,

ExecStart=/usr/bin/dockerd -H fd:// --iptables=false

If Docker gets an upgrade during apt-get dist-upgrade, this docker.service file may get overwritten and you will need update it to override ExecStart again.

For Docker iptables, create a csfpost.sh script that will be triggered after the ConfigServer firewall has been started or reloaded.

sudo nano /etc/csf/csfpost.sh

echo "[DOCKER] Setting up FW rules."

iptables -N DOCKER

# Masquerade outbound connections from containers
iptables -t nat -A POSTROUTING -s ! -o docker0 -j MASQUERADE

# Accept established connections to the docker containers
iptables -t filter -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Allow docker containers to communicate with themselves & outside world
iptables -t filter -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
iptables -t filter -A FORWARD -i docker0 -o docker0 -j ACCEPT

echo "[DOCKER] Done."

Make the script executable.

sudo chmod +x /etc/csf/csfpost.sh

Add an exception to allow container traffic through the firewall.

sudo nano /etc/csf/csf.allow
# The following IP addresses will be allowed through iptables # Docker

Reload the systemd daemon to pickup these changes, restart the docker daemon and reload the ConfigServer firewall.

sudo systemctl daemon-reload

sudo systemctl restart docker

sudo csf -r

Basic Auth

This will be used to password protect applications as needed.

Use the htpasswd utility included in the apache2-utils package to create an encrypted password.

sudo apt-get install apache2-utils

Generate the password with htpasswd. For example, user admin and password secret.

htpasswd -nb admin secret

Copy the output, it will be added to the traefik.toml file created in the next step. For example, copy:



Use Docker Compose to setup Traefik reverse proxy and load balancer as a docker container. Within the home directory, create a new directory named docker for the configuration files. Create another directory for docker/traefik files.

cd ~/
mkdir docker
mkdir docker/traefik

Create a traefik/traefik.toml to configure entry points and the web provider for access to the dashboard interface.

nano docker/traefik/traefik.toml
defaultEntryPoints = ["http", "https"]

address = ":8080"
  users = ["admin:$apr1$m7bjJGAs$yoFBU4EmPy0wAQuKccomQ/"]


address = ":80"
entryPoint = "http"

# [entryPoints.https]
# address = ":443"

# [entryPoints.https.tls]

# [acme]
# email = "myemail@example.com"
# storage = "acme.json"
# entryPoint = "https"
# onDemand = false
# OnHostRule = true
# [acme.httpChallenge]
# entryPoint = "http"
# provider = ""
# delayBeforeCheck = 0

Traefik has built in support for the free Let’s Encrypt SSL certificate retrieval service. A server with a public domain is needed for the service to validate. The traefik.toml file example above contains a commented stub for reference.

Let’s Encrypt has permanently disabled TLS-SNI-0x challenge due to a vulnerability and Traefik prior to 1.5 was using TLS-SNI-01 challenge by default. Refer to the [acme] configuration docs for the new [acme.httpChallenge] section as needed.


Create a traefik/dockerfile to add the traefik.toml to the image.

nano docker/traefik/dockerfile
FROM traefik
ADD traefik.toml .
# EXPOSE 443

Create a traefik/docker-compose.yml file to configure Traefik services and networks.

version: '2'

    build: .
    restart: always
    command: --docker --logLevel=DEBUG
      - webgateway
      - "80:80"
#      - "443:443"
      - "8080:8080"
      - /var/run/docker.sock:/var/run/docker.sock

    driver: bridge

Update CSF firewall configuration to allow traffic on the password protected port 8080.

sudo nano /etc/csf/csf.conf

Append 8080 to the list of TCP ports. For example,

# Allow incoming TCP ports
TCP_IN = "20,21,22,25,53,80,110,143,443,465,587,993,995,8080"

# Allow outgoing TCP ports
TCP_OUT = "20,21,22,25,53,80,110,113,443,587,993,995,8080"

Use docker-compose to create the Docker container and run the traefik application.

docker-compose -f ~/docker/traefik/docker-compose.yml up -d


Navigate to the VM in a browser using the IP address over port 8080 to login to the Traefik dashboard. For example, which redirects to

Create a whoami/docker-compose.yml file to configure another container application labeled whoami. The image for this container uses a tiny Go webserver that prints system information and HTTP request to output.

mkdir ~/docker/whoami

nano ~/docker/whoami/docker-compose.yml
version: '2'

    image: emilevauge/whoami
      - web
      - "traefik.backend=whoami"
      - "traefik.frontend.rule=PathPrefixStrip: /whoami" # IP/whoami/
      # - "traefik.frontend.rule=Host:vm.ubuntuserver.whoami.com"

      name: traefik_webgateway

Access the application in a browser using the VM IP address. For example, To use a domain name, add vm.ubuntuserver.whoami.com to your computers hosts file. Then remove the comment for the Host frontend rule in the whoami/docker-compose.yml.

When you’re done testing everything and ready to enable the firewall, disable the testing flag.

sudo nano /etc/csf/csf.conf

Set TESTING = "0" and reload.

sudo csf -r


comments powered by Disqus