Configuration Traefik+Docker SSL

Hello,
I have been trying to get Traefik, Docker and OwnCloud to work for a couple of weeks. I have tried several guides, read documentation without anything nothing working. Finally i looked for a youtube guide (https://www.youtube.com/watch?v=2ImyICAC8nA) which made everything work! (only http though).

I have a couple of things i still dont understand totally and would appreciate some help with:

  1. Ports? there are ports internal/external in the yml file, ports both in for example my owncloud but also in traefik, how is the workflow of the ports? which port should i set from my router all the way to my owncloud container through traefik/docker?

  2. Next step would be to activate HTTPS, admin password? and maybe other security measures. How do i based on my docker-compose.yml file configure SSL/HTTPS,admin password and other security? Im planning on doing it with LetsEncrypt?

  3. Also are there any other things i should change/add?
    Would be very grateful for help

  • acme.json (/etc/traefik/) file created but empty for now

  • .env file (/home/*******/owncloud/)

Summary
OWNCLOUD_VERSION=10.14
OWNCLOUD_DOMAIN=localhost:8080
OWNCLOUD_TRUSTED_DOMAINS=localhost,<DDNS adress>,<public IP>
ADMIN_USERNAME=****
ADMIN_PASSWORD=****
HTTP_PORT=8090
  • docker-compose.yml (/home/*****/owncloud/)
Summary
volumes:
  files:
    driver: local
  mysql:
    driver: local
  redis:
    driver: local

services:
  owncloud:
    image: owncloud/server:${OWNCLOUD_VERSION}
    restart: always
    depends_on:
      - mariadb
      - redis
      - traefik
    ports:
      - ${HTTP_PORT}:8090
    environment:
      - OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
      - OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloud
      - OWNCLOUD_DB_USERNAME=owncloud
      - OWNCLOUD_DB_PASSWORD=owncloud
      - OWNCLOUD_DB_HOST=mariadb
      - OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
      - OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - OWNCLOUD_MYSQL_UTF8MB4=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
      - OWNCLOUD_VERSION_HIDE=true
      - OWNCLOUD_DEBUG_MODE=false
      - OWNCLOUD_SERVER_HOSTNAME_HIDE=true
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - files:/mnt/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.owncloud.rule=Host(`<mypublic-IP>`)"

  mariadb:
    image: mariadb:10.6
    container_name: owncloud_mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=****
      - MYSQL_USER=****
      - MYSQL_PASSWORD=****
      - MYSQL_DATABASE=****
    command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - mysql:/var/lib/mysql
    labels:
      - "traefik.enable=false"

  redis:
    image: redis:6
    container_name: owncloud_redis
    restart: always
    command: ["--databases", "1"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - redis:/data
    labels:
      - "traefik.enable=false"

  traefik:
    image: traefik:v3.1
    command: --api.insecure=true --providers.docker
    ports:
      - 80:80
      - 8080:8080
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Raspberry pi 5, Debian bookworm 12.
Docker 27.1.1
I access my docker through setting up a Dynu systems DDNS -> public IP -> Docker (Traefik)

Check simple Traefik example. Traefik needs to open container ports and define entrypoint ports. Then in dynamic config file or target container labels you define the internal ports to use.

Thank you for your reply,
I have read several examples and guides and no matter how i move around stuff in docker-compose.yml i cant seem to get anything to work.

I have checked the example you gave me which does not differ from other example i have read can you help me set it up by beeing more descriptive of what needs to be done?

I waited until last end to ask for help, im clueless and would not create this thread if it was as easy as following an example.

Examples/Guides i have used:

You set docker.network, but don’t use a Docker network and don’t attach Traefik and target service to it.

You can’t mix traefik.yml/toml and static config in command:.

You should only open ports: on Traefik, not on other services/containers. Otherwise security middlewares could be circumvented.

You should probably set the correct target service port in labels, as in example.

You set docker.network, but don’t use a Docker network and don’t attach Traefik and target service to it.

I have searched the files provided in this thread after docker.network but cant find it?

You can’t mix traefik.yml/toml and static config in command:.

Correct, must have had a brainfreeze when i posted the traefik.toml file as its not used in setting up dockercontainers

You should only open ports: on Traefik, not on other services/containers. Otherwise security middlewares could be circumvented.

Got it, so i remove "ports:" from owncloud in docker-compose file

   ports:
      - ${HTTP_PORT}:8080

You should probably set the correct target service port in labels, as in example.

like this?
services:
owncloud:
....
labels:
- "traefik.http.services.owncloud.loadbalancer.server.port=8080"

Also do i need the whoami container? and if yes, what is the use of it?

whoami is just an example. Replace it with owncloud, use the labels and adapt the port.

I did as your simple Traefik example and tried to adapt it to my container:
Now i get to the dashboard of docker in the browser, what do i need to do to get to the container?

Docker-compose.yml
networks:
  proxy:
    name: proxy
volumes:
  files:
    driver: local
  mysql:
    driver: local
  redis:
    driver: local
  letsencrypt:
    name: letsencrypt

services:
  owncloud:
    image: owncloud/server:${OWNCLOUD_VERSION}
    restart: always
    depends_on:
      - mariadb
      - redis
      - traefik
    environment:
      - OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
      - OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=owncloud
      - OWNCLOUD_DB_USERNAME=****
      - OWNCLOUD_DB_PASSWORD=****
      - OWNCLOUD_DB_HOST=mariadb
      - OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
      - OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - OWNCLOUD_MYSQL_UTF8MB4=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
      - OWNCLOUD_VERSION_HIDE=true
      - OWNCLOUD_DEBUG_MODE=false
      - OWNCLOUD_SERVER_HOSTNAME_HIDE=true
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - files:/mnt/data
    labels:
      - traefik.enable=true
      - traefik.http.routers.owncloud.rule=Host(`****.com`) || Host(`www.****.com`)
      - traefik.http.services.owncloud.loadbalancer.server.port=80
      - traefik.http.middlewares.mywwwredirect.redirectregex.regex=^https://www\.(.*)
      - traefik.http.middlewares.mywwwredirect.redirectregex.replacement=https://$${1}
      - traefik.http.routers.owncloud.middlewares=mywwwredirect
    networks:
      - proxy

  mariadb:
    image: mariadb:10.6
    container_name: owncloud_mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=*****
      - MYSQL_USER=*****
      - MYSQL_PASSWORD=*****
      - MYSQL_DATABASE=*****
    command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=owncloud"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - mysql:/var/lib/mysql
    labels:
      - "traefik.enable=false"
    networks:
      - proxy

  redis:
    image: redis:6
    container_name: owncloud_redis
    restart: always
    command: ["--databases", "1"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - redis:/data
    labels:
      - "traefik.enable=false"
    networks:
      - proxy

  traefik:
    image: traefik:v3.1
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - letsencrypt:/letsencrypt
      #- /var/log:/var/log
    command:
      - --api.dashboard=true
      - --log.level=INFO
      - --log.filepath=/home/****/owncloud/traefik.log
      - --accesslog=true
      - --accesslog.filepath=/home/****/owncloud/traefik-access.log
      - --providers.docker.network=web
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entryPoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.asDefault=true
      - --entrypoints.websecure.http.tls.certresolver=myresolver
      - --certificatesresolvers.myresolver.acme.email=****@hotmail.com
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
    labels:
      - traefik.enable=true
      - traefik.http.routers.mydashboard.rule=Host(`****.com`)
      - traefik.http.routers.mydashboard.service=api@internal
      #- traefik.http.routers.mydashboard.middlewares=myauth
      #- traefik.http.middlewares.myauth.basicauth.users=*****:$$****$$****/l$$*******/

You should use different (sub-) domains for Owncloud and Traefik.

Or specify the paths used for Traefik dashboard, if they don’t conflict with your other app (doc)

# Dynamic Configuration
labels:
  - "traefik.http.routers.dashboard.rule=Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))"
  - "traefik.http.routers.dashboard.service=api@internal"
  - "traefik.http.routers.dashboard.middlewares=auth"
  - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"

Or disable Traefik dashboard by removing the labels completely.

Removed it and now i get gateway timeout, have tried from different devices
see updated code below

Summary
networks:
  proxy:
    name: proxy

volumes:
  files:
    driver: local
  mysql:
    driver: local
  redis:
    driver: local
  letsencrypt:
    name: letsencrypt

services:
  owncloud:
    image: owncloud/server:${OWNCLOUD_VERSION}
    restart: always
    depends_on:
      - mariadb
      - redis
      - traefik
    environment:
      - OWNCLOUD_DOMAIN=${OWNCLOUD_DOMAIN}
      - OWNCLOUD_TRUSTED_DOMAINS=${OWNCLOUD_TRUSTED_DOMAINS}
      - OWNCLOUD_DB_TYPE=mysql
      - OWNCLOUD_DB_NAME=****
      - OWNCLOUD_DB_USERNAME=****
      - OWNCLOUD_DB_PASSWORD=****
      - OWNCLOUD_DB_HOST=mariadb
      - OWNCLOUD_ADMIN_USERNAME=${ADMIN_USERNAME}
      - OWNCLOUD_ADMIN_PASSWORD=${ADMIN_PASSWORD}
      - OWNCLOUD_MYSQL_UTF8MB4=true
      - OWNCLOUD_REDIS_ENABLED=true
      - OWNCLOUD_REDIS_HOST=redis
      - OWNCLOUD_VERSION_HIDE=true
      - OWNCLOUD_DEBUG_MODE=false
      - OWNCLOUD_SERVER_HOSTNAME_HIDE=true
    healthcheck:
      test: ["CMD", "/usr/bin/healthcheck"]
      interval: 30s
      timeout: 10s
      retries: 5
    volumes:
      - files:/mnt/data
    labels:
      - traefik.enable=true
      - traefik.http.routers.owncloud.rule=Host(`****`)
      - traefik.http.services.owncloud.loadbalancer.server.port=80
      - traefik.http.middlewares.mywwwredirect.redirectregex.regex=^https://www\.(.*)
      - traefik.http.middlewares.mywwwredirect.redirectregex.replacement=https://$${1}
      - traefik.http.routers.owncloud.middlewares=mywwwredirect
    networks:
      - proxy

  mariadb:
    image: mariadb:10.6
    container_name: owncloud_mariadb
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=****
      - MYSQL_USER=****
      - MYSQL_PASSWORD=****
      - MYSQL_DATABASE=****
    command: ["--max-allowed-packet=128M", "--innodb-log-file-size=64M"]
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-u", "root", "--password=****"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - mysql:/var/lib/mysql
    labels:
      - "traefik.enable=false"
    networks:
      - proxy

  redis:
    image: redis:6
    container_name: owncloud_redis
    restart: always
    command: ["--databases", "1"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - redis:/data
    labels:
      - "traefik.enable=false"
    networks:
      - proxy

  traefik:
    image: traefik:v3.1
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - letsencrypt:/letsencrypt
      - /var/log:/var/log
    command:
      - --api.dashboard=true
      - --log.level=INFO
      - --log.filepath=/home/****/owncloud/traefik.log
      - --accesslog=true
      - --accesslog.filepath=/home/****/owncloud/traefik-access.log
      - --providers.docker.network=proxy
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entryPoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --entrypoints.websecure.asDefault=true
      - --entrypoints.websecure.http.tls.certresolver=myresolver
      - --certificatesresolvers.myresolver.acme.email=****@hotmail.com
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json
    labels:
      - traefik.enable=true


In host, do i need to type a domainname? or does it work with my public ip for testing purposes?
example:

- traefik.http.routers.owncloud.rule=Host(`30.200.180.249`)

Traefik doesn’t work because it’s not attached to the proxy Docker network.

And you can’t use a simple IP, as you have everything configured for https. To generate LetsEncrypt TLS certs, you need to use real domain names.

Thank you!!

Last part i cant seem to get working is how to setup Traefik+Letsencrypt with Dynu DDNS, I can access my owncloud now but https is still crossed out in the browser

when i do a curl i get the following "curl: (60) SSL certificate problem: self-signed certificate"

I have found dynu on Traefik Let's Encrypt Documentation - Traefik so i guess it will work, Traefik also references to Installation :: Let’s Encrypt client and ACME library written in Go.

Should i install Lego? or do i just need to tweak some parameters on dynu or traefik?

Fixed it!!!
Seemed my firewall was blocking something so i disabled it, now i need to find which port is blocking