Reverse Proxy with Traefik

I am attempting to setup sentry behind traefik but I am running into an issue. My traefik setup is configured like so:

version: "3.3"

services:

    traefik:

        image: traefik:v2.0

        restart: always

        container_name: traefik

        ports:

            - "80:80" # <== http

            - "8080:8080" # <== :8080 is where the dashboard runs on

        command:

            - --api.dashboard=true # <== Enabling the dashboard to view services, middlewares, routers, etc...

            - --api.debug=true # <== Enabling additional endpoints for debugging and profiling

            - --log.level=DEBUG # <== Setting the level of the logs from traefik

            - --providers.docker=true # <== Enabling docker as the provider for traefik

            - --providers.docker.exposedbydefault=false # <== Don't expose every container to traefik, only expose enabled ones

            - --providers.docker.network=web # <== Operate on the docker network named web

            - --entrypoints.web.address=:80 # <== Defining an entrypoint for port :80 named web

        volumes:

            - /var/run/docker.sock:/var/run/docker.sock # <== Volume for docker admin

        networks:

            - web

        labels:

            - "traefik.enable=true" # <== Enable traefik on itself to view dashboard and assign subdomain to view it

            - "traefik.http.routers.api.rule=Host(`monitor.example.com`)" # <== Setting the domain for the dashboard

            - "traefik.http.routers.api.service=api@internal" # <== Enabling the api to be a service to access

networks:

    web:

        external: true

I tested this with wordpress first here is that config:

version: "3.3"

services:

    wordpress: # <== we aren't going to open :80 here because traefik is going to serve this on entrypoint 'web'

        image: wordpress

        restart: always

        container_name: wp

        environment:

            WORDPRESS_DB_HOST: db

            WORDPRESS_DB_USER: exampleuser

            WORDPRESS_DB_PASSWORD: examplepass

            WORDPRESS_DB_NAME: exampledb

        volumes:

            - wordpress:/var/www/html

        networks:

            - web

            - backend

        labels:

            - "traefik.enable=true" # <== Enable traefik to proxy this container

            - "traefik.http.routers.nginx-web.rule=Host(`wordpress.example.com`)" # <== Your Domain Name goes here for the http rule

            - "traefik.http.routers.nginx-web.entrypoints=web" # <== Defining the entrypoint for http, **ref: line 30

    db:

        image: mysql:5.7

        restart: always

        environment:

            MYSQL_DATABASE: exampledb

            MYSQL_USER: exampleuser

            MYSQL_PASSWORD: examplepass

            MYSQL_RANDOM_ROOT_PASSWORD: '1'

        volumes:

            - db:/var/lib/mysql

        networks:

            - backend

    

networks:

    web:

        external: true

    backend:

        external: false

  

volumes:

    wordpress:

        external: true

    db:

        external: true

and that works fine. I can visit the endpoint I configured and wordpress is served.

So I modified the docker-compose.yml file for sentry (after running ./install.sh) and commented out the ports for the nginx container and added the following

networks:
      - web
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx-web.rule=Host(`sentry.example.com`)"
      - "traefik.http.routers.nginx-web.entrypoints=web"

and added this to the bottom of the file

networks:
  web:
    external: true

My issue is after running docker-compose up -d everything starts fine but after maybe a minute or so the nginx containers drops from the traefik dashboard. When I run docker-compose ps I see that the nginx container is restarting. It does not leave this state. Am I configuring something wrong here or am I missing something.

Here are the results of docker-compose logs nginx

nginx_1                        | 2020/08/24 23:43:17 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:18 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:19 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:20 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:21 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:23 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:27 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:34 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:43:47 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:44:14 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | 2020/08/24 23:45:05 [emerg] 1#1: host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55
nginx_1                        | nginx: [emerg] host not found in upstream "relay:3000" in /etc/nginx/nginx.conf:55

After you assigned the “web” network to nginx it isn’t in the default network anymore. Therefor no connection to the other containers is possible. Possible solution: mark “web” as default network or assign both networks to nginx like it is done in the wordpress example.

Furthermore you can skip the nginx container if you also add the label

"traefik.http.routers.relay.rule=Host(`sentry.example.com`) && PathPrefix(`/api/store/`, `/api/{id:[1-9]\\d*/}`)"

to the relay container. In addition add the labels you added to nginx to the web container.

I had realized that I need to add the default network to the nginx container. So I did and now that container stays up but I’m still having issues with accessing the container with traefik. when I visit sentry.example.com I get a 404.

I took your advice and commented out the nginx container added that label to the relay container and added the labels from the nginx container to the web container. The Web container does show up in traefik

Here is the containers I made changes to

web:
    << : *sentry_defaults
    networks:
      - web
      - default
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx-web.rule=Host(`sentry.example.com`)"
      - "traefik.http.routers.nginx-web.entrypoints=web"

#nginx:
  #  << : *restart_policy
  #  ports:
  #    - '9000:80/tcp'
  #  expose:
  #     - '80'
  #  networks:
  #    - web
  #    - default
  #  labels:
  #    - "traefik.enable=true"
  #    - "traefik.http.routers.nginx-web.rule=Host(`sentry.example.com`)"
  #    - "traefik.http.routers.nginx-web.entrypoints=web"
  #  image: 'nginx:1.16'
  #  volumes:
  #    - type: bind
  #      read_only: true
  #      source: ./nginx
  #      target: /etc/nginx
  #  depends_on:
  #    - web
  #    - relay

relay:
    << : *restart_policy
    image: '$RELAY_IMAGE'
    labels:
      - "traefik.http.routers.relay.rule=Host(`sentry.example.com`) && PathPrefix(`/api/store/`, `/api/{id:[1-9]\\d*/}`)"
    volumes:
      - type: bind
        read_only: true
        source: ./relay
        target: /work/.relay
    depends_on:
      - kafka
      - redis

With this configuration the web container now is a constant state of restarting.

Here is the log from docker-compose logs web

web_1                          | 16:32:12 [WARNING] sentry.utils.geo: settings.GEOIP_PATH_MMDB not configured.
web_1                          | /usr/local/lib/python2.7/site-packages/cryptography/__init__.py:39: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
web_1                          |   CryptographyDeprecationWarning,
web_1                          | 16:32:15 [INFO] sentry.plugins.github: apps-not-configured
web_1                          | *** Starting uWSGI 2.0.19.1 (64bit) on [Tue Aug 25 16:32:15 2020] ***
web_1                          | compiled with version: 8.3.0 on 24 August 2020 10:07:29
web_1                          | os: Linux-3.10.0-1127.18.2.el7.x86_64 #1 SMP Sun Jul 26 15:27:06 UTC 2020
web_1                          | nodename: 455fbacf1c0c
web_1                          | machine: x86_64
web_1                          | clock source: unix
web_1                          | detected number of CPU cores: 8
web_1                          | current working directory: /
web_1                          | detected binary path: /usr/local/bin/uwsgi
web_1                          | !!! no internal routing support, rebuild with pcre support !!!
web_1                          | your memory page size is 4096 bytes
web_1                          | detected max file descriptor number: 1048576
web_1                          | lock engine: pthread robust mutexes
web_1                          | thunder lock: enabled
web_1                          | bind(): Permission denied [core/socket.c line 769]

This means it cannot bind on the socket due to permission issues. Are you trying to use port 80, which is protected?

The output of docker-compose ps showed port 9000 before I made the changes I noted above. I am not specify any ports

web:
    << : *sentry_defaults
    networks:
      - web
      - default
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.nginx-web.rule=Host(`sentry.example.com`)"
      - "traefik.http.routers.nginx-web.entrypoints=web"

Could the default network or traefik be using port 9000?

I fixed the problem.

I deleted my sentry directory and pulled a fresh copy down from github. I changed nothing and ran ./install.sh

Next I edited the docker-compose.yml. This is where my issue was I was running the wordpress container as well so when I copied the labels from that container into the sentry nginx container I did not change the name of the router which is what was causing the issue. I did not need to do anything with the port except to not bind port 80 to 9000

this is what I had before

expose:
  - "80"
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.nginx-web.rule=Host(`sentry.example.com`)"
  - "traefik.http.routers.nginx-web.entrypoints=web"

and this is what I have now

# ports:
#   - "9000:80"
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.sentry-web.rule=Host(`sentry.example.com`)"
  - "traefil.http.routers.sentry-web.entrypoints=web"

and that was it I can now visit sentry.example.com and proxies me to my sentry instance

I will write a short write up on this on my blog and post its link here for anyone else looking to do this and not being sure what they need to do.

1 Like