Traefic Routing for FireflyIII

  docker, docker-compose, routes, traefik

Greetings Stack Overflow,

I have a RespberryPi4B, on which I installed Ubuntu 20.
(Linux ubuntu 5.4.0-1034-raspi aarch64 – Ubuntu 20.04.1 LTS)

On this Pi I want to install several Applications for my local use only.
To be able to have multiple Applications exposed, I use Traefik as a Proxy.
To easier deploy the Applications, I use Docker and Docker-Compose

Already up and running I have a Nextcloud instance, which works just fine.
Now I want to add FireflyIII as an Application, but the routing does not comply, and greets me with "Bad Gateway".

Here’s what I have

The following docker-compose.yml for my Nextcloud works like a charm:

version: '3.3'

services:
  nextcloud-db:
    image: mariadb
    container_name: nextcloud-db
    command: --transaction-isolation=READ-COMMITTED --log-bin=ROW
    restart: unless-stopped
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - /opt/containers/nextcloud/database:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD={supersecret}
      - MYSQL_PASSWORD={supersecret}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloudusr
      - MYSQL_INITDB_SKIP_TZINFO=1
    networks:
      - default

  nextcloud-redis:
    image: redis:alpine
    container_name: nextcloud-redis
    hostname: nextcloud-redis
    networks:
        - default
    restart: unless-stopped
    command: redis-server --requirepass {supersecret}

  nextcloud-app:
    image: nextcloud
    container_name: nextcloud-app
    restart: unless-stopped
    depends_on:
      - nextcloud-db
      - nextcloud-redis
    environment:
        REDIS_HOST: nextcloud-redis
        REDIS_HOST_PASSWORD: {supersecret}
    volumes:
      - /opt/containers/nextcloud/app:/var/www/html
      - /opt/containers/nextcloud/daten:/var/www/html/data

    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nextcloud-app.entrypoints=http"
      - "traefik.http.routers.nextcloud-app.rule=Host(`nextcloud.mydomain.com`)"
      - "traefik.http.middlewares.nextcloud-app-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.nextcloud-app.middlewares=nextcloud-app-https-redirect"
      - "traefik.http.routers.nextcloud-app-secure.entrypoints=https"
      - "traefik.http.routers.nextcloud-app-secure.rule=Host(`nextcloud.mydomain.com`)"
      - "traefik.http.routers.nextcloud-app-secure.tls=true"
      - "traefik.http.routers.nextcloud-app-secure.tls.certresolver=http"
      - "traefik.http.routers.nextcloud-app-secure.service=nextcloud-app"
      - "traefik.http.services.nextcloud-app.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"
      - "traefik.http.routers.nextcloud-app-secure.middlewares=nextcloud-dav,[email protected]"
      - "traefik.http.middlewares.nextcloud-dav.replacepathregex.regex=^/.well-known/ca(l|rd)dav"
      - "traefik.http.middlewares.nextcloud-dav.replacepathregex.replacement=/remote.php/dav/"
    networks:
      - proxy
      - default

networks:
  proxy:
    external: true

While knowing that this configuration, and these traefik labels work, I would assume, that the following docker-compose.yml, now for FireflyIII would work as well. And while the container spins up without any visible issues – I can see in the container logs, that the applications connects to the database and prepares everything – the access via browser is not possible – I get a Bad Gateway.

This is my FireflyIII’s docker-compose.yml

version: '3.3'

services:
  fireflydb:
    image: mariadb
    container_name: fireflydb
    environment:
      - MYSQL_RANDOM_ROOT_PASSWORD=yes
      - MYSQL_USER=fireflyuser
      - MYSQL_PASSWORD={supersecret}
      - MYSQL_DATABASE=fireflydb
    volumes:
      - firefly_db:/var/lib/mysql
    networks:
      - default

  firefly:
    image: jc5x/firefly-iii:latest
    container_name: firefly
    volumes:
      - firefly_upload:/var/www/html/storage/upload
    depends_on:
      - fireflydb
    env_file: .env
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.firefly-app.entrypoints=http"
      - "traefik.http.routers.firefly-app.rule=Host(`firefly.mydomain.com`)"
      - "traefik.http.middlewares.firefly-app-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.firefly-app.middlewares=firefly-app-https-redirect"
      - "traefik.http.routers.firefly-app-secure.entrypoints=https"
      - "traefik.http.routers.firefly-app-secure.rule=Host(`firefly.mydomain.com`)"
      - "traefik.http.routers.firefly-app-secure.tls=true"
      - "traefik.http.routers.firefly-app-secure.tls.certresolver=http"
      - "traefik.http.routers.firefly-app-secure.service=firefly-app"
      - "traefik.http.services.firefly-app.loadbalancer.server.port=80"
      - "traefik.docker.network=proxy"
    networks:
      - proxy
      - default

volumes:
   firefly_upload:
   firefly_db:

networks:
   proxy:
      external: true

The only difference between the Traefik Labels is, that I don’t need the replacepathregex labels for firefly, and that I changed the Hosts and application names:

nextcloud.mydomain.com -> firefly.mydomain.com
nextcloud-app/nextcloud-app-secure -> firefly-app/firefly-app-secure

I just don’t understand yet, why the "same" configuration behaves differently.
The Traefik container logs don’t throw any errors.

A note about the SSL Certificates, since the applications are run in my local network, and I edit my local hostfile to access the application via browser, the SSL renewal isn’t possible, I am aware of that. I currently work around it by manually renewing on a different server and copying the cert to my Pi. Quick and dirty, but works for now.

For completeness, here’s my Traefik’s traefik.yml, docker-compose.yml and dynamic_conf.yml:

traefik.yml:

api:
  dashboard: true

entryPoints:
  http:
    address: ":80"
  https:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
  file:
    filename: "/dynamic_conf.yml"

certificatesResolvers:
  http:
    acme:
      email: [email protected]
      storage: acme.json
      httpChallenge:
        entryPoint: http

docker-compose.yml:

version: '3'

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    restart: unless-stopped
    security_opt:
      - no-new-privileges:true
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./data/traefik.yml:/traefik.yml:ro
      - ./data/acme.json:/acme.json
      - ./data/dynamic_conf.yml:/dynamic_conf.yml
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.traefik.entrypoints=http"
      - "traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)"
      - "traefik.http.middlewares.traefik-auth.basicauth.users=user:secret"
      - "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
      - "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
      - "traefik.http.routers.traefik-secure.entrypoints=https"
      - "traefik.http.routers.traefik-secure.rule=Host(`traefik.mydomain.com`)"
      - "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
      - "traefik.http.routers.traefik-secure.tls=true"
      - "traefik.http.routers.traefik-secure.tls.certresolver=http"
      - "[email protected]"
      - "providers.file.filename=/dynamic_conf.yml"

networks:
  proxy:
    external: true

dynamic_conf.yml

tls:
  options:
    default:
      minVersion: VersionTLS12

      cipherSuites:
        - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
        - TLS_AES_128_GCM_SHA256
        - TLS_AES_256_GCM_SHA384
        - TLS_CHACHA20_POLY1305_SHA256

      curvePreferences:
        - CurveP521
        - CurveP384

      sniStrict: true

http:
  middlewares:
    secHeaders:
      headers:
        browserXssFilter: true
        contentTypeNosniff: true
        frameDeny: true
        sslRedirect: true
        #HSTS Configuration
        stsIncludeSubdomains: true
        stsPreload: true
        stsSeconds: 31536000
        customFrameOptionsValue: "SAMEORIGIN"

The only thing I could think of, might be a problem with the internal Ports.
But I don’t know enough about traefik and docker yet, to say for sure.

I appreciate any hints and suggestions for improvement.

Source: Docker Questions

LEAVE A COMMENT