Using ports endpoints for containers

Hi

I currently have Sonarqube, Postgres & Nginx running via a single docker-compose using nginx as a reverse proxy to provide TLS. So I've been looking and trying to configure replacing nginx with Traefik. Our current host sits on a subdomain, which the cert we have is solely for that domain. We host multiple container based systems on that host and just use different ports to dissociate between them. I've been unable to configure my traefik instance to run sonarqube and wondered if someone could help identify how to do it. This is my current docker-compose, I wasn't sure how to use a simple port based url like subdomain.domain.com:9000 which is how nginx runs this. So I tried using a path, but was unable to get this to work

version: '3'
services:
  sonarqube:
    container_name: sonarqube
    hostname: sonarqube
    image: 'sonarqube:community'
    networks:
        - traefik
        - sq_net
    labels:
      - traefik.http.routers.sq.tls=true
      - traefik.http.routers.sq.rule="Host(`subdomain.domain.com`) && Path(`/sonarqube`)"
      - traefik.http.services.sq.loadbalancer.server.port=9000
      - traefik.enable=true
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: test
      SONAR_JDBC_PASSWORD: test
    restart: unless-stopped
    volumes:
        - 'sonarqube_data:/opt/sonarqube/data'
        - 'sonarqube_extensions:/opt/sonarqube/extensions'
        - 'sonarqube_logs:/opt/sonarqube/logs'
  db:
    image: 'postgres:10'
    restart: unless-stopped
    depends_on:
        - sonarqube
    networks:
        - sq_net
    labels:
      - traefik.enable=false
    volumes:
        - 'sonar_psql:/var/lib/postgresql'
        - 'sonar_psql_data:/var/lib/postgresql/data'
    environment:
        - POSTGRES_DB=sonar
        - POSTGRES_USER=test
        - POSTGRES_PASSWORD=test

networks:
  traefik:
    external: true
  sq_net:
    external: false

volumes:
  sonar_psql:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonar_psql"
        o: bind

  sonar_psql_data:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonar_psql_data"
        o: bind

  sonarqube_data:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonarqube_data"
        o: bind

  sonarqube_extensions:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonarqube_extensions"
        o: bind

  sonarqube_logs:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonarqube_logs"
        o: bind

Hello @jonny7 and thanks for your interest in Traefik,

If I'm understanding well, you are trying to expose sonarqube through Traefik on port 9000. In order to do that, you will have to configure a Traefik entry point on port 9000 as explained in the following documentation and to enable the Docker provider.

Then, you will have to configure a router and a service for the sonarqube container. The container configuration would look like the following:

version: '3'
services:
  sonarqube:
    container_name: sonarqube
    hostname: sonarqube
    image: 'sonarqube:community'
    networks:
        - traefik
        - sq_net
    labels:
      - traefik.enable=true
      - traefik.docker.network=traefik # needed because there is multiple networks
      - traefik.http.routers.sq.tls=true
      - traefik.http.routers.sq.rule=Host(`subdomain.domain.com`)
      - traefik.http.routers.sq.entrypoints=sonarqube # attach this router to the entrypoint named sonarqube
      - traefik.http.services.sq.loadbalancer.server.port=9000 # this is the port exposed by the sonarqube container (might be optional)
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: test
      SONAR_JDBC_PASSWORD: test
    restart: unless-stopped
    volumes:
        - 'sonarqube_data:/opt/sonarqube/data'
        - 'sonarqube_extensions:/opt/sonarqube/extensions'
        - 'sonarqube_logs:/opt/sonarqube/logs'
....

To be able to help you, it will be better if you can share your static configuration, logs, the Traefik container configuration and also what are the errors.

Hope this helps!

1 Like

Sure - thanks @kevinpollet

So that change didn't work for me. Here are my configs


[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

[api]
  dashboard = true

[providers.docker]
  watch = true
  network = "traefik"

[providers.file]
  filename = "traefik_dynamic.toml"
  watch = true
[http.middlewares.simpleAuth.basicAuth]
  users = [
    "admin:$somehash"
  ]

[http.routers.api]
  rule = "Host(`subdoamin.domain.com`)"
  entrypoints = ["websecure"]
  middlewares = ["simpleAuth"]
  service = "api@internal"
  [http.routers.api.tls]


[tls.stores]
  [tls.stores.default]
    [tls.stores.default.defaultCertificate]
      certFile = "/domain.cert"
      keyFile = "/domain.key"

I actually can't see logs for this attempt of subdomain.domain.com:9000. I do see

time="2021-01-21T16:00:40Z" level=error msg="entryPoint \"sonarqube\" doesn't exist" entryPointName=sonarqube routerName=sq@docker
time="2021-01-21T16:00:40Z" level=error msg="no valid entryPoint for this router" routerName=sq@docker

Where I tried subdir paths instead.

Maybe I'm not understanding well your issue.

To be sure, you want to expose the sonarqube through Traefik on port 9000?
This means that your service will be accessible on subdomain.domain.com:9000.

If that's the case you have to configure an entrypoint for that and that's what the error logs says:

time="2021-01-21T16:00:40Z" level=error msg="entryPoint \"sonarqube\" doesn't exist" entryPointName=sonarqube routerName=sq@docker
time="2021-01-21T16:00:40Z" level=error msg="no valid entryPoint for this router" routerName=sq@docker

To fix that you will have to add the configuration for this entrypoint, something like:

[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

  [entryPoints.sonarqube]
    address = ":9000"

Apologies for the late reply Kevin.

Yes you're right, but I still get "unable to connect" when I visit subdomain.domain.com:9000.

So my config looks like so in traefik

In my traefik.toml I specify port 9000

[entryPoints]
  [entryPoints.web]
    address = ":80"
    [entryPoints.web.http.redirections.entryPoint]
      to = "websecure"
      scheme = "https"

  [entryPoints.websecure]
    address = ":443"

  [entryPoints.sonarqube]
    address = ":9000"

[api]
  dashboard = true

[providers.docker]
  watch = true
  network = "traefik"

[providers.file]
  filename = "traefik_dynamic.toml"
  watch = true

The dynamic config

[http.middlewares.simpleAuth.basicAuth]
  users = [
    "admin:$somehash"
  ]

[http.routers.api]
  rule = "Host(`subdoamin.domain.com`)"
  entrypoints = ["websecure"]
  middlewares = ["simpleAuth"]
  service = "api@internal"
  [http.routers.api.tls]


[tls.stores]
  [tls.stores.default]
    [tls.stores.default.defaultCertificate]
      certFile = "/domain.cert"
      keyFile = "/domain.key"

And i'm launching this sonarqube instance in it's own docker-compose. which is updated to be:


version: '3'
services:
  sonarqube:
    container_name: sonarqube
    hostname: sonarqube
    image: 'sonarqube:community'
    labels:
      - traefik.enable=true
      - traefik.http.routers.sonarqube.tls=true
      - traefik.http.routers.sonarqube.entrypoints=sonarqube
      - traefik.docker.network=traefik
      - traefik.http.routers.sonarqube.rule=Host(`subdomain.domain.com`)
    networks:
        - traefik
        - sq_net
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonar
      SONAR_JDBC_USERNAME: user
      SONAR_JDBC_PASSWORD: password
    restart: unless-stopped
    volumes:
        - 'sonarqube_data:/opt/sonarqube/data'
        - 'sonarqube_extensions:/opt/sonarqube/extensions'
        - 'sonarqube_logs:/opt/sonarqube/logs'
  db:
    image: 'postgres:10'
    restart: unless-stopped
    depends_on:
        - sonarqube
    networks:
        - sq_net
    labels:
      - traefik.enable=false
    volumes:
        - 'sonar_psql:/var/lib/postgresql'
        - 'sonar_psql_data:/var/lib/postgresql/data'
    environment:
        - POSTGRES_DB=sonar
        - POSTGRES_USER=user
        - POSTGRES_PASSWORD=pass

networks:
  traefik:
    external: true
  sq_net:
    external: false

volumes:
  sonar_psql:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonar_psql"
        o: bind

  sonar_psql_data:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonar_psql_data"
        o: bind

  sonarqube_data:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonarqube_data"
        o: bind

  sonarqube_extensions:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonarqube_extensions"
        o: bind

  sonarqube_logs:
    driver: local
    driver_opts:
        type: none
        device: "$PWD/sonarqube_logs"
        o: bind

So I'm not sure what's wrong here as Traefik, doesn't seem to report errors

Is it normal that the Host rule in your screen capture has a typo?
I see Host(`subdoamin.domain.com`) instead of Host(`subdomain.domain.com`)

Without logs, it's a bit hard to help you.

Could you enable the debug logs as described here and paste them from the beginning after sending a request to https://subdomain.domain.com:9000?

What is the output of a curl request? (curl -v -k https://subdomain.domain.com:9000)

Hi Kevin

The typo was just a placeholder for our real domain. It's correct in production.

So I enabled the logs and this request doesn't get picked up at all. Curl returns connection refused.

Without logs or more insights, it's really hard to help you more. I'm not able to understand if the problem is that a client is not able to reach Traefik or if Traefik is not able to reach the sonarqube service.

As the curl request is falling, I'm suspecting that a client is not able to send a request to Traefik.

Are you sure that Traefik is reachable from a client?
Maybe you have missed exposing the port 9000 in the Traefik deployment?
Could you share the content of the docker-compose used to deploy Traefik?

1 Like

Thanks for your perseverance! I didn't even think to check I'd enabled the port for 9000 on traefik itself

1 Like

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.