How to configure the second version of the popular reverse proxy Traefik for Nextcloud in Docker.

Those who run their own Linux server at home and want SSL-protected access to their Nextcloud from the Internet will find Traefik to be a well-functioning and modern reverse proxy. Since the release of version 2.0, the many configuration examples found on the Internet are unfortunately incompatible with the current version.

In this article I will show you how to configure your Docker and Traefik containers so that SSL certificates are obtained via TLS Challenge. I have also considered all settings that are necessary for the “HTTP Strict Transport Security” mechanism. In my Github repository you can see the complete Docker setup.

The configuration of the Traefik version 2.x container

At this point the general settings of the Traefik container are made and the certificate resolver is configured. It is important to distinguish that the configuration of the offered services is done on the side of the service container and not in the configuration of the Traefik container. bug

version: "3.3"
services:
  traefik:
    image: "traefik:latest"
    container_name: "traefik2"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      #- "--certificatesresolvers.mytlschallenge.acmbuge.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
      - "--certificatesresolvers.mytlschallenge.acme.email=***youremail@here***"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "443:443"
      - "8080:8080"
    volumes:
      - "./letsencrypt:/letsencrypt"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - traefik_proxy
      - default
    logging:
      options:
        max-size: '12m'
        max-file: '5'
      driver: json-file

networks:
  traefik_proxy:
    external:
      name: traefik_proxy
  default:
    driver: bridge

The configuration of the Nextcloud container

The Nextcloud container needs some labels that define which configuration Traefik offers for this container. Specifically, the router and the middleware, which modifies the HTTP headers, are configured here.

labels:
  - "traefik.enable=true"
  - "traefik.port=80"
  - "traefik.http.routers.cloud.entrypoints=websecure"
  - "traefik.http.routers.cloud.rule=Host(`yourhostname`)"
  - "traefik.http.routers.cloud.tls.certresolver=mytlschallenge"
  - "traefik.http.routers.cloud.middlewares=cloud@docker"
  - "traefik.docker.network=traefik_proxy"
  - "traefik.http.middlewares.cloud.headers.customFrameOptionsValue=SAMEORIGIN"
  - "traefik.http.middlewares.cloud.headers.framedeny=true"
  - "traefik.http.middlewares.cloud.headers.sslredirect=true"
  - "traefik.http.middlewares.cloud.headers.stsIncludeSubdomains=true"
  - "traefik.http.middlewares.cloud.headers.stsPreload=true"
  - "traefik.http.middlewares.cloud.headers.stsSeconds=15552000"

Please check my Github repository for complete docker-compose-files: https://github.com/bedawi/liberty-server

Step-by-step howto

Step 1: Prepare your linux server.

Install docker and docker-compose. Here is an example how this works on Fedora 31: (Please make sure you understand what these commands mean – do not copy and paste!)

$ curl -fsSL https://get.docker.com -o get-docker.sh
$ sudo bash get-docker.sh
$ sudo pip install docker-compose
$ sudo dnf -y install git vim
$ sudo usermod -aG docker YOURUSERNAMEHERE
$ sudo systemctl enable docker.socket
$ sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=0" --make-default
$ sudo reboot

Step 2: Prepare your folder

Now create a folder where you want to store your containers’s configuration and the files of the nextcloud server.

$ sudo mkdir /SOMEDATAFOLDER
$ sudo chown YOURUSERNAME:YOURGROUPNAME /SOMEDATAFOLDER

After this, cd into the new folder and clone my repository:

$ cd /SOMEDATAFOLDER
$ git clone https://github.com/bedawi/liberty-server.git

Copy the example configurations for traefik and nextcloud to your data folder:

$ cp -r liberty-server/traefik2 .
$ cp -r liberty-server/nextcloud .
$ cp -r liberty-server/database .

Now create the needed docker networks for nextcloud and traefik:

Step 3: Traefik

$ docker network create nextcloud_backend
$ docker network create traefik_proxy

Now edit the docker-composer file in the traefik2 folder and set your eMail address. This is important for registration of your domain with Let’s Encrypt. If you do not provide a valid address here ou will not be notified when there is a problem with your certificates!

Editing traefik’s docker compose file and setting an eMail address.

After this, start up traefik:

$ docker-compose up -d
Starting traefik

Step 4: Database

To set up the database, cd into the folder, edit the docker compose file and set a password. Bring up the database after this:

Step 5: Nextcloud

Next, cd into the nextcloud-folder and edit the docker-compose file. Set your machine’s hostname and bring the container up.

In the following example I also enable port 80 for bypassing traefik, just in case it does not work for some reason:

Initialization takes a while. Wait until you see the following message:

[Sun Jan 26 12:02:34.084218 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'

Now try to access your machine on https://yourmachinename/ … if this dows not work, try the fallback on http://yourmachinename/ (without the s in https – this is the port 80 we opened deliberately for debugging)

In the nextcloud setup dialog select “MySQL/MariaDB” and type in the database name, user and password from your docker-compose file. The server address is “cloud-db”.

After your setup is completed, ctrl-c the “docker-compose up”-command in your terminal, remove the port 80 from the docker-compose-file and delete the created container with

$ docker rm nextcloud-app

Then start it with

$ docker-compose up -d

No individual support – Sorry!

Dear readers. I know that docker administration can be confusing and frustrating for beginners. There is so much to learn and I wish I had the time to sit down with every new Linux container admin for tea and biscuits to go through his/her individual configuration. Unfortunately this is not possible because besides my daytime job I have a cat and a partner competing for my attention.

Please do not post individual requests for help into the comments. Instead try to figure out how docker works on your own. To learn docker one could for example attend to an online course on linuxacademy.com.

Found a bug?

Everyone makes mistakes and my code is never 100% bug free. If you found an error on my project, please use the issues-page on github.

19 Comments

  1. Great work!! It works!!
    Could you explain middleware labels please?
    Most of these parameters are out of my knowledge..

  2. I’m new to docker and Traefik and I’m having a hard time getting this to work. For the nextcloud site firefox tells me “SSL_ERROR_INTERNAL_ERROR_ALERT”. Can’t for the life of me tell where ive messed up my configs.

    1. Sorry my dear, without more details I cannot help. Did you clone my repo? ( https://github.com/bedawi/liberty-server ) How do your docker-compose files look like? Have you had a look into the log-file of traefik? Do you have a firewall / web application firewall installed in front of your machine? What messages does the journal of your distribution throw? ( $ journalctl -f )
      Hint: Install Portainer ( https://www.portainer.io/installation/ ) and look into the log files of traefik and nextcloud.

      1. Apologies. I was not sure what info you would want to look at.
        I did clone the repo via git.
        There is a firewall in front. I have ports 80 and 443 forwarded to the server.

        I made some progress and found a silly typo in my domain name in the nextcloud docker compose file. However I am still unable to connect, Now getting “Gateway Timeout”

        This Portainer is really neat I wish I knew about it before!

        Docker compose files:
        Trae: https://pastebin.com/L4fkhaEx
        NC: https://pastebin.com/6aenVbPy
        DB: https://pastebin.com/P49GjS3H

        Trae Log: https://pastebin.com/0BzkcpDs

        Thank you for your time 🙂

          1. Thanks for the reply! I noticed that error as well and fixed it (I just started over by re-cloning the repo) but alas I’m still having no luck. Same error I’m afraid.

          2. – “traefik.http.routers.cloud.rule=Host(`nc.example.com`)” # Put in your hostname here, e.g. subdomain.domain.tld

            ^^ this must be set on your nextcloud container.
            Usually “Bad Gateway” means that the destination container is unreachaeable from traefik. If you did not set the hostname it would be explained. Also please note that sometimes traefik needs a restart, after changes with a container.

  3. The hostname is set, I just changed it to example.com for the post here. I have tried restarting all the containers (many many times haha).

    1. @Christian and @Zach: I found an error in my repo. The traefik container and the nextcloud container did not use the same network “traefik_proxy” – instead nextcloud’s docker-compose-file refered to “webproxy”. I fixed this error on the repository.
      Furthermore it can be helpful to open port 80 on nextcloud and bypass traefik for the setup phase. Check out the new docker-compose-file of nextcloud where I added two line to open port 80 directly.

      1. Oh awesome! I was thinking it was something like that but I didn’t notice it when I was looking. In the next few days I’ll give it another shot, but I ended up installing NextCloud on bare metal instead. But I do wanna look into Matrix soon anyway so that is a good excuse 🙂

        Thanks for your help!

        1. Note – the webproxy reference is still found in the nextcloud/docker-compose.yaml and matrix-synapse/docker-compose.yaml.

  4. HOW! to get such a beautfiull looking shell <3

    I know it is offtopic, but it looks reaaaaaly nice 🙂

Comments are closed.