Traefik and an application running with nginx

Thank you for your response
Im sharing my traefik.yaml since I use systemctl to make it up and running so you can find it as fololows:

log:
  level: INFO

api:
  insecure: true
  dashboard: true




entrypoints:
  authenticated:
    address: ":86"
  web:
    address: ":85"
providers:
  file:
    filename: /etc/traefik/traefik.yaml
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
network: traefik_net



middlewares:
  redirect-to-https:
    redirectScheme:
      scheme: https

  forward-auth:
    forwardAuth:
      address: http://forward-auth:4181
      trustForwardHeader: true
      authResponseHeaders: X-Forwarded-User
      whitelistDomains: example.com
      providersOIDC:
        name: oidc
        clientID: farnoosh.aslan@yahoo.com
        clientSecret: aslan
        issuerURL: https://192.168.1.53/.well-known/openid-configuration
        scopes: "openid email profile"
        userIDKey: sub
        usernameKey: email


http:
  middlewares:
    redirect-to-https@file: {}
    forwar-auth@file: {}
routers:

   zitadel-router:
     entryPoints:
     - web
     middlewares:
    - redirect-to-https
     rule: 'HostRegexp(`192.168.1.53`, `{subdomain:[a-z]+}.192.168.1.53`)'
     service: zitadel
   mypage-router:
      entryPoints:
        - web
      middlewares:
        - forward-auth
      rule: "Host(`192.168.1.53`) && PathPrefix(`/mypage`)"
      service: mypage





services:

   zitadel:
     loadBalancer:
       servers:
       - url: "http://zitadel"
       passHostHeader: true
   mypagepage-service:
     loadBalancer:
       servers:
       - url: "http://mypage.192.168.1.53"

my traefik-docker-compose.yaml:

version: '3.8'
services:

  mypage:
    networks:
      - traefik_net
    image: "mypage"
    volumes:
      - ./mypage:/home/mypage:ro
    container_name: mypage
    labels:
      - "traefik.enable=true"
      - "traefik.http.middlewares.mypage-https.redirectscheme.scheme=https"
      - "traefik.http.routers.mypage.entrypoints=web"
      - "traefik.http.routers.mypage.rule=Host(`mypage.192.168.1.53`) && Path(`/mypage`)"
      - "traefik.http.routers.mypage.middlewares=forward-auth"
      - "traefik.http.routers.mypage.priority=100"
  traefik-auth:
    container_name: traefik-auth
    image: funkypenguin/traefik-forward-auth
    restart: always
    networks:
      - traefik_net
    stdin_open: true
    tty: true
    environment:
      SECRET: /zitadel-secrets.yaml
      AUTH_HOST: auth.192.168.1.53
      LOG_LEVEL: debug
    labels:
      traefik.http.middlewares.traefik-auth.forwardauth.address: http://oauth:4181
      traefik.http.middlewares.traefik-auth.forwardauth.authResponseHeaders: X-Forwarded-User
      traefik.http.middlewares.traefik-auth.forwardauth.trustForwardHeader: "true"
      traefik.http.routers.traefik-auth.middlewares: zitadel@file
      traefik.enable: "true"
      traefik.http.routers.traefik-auth.rule: Host(`auth.192.168.1.53`)
      traefik.http.routers.traefik-auth.tls: "true"
      traefik.http.routers.traefik-auth.tls.certresolver: letsencrypt
      traefik.http.services.traefik-auth.loadbalancer.server.port: 4181
      traefik.http.routers.traefik-auth.entrypoints: web-secure
    restart: always

  zitadel:
    restart: 'always'
    networks:
      - 'zitadel'
    image: 'ghcr.io/zitadel/zitadel:stable'
    command: 'start-from-init --config /zitadel-config.yaml --config /zitadel-secrets.yaml --steps /zitadel-init-steps.yaml --masterkey "${ZITADEL_MASTERKEY}" --tlsMode disabled'
    depends_on:
      certs:
        condition: 'service_started'

    labels:
            traefik.http.middlewares.zitadel.redirectscheme.scheme: redirect-to-https
            traefik.http.routers.zitadel.middlewares: redirect-to-https
   volumes:
      - './zitadel-config.yaml:/zitadel-config.yaml:ro'
      - './zitadel-secrets.yaml:/zitadel-secrets.yaml:ro'
      - './zitadel-init-steps.yaml:/zitadel-init-steps.yaml:ro'
      - 'zitadel-certs:/crdb-certs:ro'

  certs:
    image: 'cockroachdb/cockroach:v22.2.2'
    entrypoint: [ '/bin/bash', '-c' ]
    command: [ 'cp /certs/* /zitadel-certs/ && cockroach cert create-client --overwrite --certs-dir /zitadel-certs/ --ca-key /zitadel-certs/ca.key zitadel_user && chown 1000:1000 /zitadel-certs/*' ]
    volumes:
      - 'certs:/certs:ro'
      - 'zitadel-certs:/zitadel-certs:rw'
    depends_on:
      my-cockroach-db:
        condition: 'service_healthy'

  my-cockroach-db:
    restart: 'always'
    networks:
      - 'zitadel'
    image: 'cockroachdb/cockroach:v22.2.2'
    command: 'start-single-node --advertise-addr my-cockroach-db'
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"]
      interval: '10s'
      timeout: '30s'
      retries: 5
      start_period: '20s'
    ports:
      - '9090:8080'
      - '26257:26257'
    volumes:
      - 'certs:/cockroach/certs:rw'
      - 'data:/cockroach/cockroach-data:rw'

networks:
  zitadel:
  traefik_net:
    external: true



volumes:
  certs:
  zitadel-certs:
  data:

I also tried with the configuration in zitadel documentation but the error is still there

Thanks for the configuration,
could you set the log level of Traefik to debug and share the whole logs please?

INFO[0000] Configuration loaded from file: /etc/traefik/traefik.yaml 
INFO[2023-05-15T14:06:06Z] Traefik version 2.8.7 built on 2022-09-23T14:34:26Z 
DEBU[2023-05-15T14:06:06Z] Static configuration loaded {"global":{"checkNewVersion":true},"serversTransport":{"maxIdleConnsPerHost":200},"entryPoints":{"authenticated":{"address":":86","transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s"}},"forwardedHeaders":{},"http":{},"http2":{"maxConcurrentStreams":250},"udp":{"timeout":"3s"}},"traefik":{"address":":8080","transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s"}},"forwardedHeaders":{},"http":{},"http2":{"maxConcurrentStreams":250},"udp":{"timeout":"3s"}},"web":{"address":":85","transport":{"lifeCycle":{"graceTimeOut":"10s"},"respondingTimeouts":{"idleTimeout":"3m0s"}},"forwardedHeaders":{},"http":{},"http2":{"maxConcurrentStreams":250},"udp":{"timeout":"3s"}}},"providers":{"providersThrottleDuration":"2s","docker":{"watch":true,"endpoint":"unix:///var/run/docker.sock","defaultRule":"Host(`{{ normalize .Name }}`)","network":"traefik_net","swarmModeRefreshSeconds":"15s"},"file":{"watch":true,"filename":"/etc/traefik/traefik.yaml"}},"api":{"insecure":true,"dashboard":true},"log":{"level":"DEBUG","format":"common"},"pilot":{"dashboard":true}} 
INFO[2023-05-15T14:06:06Z] 
Stats collection is disabled.
Help us improve Traefik by turning this feature on :)
More details on: https://doc.traefik.io/traefik/contributing/data-collection/ 
2023/05/15 14:06:06 traefik.go:80: command traefik error: error while building entryPoint authenticated: error preparing server: error opening listener: listen tcp :86: bind: address already in use

You have to change the port (by the way, ports 85 and 86 are generally reserved)
It would be easier to have traefik in the docker-compose to have more flexibility and avoid network issues.

I advise you to build step by step a single docker-compose that contains your application, traefik, and zitadel. You can start by adding your application in your docker-compose and see that everything works, then add traefik in the docker-compose and expose your service without middleware.
Once Traefik exposes your application well, add zitadel in the docker-compose.
Once all these steps are done, you can take out bricks from your docker again if you have the need.

but actually I have created my traefik locally and I run it with systemctl so is there any solution to make the traefik up and run in that way and other app in docker compose?

You want to run Traefik and your app with compose? See this simple Traefik example.

thank you @bluepuma77 but the problem is that I run my traefik locally on my server and then I want to use docker compose for my app and zitadel to protect it.

You can perfectly use traefik in the docker-compose and expose only the ports you need to the outside.

Why do you try to use an extra traefik-forward-auth service when zitadel provides docs for using it as Traefik middleware?

@jbd thank you for response, the problem is middleware dose not exist and the ports are correct.

@bluepuma77 thanks . so you mean I cant use both zitadel and forwardauth?

I need to receive something like that

Now you have mixed it all:

  1. Traefik ForwardAuth
  2. Traefik Auth Middleware
  3. HTTP Basic Auth

All can ask for a username/password, but they are different mechanisms and different approaches where user/pass are stored.

There is a recent post about Traefik and Zitadel, maybe check that: link.

I highly discourage their practice to place static and dynamic config in the same traefik.yml file, doesn’t seem secure and future proof to me.

In the example they let Traefik generate a proprietary TLS cert, so you will get a TLS error in your browser about an untrusted “Traefik cert”.

Instead you probably want to use a certificatesresolvers for a LetsEncrypt cert (declare in static config) or load a custom (paid for) cert (in dynamic config).

Thank you @bluepuma77 for your complete explanation. do you have the documentation of traefik auth middleware and traefik forwardauth?

@bluepuma77 zitadel is using middleware itself so can I use "traefik Auth Middleware" or "Traefik ForwardAuth" with zitadel ?

my updated traefik.yaml:

log:
  level: DEBUG

api:
  insecure: true
  dashboard: true




entrypoints:
  authenticated:
    address: ":86"
  web:
    address: ":80"
providers:
  file:
    filename: /etc/traefik/traefik.yaml
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false
    network: traefik


http:
  middlewares:
    zitadel:
      forwardAuth:
        address: "http://traefik-auth:4181"
        trustForwardHeader: true
        authResponseHeaders:
          - "X-Forwarded-User"
      headers:
        isDevelopment: false
        allowedHosts:
        - '192.168.1.53'
        customRequestHeaders:
          :authority: '192.168.1.53'
  routers:

    router0:
      entryPoints:
      - web
      rule: 'HostRegexp(`192.168.1.53`, `{subdomain:[a-z]+}.192.168.1.53`)'
      service: zitadel




  services:

    zitadel:
      loadBalancer:
        servers:
        - url: h2c://192.168.1.53:8080
        passHostHeader: true

and updated docker compose :

version: '3.8'
services:
  traefik:
    networks:
      - 'zitadel'
    image: 'traefik:v2.10.1'
    container_name: 'traefik'
    restart: 'unless-stopped'
    ports:
      - '80:80'
    volumes:
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
      - './traefik.yaml:/etc/traefik/traefik.yaml'
  zitadel:
    restart: 'always'
    networks:
      - 'zitadel'
    image: 'ghcr.io/zitadel/zitadel:stable'
    command: 'start-from-init --config /zitadel-config.yaml --config /zitadel-secrets.yaml --steps /zitadel-init-steps.yaml --masterkey "${ZITADEL_MASTERKEY}" --tlsMode disabled'
    depends_on:
      certs:
        condition: 'service_started'

    labels:
       - "traefik.http.middlewares.zitadel.redirectscheme.scheme=redirect-to-https"
       - "traefik.http.routers.zitadel.middlewares=redirect-to-https"
    volumes:
      - './zitadel-config.yaml:/zitadel-config.yaml:ro'
      - './zitadel-secrets.yaml:/zitadel-secrets.yaml:ro'
      - './zitadel-init-steps.yaml:/zitadel-init-steps.yaml:ro'
      - 'zitadel-certs:/crdb-certs:ro'

  certs:
    image: 'cockroachdb/cockroach:v22.2.2'
    entrypoint: [ '/bin/bash', '-c' ]
    command: [ 'cp /certs/* /zitadel-certs/ && cockroach cert create-client --overwrite --certs-dir /zitadel-certs/ --ca-key /zitadel-certs/ca.key zitadel_user && chown 1000:1000 /zitadel-certs/*' ]
    volumes:
      - 'certs:/certs:ro'
      - 'zitadel-certs:/zitadel-certs:rw'
    depends_on:
      my-cockroach-db:
        condition: 'service_healthy'

  my-cockroach-db:
    restart: 'always'
    networks:
      - 'zitadel'
    image: 'cockroachdb/cockroach:v22.2.2'
    command: 'start-single-node --advertise-addr my-cockroach-db'
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health?ready=1"]
      interval: '10s'
      timeout: '30s'
      retries: 5
      start_period: '20s'
    ports:
        - '9090:8080'
      - '26257:26257'
    volumes:
      - 'certs:/cockroach/certs:rw'
      - 'data:/cockroach/cockroach-data:rw'
  test-auth1:
    container_name: test-auth1
    image: thomseddon/traefik-forward-auth
    environment:
      SECRET: /zitadel-secrets.yaml
    labels:
      - "traefik.http.middlewares.test-auth1.forwardauth.address=http://oauth:4181"
      - "traefik.http.middlewares.test-auth1.forwardauth.authResponseHeaders=X-Forwarded-User"
      - "traefik.http.middlewares.test-auth1.forwardauth.trustForwardHeader=true"
      - "traefik.http.routers.test-auth1.middlewares=test-auth1"
      - "traefik.enable=true"
      - "traefik.http.routers.test-auth1.rule=Host(`auth.192.168.1.53`)"
      - "traefik.http.routers.test-auth1.tls=true"
      - "traefik.http.routers.test-auth1.tls.certresolver=letsencrypt"
      - "traefik.http.services.test-auth1.loadbalancer.server.port=4181"
  whoami1:
    # A container that exposes an API to show its IP address
    image: containous/whoami
    restart: unless-stopped

    logging:
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - traefik

    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.port=85"

      # Define the URL to access this app
      - "traefik.http.routers.whoami1.rule=Host(`whoami1.${DOMAINNAME}`)"

      # Access via HTTPS only

      # Forward authentication to zitadel for logon
      - "traefik.http.routers.whoami1.middlewares=zitadel@file"

      # The application (i.e. this container)
      - "traefik.http.routers.whoami1.service=whoami1"
      - "traefik.http.services.whoami1.loadbalancer.server.port=85"

      # TLS is used to protect the domain
      - "traefik.http.routers.whoami1.tls=true"
      - "traefik.http.routers.whoami1.tls.certresolver=leresolver"
      - "traefik.http.routers.whoami1.tls.domains[0].main=${DOMAINNAME}"
      - "traefik.http.routers.whoami1.tls.domains[0].sans=*.${DOMAINNAME}"
networks:
  zitadel:
  traefik:
    external: true
    name: traefik


volumes:
  certs:
  zitadel-certs:
  data: