Blog

Set up ownCloud + Traefik as a Reverse Proxy with Let’s Encrypt SSL

Docker Series Pt.2: Docker is an easy and powerful way to set up ownCloud, making it easy to extend the architecture. The reverse proxy Traefik, for example, integrates other services and can provide Let’s Encrypt SSL certificates.
ownCloud Docker Series

In the first blog post of this series you learned how to set up ownCloud with docker-compose. This tutorial builds on this knowledge to build an advanced docker setup. Docker can do far more than just setting up containers, it also makes communication between containers easier.

A reverse proxy is useful in many ways. You can integrate multiple services easily in your setup, while they are reachable with only one public IP. It can also provide and automate Let’s Encrypt SSL certificates – for all your services.

Using Traefik has many advantages: it is easy to set up, it has a useful web interface, and it’s specifically designed to work with docker containers.

This guide explains how to set up Docker with Traefik and integrate an ownCloud into it. Integrating other docker images like WordPressJitsiMailman, or Collabora works in a similar way… try it out and play around!

The First Steps

This guide assumes that you already have docker-compose installed on your machine. If you haven’t, just follow these official instructions for your operating system.

First you have to create a network for all services which should be reachable from the Internet. We then need to define it outside of a docker-compose file, as we want to use it for multiple docker-compose files:

docker network create web

This way, your database containers are protected. Not even Traefik can see them, they will all get their own internal network later, one for each service.

Then we will set up our working directory. You can also use another place on the system, but then you will have to change all the paths in this guide.

mkdir -p /opt/traefik
touch /opt/traefik/docker-compose.yml
touch /opt/traefik/acme.json && chmod 600 /opt/traefik/acme.json
touch /opt/traefik/traefik.toml

Let’s also assume that you have bought a domain which is pointing to the IP address of your server. Each of your services will need a subdomain, but they can all point to the same IP. Here’s an example:

ownCloud docker traefik dns settings

Example IPv4 DNS settings for your server

In this guide, the domain and subdomains are example.com, traefik.example.com, and owncloud.example.com – you will need to exchange it with your domain name when you are copy-pasting the docker-compose and config files.

Define the Traefik Container

Now we will set up Traefik. First create and edit the traefik docker-compose file with vim /opt/traefik/docker-compose.yml:

version: '2'

services:
  proxy:
    # You might want to use a proper version
    image: traefik
    command: --configFile=/traefik.toml
    restart: unless-stopped
    # Here's the network we created:
    networks:
      - web
    # The traefik entryPoints
    ports:
      - 80:80
      - 443:443
    labels:
      - traefik.enable=true
      - traefik.frontend.rule=Host:traefik.example.com
      # Traefik will proxy to its own GUI.
      - traefik.port=8080
      - traefik.docker.network=web
    volumes: 
      - /var/run/docker.sock:/var/run/docker.sock 
      - /opt/traefik/traefik.toml:/traefik.toml 
      - /opt/traefik/acme.json:/acme.json 

networks: 
  web: 
    external: true 

You should of course replace example.com in the docker-compose file with your own domain name.

The Traefik Config File

Traefik has a toml config file to manage entry points, Let’s Encrypt settings, and the web interface. Create the traefik config file with vim /opt/traefik/traefik.toml:

# uncomment this line to get debug info with "docker logs":
#debug = true

defaultEntryPoints = ["https","http"]

# The syntax is somewhat esoteric so this is mostly copy-paste
[entryPoints]
  [entryPoints.http]
  address = ":80"
    [entryPoints.http.redirect]
    entryPoint = "https"
  [entryPoints.https]
  address = ":443"
  [entryPoints.https.tls]

[docker]
endpoint = "unix:///var/run/docker.sock"
domain = "example.com"
watch = true
exposedbydefault = false

[acme]
email = ""
storage = "/acme.json"
# problems with let's encrypt? You can use this staging environment, 
# if you have to do a lot of trial and error:
#caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
entryPoint = "https"
OnHostRule = true
[acme.httpChallenge]
entryPoint = "http"

# enable web configuration backend.
[web]

# Web administration port, proxied in docker-compose.yml
address = ":8080"

You need to add your domain and email address at [docker] and [acme], so that the config file works for you. The values you have to change are in bold.

This traefik.toml automatically fetches a Let’s Encrypt SSL certificate, and also redirects all unencrypted HTTP traffic to port 443. This way, no one accidentally accesses your ownCloud without encryption.

Now we are good to go! Run the container with docker-compose -f /opt/traefik/docker-compose.yml up -d. And that’s it!

If Let’s Encrypt doesn’t work out of the box, you may have to do some troubleshooting. Note that Let’s Encrypt blocks certificate requests if you try too often; that’s why you can use the alternative caServer option in traefik.toml.

If you uncomment it, Traefik asks the Let’s Encrypt staging server for an (untrusted) certificate. When you get that to work, you can then comment out the caServer option again, so it uses the default server for fetching trusted certificates. Good luck troubleshooting!

If it works, you can visit traefik.example.com to look at the web interface. It should look like this:

ownCloud docker traefik web interface

The Traefik web interface with no other containers running yet.

Add Basic Authentication for Traefik

If you want to expose the Traefik web interface, you would probably like to have some form of authentication. Basic auth is supported so let’s add that. Run this for the username you want – for example admin – and enter your password. It will compute a hash of the password, which you can use in the docker-compose file:

htpasswd -n username

Here’s what I got for admin/admin:

admin:$apr1$IBj9Hfsd$kf7vXLpY4/9XD365jcp/n1

(Don’t use admin/admin as a password combination. Every hacker tries that first.)

Now that needs to go in the docker-compose.yml. Add this to the labels-section: (Note: any $ signs have to be escaped with another $.)

    labels:
      - "traefik.frontend.auth.basic=admin:$$apr1$$IBj9Hfsd$$kf7vXLpY4/9XD365jcp/n1"

Rebuild your container with docker-compose -f /opt/traefik/docker-compose.yml up -d and now you should have basic auth! Just visit traefik.example.com again – and you will be prompted for a password.

Now you have a running Traefik container, with a secured web interface, where you can watch the containers that Traefik is handling.

Add the ownCloud Containers

Now let’s add an ownCloud to this setup. We’ve already covered the ownCloud docker-compose file in the last blogpost, biut now you will learn how to integrate it here.

First, create a folder for ownCloud and edit the docker-compose.yml with

mkdir /opt/ownCloud
vim /opt/ownCloud/docker-compose.yml

You can use this as an example, but you should use your own domain instead of example.comand change any insecure default passwords. Everything you have to change is in bold here:

version: '2.1'
volumes:
files:
driver: local
mysql:
driver: local
backup:
driver: local
redis:
driver: local
services:
owncloud:
image: owncloud/server:10.0
restart: unless-stopped
depends_on:
- db
      - redis
    environment:
- OWNCLOUD_DOMAIN=owncloud.example.com
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloud
      - OWNCLOUD_DB_USERNAME=owncloud
      - OWNCLOUD_DB_PASSWORD=owncloud
      - OWNCLOUD_DB_HOST=db
      - OWNCLOUD_ADMIN_USERNAME=admin
      - OWNCLOUD_ADMIN_PASSWORD=admin
      - OWNCLOUD_UTF8MB4_ENABLED=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
    networks:
- web
      - internal
    labels:
- traefik.enable=true
      - traefik.frontend.rule=Host:owncloud.example.com
      - traefik.port=80
      - traefik.docker.network=web
    healthcheck:
test: ["CMD", "/usr/bin/healthcheck"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- files:/mnt/data

db:
image: webhippie/mariadb:latest
restart: unless-stopped
environment:
- MARIADB_ROOT_PASSWORD=owncloud
      - MARIADB_USERNAME=owncloud
      - MARIADB_PASSWORD=owncloud
      - MARIADB_DATABASE=owncloud
      - MARIADB_MAX_ALLOWED_PACKET=128M
      - MARIADB_INNODB_LOG_FILE_SIZE=64M
      - MARIADB_INNODB_LARGE_PREFIX=ON
      - MARIADB_INNODB_FILE_FORMAT=Barracuda
    healthcheck:
test: ["CMD", "/usr/bin/healthcheck"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- mysql:/var/lib/mysql
      - backup:/var/lib/backup
    networks:
- internal

redis:
image: webhippie/redis:latest
restart: unless-stopped
environment:
- REDIS_DATABASES=1
    healthcheck:
test: ["CMD", "/usr/bin/healthcheck"]
interval: 30s
timeout: 10s
retries: 5
volumes:
- redis:/var/lib/redis
    networks:
- internal

networks:
web:
external: true
internal:

If you read carefully, you will notice that we only expose port 80 for the ownCloud container. How does this fit with using SSL certificates?

Well, the ownCloud container does not communicate with the outside at all – only with the Traefik container. Traefik does not need to encrypt the traffic to the ownCloud container and vice versa, they are on the same machine anyway. As Traefik handles the SSL encryption, ownCloud does not even need to know that users are accessing it encrypted.

You can run the container with docker-compose -f /opt/ownCloud/docker-compose.yml up -d and then ownCloud starts! As soon as the health test at docker ps shows the ownCloud container as being healthy, Traefik will start routing to it. You can check if your ownCloud works at owncloud.example.com.

Congratulations! You just set up ownCloud with Traefik. What’s next?

Play Around with Docker!

You can also add other services like, as we already mentioned, WordPressJitsiMailman, and Collabora, but there are also hundreds of others to choose from. All of them are only a container away.

When you have integrated some services and have a cool docker-compose file for your setup, why not share it, so that everyone can learn from it? This way, others have an easier time setting it up – or can point out where you can improve your setup.

Did you encounter problems with this guide? You can always ask in the comments for advice. And if you made it through this how-to easily, share your success on social media!

A big warm thank you to Jon Neverland for his blogpost Traefik with Docker and Let’s encrypt

Did you like this how-to? Share it on social media. If you want to learn more about docker, stay tuned! This is the second part of a series about docker. Click here for part one and here for part three!

ownCloud

September 6, 2018

Read now:

Understanding Web Applications in oCIS

Understanding Web Applications in oCIS

In today’s fast-paced digital world, web applications play a crucial role in enhancing user experience and functionality. Infinite Scale comes with a world-class web interface to manage file resources, but it can be extended by utilizing ownCloud Infinite Scale (oCIS) as a construction set for custom web apps.

read more
Full digital sovereignty has 3 levels

Full digital sovereignty has 3 levels

Digital sovereignty is becoming increasingly important for public authorities and companies – and they already have the option of using fully sovereign software stacks. Content collaboration specialist ownCloud explains what sets them apart.

read more