Traefik/Portainer - ERR_TOO_MANY_REDIRECTS - traefik

I'm trying to setup Traefik and Portainer but seem to be hitting some issues. I think mainly around Traefik and setting up new containers.
Everything looks correct to me but I seem to be getting an error when I point to my subdomain
ERR_TOO_MANY_REDIRECTS
If I point to the IP address and Port, the Portainer dashboard is displayed, it just seems to be that when pointing to my sub-domain, there is some recursive redirection I'm assuming.
My docker compose looks like this:-
version: '3'
services:
portainer:
image: portainer/portainer:latest
container_name: portainer-new
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data:/data
ports:
- 8000:8000
- 9000:9000
labels:
- "traefik.enable=true"
- "traefik.http.routers.portainer.entrypoints=http"
- "traefik.http.routers.portainer.rule=Host(`MY_URL`)"
- "traefik.http.middlewares.portainer-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.portainer.middlewares=portainer-https-redirect"
- "traefik.http.routers.portainer-secure.entrypoints=https"
- "traefik.http.routers.portainer-secure.rule=Host(`MY_URL`)"
- "traefik.http.routers.portainer-secure.tls=true"
- "traefik.http.routers.portainer-secure.tls.certresolver=http"
- "traefik.http.routers.portainer-secure.service=portainer"
- "traefik.http.services.portainer.loadbalancer.server.port=9000"
- "traefik.docker.network=proxy"
networks:
proxy:
external: true
Any ideas?

Okay, so I figured out my issue.
The above is correct and valid. I use CloudFlare for proxy/DNS etc... I had added my subdomain to my DNS settings, but my Proxy Status was Proxied rather than DNS ONLY. After setting DNS only the above worked.

Related

Traefik cannot access Dashboard

I have a problem with Traefik. All my services are OK, Traefik does his job, retrieves the certificates of Lets Encrypt, makes Load blancing between my different applications.
My problem is that I can't access the Dashboard, it asks me a login/password, yet I informed it in the docker-compose.
version: "3.7"
services:
traefik:
image: traefik:chevrotin
command:
--entrypoints.http.address=:80
--entrypoints.https.address=:443
--providers.docker=true
--api=true
--certificatesresolvers.letsencrypt.acme.httpchallenge=true
--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http
--certificatesresolvers.letsencrypt.acme.email=mymail#mail.com
--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json
labels:
- traefik.enable=true
# Redirect all HTTP traffic to HTTPS
- traefik.http.routers.to-https.rule=Host(`traefik.mydomain.com`)
- traefik.http.routers.to-https.entrypoints=http
- traefik.http.routers.to-https.middlewares=to-https
- traefik.http.routers.traefik.rule=Host(`traefik.mydomain.com`)
- traefik.http.routers.traefik.entrypoints=http
- traefik.http.routers.traefik.middlewares=auth
- traefik.http.routers.traefik.service=api#internal
- traefik.http.routers.traefik.tls=true
- traefik.http.routers.traefik.tls.certresolver=letsencrypt
- traefik.http.middlewares.to-https.redirectscheme.scheme=https
- traefik.http.middlewares.auth.basicauth.users=MyLogin:MyPassword
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /docker/letsencrypt:/letsencrypt
if you have a idea. Thanks
I find. I'm not encoded my password.
I use this website : https://www.web2generators.com/apache-tools/htpasswd-generator
to encoded my password.
"traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj
Note: all dollar signs in the hash need to be doubled for escaping

Traefik Reverse Proxy to external Server

I would like to access a Keycloak server that is on the internet and not on my docker network. I want to hide the domain of the Keycloak server behind my own domain. So if I go to http://localhost/auth/ then the page from the Keycloak server should be displayed. I don't want to have a redirect to the actual Keycloak server.
I have tried the following configuration but it does not work. When I go to http://localhost/auth I get a "404 page not found". I hope you can help me. Thank you very much for your help :)
docker-compose.yml
version: "3.7"
services:
proxy:
image: traefik:v2.2
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.file=true"
- "--providers.file.filename=/etc/traefik/rules.yml"
- "--entrypoints.web.address=:80"
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./rules.yml:/etc/traefik/rules.yml
website:
image: containous/whoami
labels:
- "traefik.enable=true"
- "traefik.http.routers.website.rule=Host(`localhost`)"
- "traefik.http.routers.website.entrypoints=web"
rules.yml
http:
routers:
my-route:
rule: "Host(`localhost`) && PathPrefix(`/auth`)"
service: my-keycloak-server
services:
my-keycloak-server:
loadBalancer:
servers:
- url: "https://keycloak.domain.com/auth"
Change:
- ./rules.yml:/etc/traefik/rules.yml
to:
- /etc/traefik/rules.yml:/etc/traefik/rules.yml
That should do it!
P.S.
Thanks for the question; really enjoyed learning about Traefik and Keycloak!

Is there a way to let some traefik services manage their tls certificates themselves?

I'll try to configure traefik for something like that:
1) server.example.com --> traefik --> httpChallengeToLetsEncrypt
2) client --> traefik (passthrough tls) --> server.example.com( with let's encrypt )
N.B.: traefik receives its requests at example.com level
What is happening:
1) Works correctly only if traefik does not manage let's encrypt certificates itself (otherwise it does not transmit any request whose pathPrefix begins with ".well-known/acme-challenge" :-\ )
2) Does not work with a config for tcp router like this:
tcp:
routers:
example:
entryPoints:
- web-secure
rule: "HostSNI(`server.example.com`)"
service: example
tls:
passthrough: true
services:
example:
loadBalancer:
servers:
- url: "https://192.168.0.1:443/"
How would you let one or more services manage their let's encrypt certificates themselves ?
And is it possible to do it at the same time that traefik also manages let's encrypt certificates or the problem mentioned in point 1 is it redibitory?
Best regards,
jmc
use tls.passthrough=true and a tcp router instead of http
below is a fully working example where apache is responsible for its own certificates.
traefik never touches them
version: "3"
services:
traefik:
image: traefik
command:
- --api.insecure=true
- --providers.docker=true
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
labels:
- traefik.http.routers.api.rule=Host(`traefik.docker.local`)
- traefik.http.routers.api.service=api#internal
whoami:
image: containous/whoami
labels:
- traefik.http.routers.whoami.rule=Host(`whoami.docker.local`)
- traefik.http.routers.whoami.service=whoami#docker
- traefik.http.services.whoami.loadbalancer.server.port=80
apache:
build: php-apache
depends_on: [traefik]
env_file: ./php-apache/env
volumes:
- "./php-apache/cert/haproxy/:/etc/ssl/haproxy/"
- "./php-apache/cert/private/:/etc/ssl/private/"
- "./php-apache/cert/trusted/:/usr/local/share/ca-certificates/"
- "./php-apache/conf/:/etc/apache2/conf-enabled/"
- "./php-apache/log/:/var/log/apache2/"
- "./php-apache/sites/available/:/etc/apache2/sites-available/"
- "./php-apache/sites/enabled/:/etc/apache2/sites-enabled/"
- "./php-apache/www/:/var/www/"
labels:
- "traefik.http.routers.apache.entrypoints=http"
- "traefik.http.routers.apache.priority=1"
- "traefik.http.routers.apache.rule=HostRegexp(`{catchall:.*}`)"
- "traefik.http.routers.apache.service=apache#docker"
- "traefik.http.services.apache.loadbalancer.server.port=80"
- "traefik.tcp.routers.apache.entrypoints=https"
- "traefik.tcp.routers.apache.rule=HostSNI(`*`)"
- "traefik.tcp.routers.apache.service=apache#docker"
- "traefik.tcp.routers.apache.tls.passthrough=true"
- "traefik.tcp.services.apache.loadbalancer.server.port=443"

Traefik and Harbor

I have changed the docker-compose.yml after the default Conf-Generation. My Proxy configuration looks like:
( I had only touched the proxy part )
proxy:
image: goharbor/nginx-photon:v1.9.4
container_name: nginx
restart: always
cap_drop:
- ALL
cap_add:
- CHOWN
- SETGID
- SETUID
- NET_BIND_SERVICE
volumes:
- ./common/config/nginx:/etc/nginx:z
networks:
- harbor
- web
dns_search: .
expose:
- 8080
ports:
- 8081:8080 #only to test if its online
labels:
- "traefik.enable=true"
- "traefik.backend=harbor-backend"
- "traefik.docker.network=web"
- "traefik.frontend.rule=Host:harbor.example.com"
- "traefik.frontend.entryPoints=https,http"
- "traefik.port=8080"
depends_on:
- registry
- core
- portal
- log
logging:
driver: "syslog"
options:
syslog-address: "tcp://127.0.0.1:1514"
tag: "proxy"
networks:
harbor:
external: false
web:
external: true
In my Harbor.yml i had leaved the http port to 80 and disabled https.
My Proxy configuration is the default one.
The Web UI works fine but when I try to login with the docker client i get this response:
root#h2791112:~# docker login registry.example.com
Username: admin
Password:
Error response from daemon: Get https://registry.example.com/v2/: unauthorized: authentication required
And that are the crendentials that work with the ui
did I miss a label ?
This worked for me: https://github.com/goharbor/harbor/issues/3114#issuecomment-432962664
Follow the steps

Redis connection refused when using traefik

I'm having a hard time trying to configure one redis container for all my applications using traefik. This is my configuration:
1 - Docker compose for Traefik and Redis:
version: '2'
services:
proxy:
container_name: traefik
image: traefik:1.3.6-alpine
command: --docker
ports:
- 80:80
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik.toml:/traefik.toml
networks:
- proxy
labels:
- traefik.frontend.rule=Host:monitor.company.dev
- traefik.port=8080
redis:
container_name: main_redis
image: redis:3.2
restart: always
volumes:
- ./data/redis:/data
networks:
- proxy
labels:
- traefik.backend=main-redis
- traefik.default.protocol=http
- traefik.frontend.rule=Host:main-redis.company.dev
- traefik.docker.network=proxy
- traefik.port=6379
networks:
proxy:
external: true
2 - Docker compose for my PHP Application.
version: '2'
services:
...
php:
container_name: myapp_php
build: ./docker/php # php:7.1-fpm base image
networks:
- internal
- proxy
labels:
- traefik.enable=false
- traefik.docker.network=proxy
expose:
- 9000
networks:
proxy:
external: true
internal:
external: false
I tried to connect my php application to main-redis.company.dev on both ports 6379 and 80 but I get a Redis::connect(): connect() failed: Connection refused message.
I also changed these stuff in my redis.conf:
Commented the line with bind 127.0.0.1
And changed protected-mode to no
My docker containers are staying in the same network, so I think it should work. Anyone knows why am I having this problem?
2022 UPDATE to #djeeg answer
For some time now you can use TCP mode for your routers. To do that you need to define the labels with TCP instead of HTTP
labels:
- "traefik.enable=true"
- "traefik.tcp.routers.redis.rule=HostSNI(`redis.example.com`)"
- "traefik.tcp.routers.redis.entrypoints=redis" //6379 entrypoint
- "traefik.tcp.routers.redis.tls.certresolver=myresolver" //let's encrypt resolver
- "traefik.tcp.routers.redis.service=redis"
- "traefik.tcp.services.redis.loadbalancer.server.port=6379"
once you got that working in order to connect assuming you are using TSL you will get error Error: Protocol error, got "H" as reply type byte.
To prevent this you need to do things.
Allow for tls connection in the connection string
Setup SNI for your DNS name or provide public certificate file via cert pr cacert
redis-cli -u redis://redis.example.com:6379 --tls --sni redis.example.com
First off, remove the traefik labels from your redis service definition, traefik is currently (Nov 2017) a HTTP proxy, so you can't expose the endpoint like that
See here:
https://github.com/containous/traefik/issues/10
https://github.com/containous/traefik/issues/1611
Then to connect the php service to the redis service, that looks like you are trying to do that within the same docker instance (rather than externally)
Instead of main-redis.company.dev:6379, it should be like on of these:
redis:6379
main_redis:6379
%PROJECT_NAME%_redis:6379
depending upon how you are deploying the container