Exclude domains from Traefik Let's Encrypt - docker

I am using Traefik as Reverse Proxy in a Docker environment. Every dockerized application is getting it's Traefik configuration as labels, like:
version: '2'
services:
whoami:
image: emilevauge/whoami:latest
labels:
- "traefik.backend=whoami"
- "traefik.frontend.rule=Host:internal.domain.com,external.domain.com;PathPrefixStrip:/whoami"
networks:
- traefik
ports:
- "80"
restart: always
networks:
traefik:
external:
name: traefik
Applications are accessible via an internal domain (intranet) and an external domain.
Now I am getting Error creating new order :: too many failed authorizations recently: see https://letsencrypt.org/docs/rate-limits/, url: " from Let's Encrypt, because Traefik tries to get a certificate for a domain which is not accessible from external.
Is there any way to exclude domains from Traefik's Let's Encrypt support?

The docker-compose label traefik.enable=false should disable it:
labels:
- traefik.enable=false

Related

Mailcow Reverse Proxy using Traefik not routing to the correct Nginx Service

I am trying to follow the community documentation on mailcow dockerized and I am using Traefik as my load balancer.
I have successfully obtained a SSL certificate and the certdump is working as expected when I check the logs.
The issue I have having is that the nginx-mailcow container is not receiving the requests when I visit mail.example.com. My Traefik logs show this:
level=error msg="entryPoint \"secure\" doesn't exist" routerName=moo#docker entryPointName=secure
level=error msg="no valid entryPoint for this router" routerName=moo#docker
My docker-compose.override.yml looks like this (not much different to the community documentation):
version: '2.1'
services:
nginx-mailcow:
networks:
traefik:
web:
labels:
- traefik.enable=true
- traefik.http.routers.moo.rule=Host(`${MAILCOW_HOSTNAME}`)
- traefik.http.routers.moo.tls=true
- traefik.http.routers.moo.tls.certresolver=godaddy
- traefik.http.routers.moo.middlewares=redirect#file
- traefik.http.routers.moo.service=nginx-mailcow
- traefik.http.services.moo.loadBalancer.passHostHeader=true
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.headers.customrequestheaders.X-Forwarded-Proto=https
- traefik.http.routers.moo.middlewares=https-redirect
- traefik.http.services.moo.loadbalancer.server.port=80
- traefik.http.routers.moo.entrypoints=secure
- traefik.docker.network=web
certdumper:
image: humenius/traefik-certs-dumper
container_name: traefik_certdumper
network_mode: none
volumes:
- acme:/traefik:ro
- ./data/assets/ssl/:/output:rw
environment:
- DOMAIN=${MAILCOW_HOSTNAME}
networks:
traefik:
external: true
web:
external: true
volumes:
acme:
name: "traefik_acme"
Can anyone see what I am doing wrong?
I have also tried with only:
labels:
- traefik.enable=true
- traefik.http.routers.moo.rule=Host(`${MAILCOW_HOSTNAME}`)
- traefik.http.routers.moo.tls=true
- traefik.http.routers.moo.tls.certresolver=godaddy
- traefik.http.services.moo.loadbalancer.server.port=80
- traefik.http.routers.moo.entrypoints=secure
- traefik.docker.network=web
This still did not work.
When you define a name for a service, you must use the same name in your service configuration, like this:
traefik.http.routers.moo.service=nginx-mailcow
traefik.http.services.moonginx-mailcow.loadBalancer.passHostHeader=true
The loadBalancer.servers (notice the s in servers) doesn't have a port key, only url:
traefik.http.services.moo.loadbalancer.server.port=80
traefik.http.services.nginx-mailcow.loadbalancer.servers.url=['http://nginx-mailcow:80']
But as you are using defaults, you can omit all of the above =)
One more thing, I don't know how your Traefik container is configured but if your Traefik is running with a defined traefik network (internal) and a web network (public), you should use the traefik network in your Mailcow container as you want to route all external traffic through Traefik.
traefik.docker.network=web
labels:
- traefik.enable=true
- traefik.http.routers.moo.rule=Host(`${MAILCOW_HOSTNAME}`)
- traefik.http.routers.moo.tls=true
- traefik.http.routers.moo.tls.certresolver=godaddy
- traefik.http.routers.moo.middlewares=redirect#file
- traefik.http.middlewares.https-redirect.redirectscheme.scheme=https
- traefik.http.middlewares.https-redirect.headers.customrequestheaders.X-Forwarded-Proto=https
- traefik.http.routers.moo.middlewares=https-redirect
- traefik.http.routers.moo.entrypoints=secure
- traefik.docker.network=traefik
#30daysofstackoverflow

docker-compose configuration to reach container from different project/network via domain url

This is a hard one but it would be great to solve it and my configuration would awesome!
I have two docker-compose projects: no 1. contains configuration for traefik, no 2. contains my-service that has http://my-domain.tld as parameter.
The goal is to call (let's say ping) http://my-domain.tld from my-service and get through to traefik. Both services now are in the same network but I need somehow to pass configuration that http://my-domain.tld points to traefik.
# Project no 1. configuration for traefik that I want to access from no 2. project
version: '3.7'
services:
traefik:
container_name: traefik
networks:
- default
networks:
default:
name: traefik
# Project no 2.
version: '3.7'
services:
my-service:
environment:
- URL=http://my-domain.tld
networks:
- traefik
networks:
traefik:
external:
name: traefik
Tried solutions:
Variant a)
Does not work. When I call http://my-domain.tld it is directed to first node in traefik network (in my case it was my-service itself). Difference from original: aliases in network section.
# Project no 2.
version: '3.7'
services:
my-service:
environment:
- URL=http://my-domain.tld
networks:
traefik:
aliases:
- ${MERCURE_DOMAIN}
networks:
traefik:
external:
name: traefik
Variant b)
Fails because traefik that service depends on is not in the project/network: Service 'my-service' depends on service 'traefik' which is undefined. Differences from original: depends_on and extra_hosts.
# Project no 2.
version: '3.7'
services:
my-service:
environment:
- URL=http://my-domain.tld
networks:
- traefik
depends_on:
- traefik
extra_hosts:
- http://my-domain.tld:traefik
networks:
traefik:
external:
name: traefik
Variant c)
Works! However keep in mind that I had to hardcode IP address of traefik service. This is not the worst scenario but it makes project less portable and I want to avoid it. Differences from original: network configuration for no 1. project, static ip for traefik service and extra_hosts for no 2. project.
# Project no 1. configuration for traefik that I want to access from next project
version: '3.7'
services:
traefik:
container_name: traefik
networks:
default:
ipv4_address: 172.133.239.10
networks:
default:
name: traefik
driver: bridge
ipam:
driver: default
config:
- subnet: 172.133.239.0/24
# Project no 2.
version: '3.7'
services:
my-service:
environment:
- URL=http://my-domain.tld
networks:
- traefik
extra_hosts:
- http://my-domain.tld:172.133.239.10
networks:
traefik:
external:
name: traefik
Variant d)
Is waiting for your suggestion how to make this perfect!
EDIT: rewrote docker-compose configuration to separate cases to show what I have tried and accomplished because there were some confusion about it.
If you know the hostname (or container name) of my-service will be static you can just call it via it's hostname (or container name if no hostname was specified; it'll default to using it's container name as it's hostname).
i.e. if my-service has the hostname container1 you can ping it like this from inside your other container, (as long as they're in the same Docker network): ping container1

How to use zabbix-web-nginx-mysql with existing nginx container?

I am trying to use docker on my debian server. There are several sites using Django framework. Every project run in it's own container with gunicorn, single nginx container works as a reverse proxy, data stores in mariadb container. Everything works correctly. It is necessary to add zabbix monitoring system on server. So, I use zabbix-server-mysql image as a zabbix-backend and zabbix-web-nginx-mysql image as a frontend. Backend run successfully, frontend fails with errors such as: "can't binding to 0.0.0.0:80 port is already allocated", nginx refuse connection to domains. As I understand, zabbix-web-nginx-mysql create another nginx container and it causes problems. Is there a right way to use zabbix images with existing nginx container?
I have a nginx reverse proxy installed on the host, which I use for proxy redirect into container. I have a working configuration for docker zabbix with the following configuration (I have omitted the environment variables).
My port 80 for the web application is served through anoter which is same set on nginx proxy_pass. Here the configuration
version: '2'
services:
zabbix-server4:
container_name: zabbix-server4
image: zabbix/zabbix-server-mysql:alpine-4.0.5
user: root
networks:
zbx_net:
aliases:
- zabbix-server4
- zabbix-server4-mysql
ipv4_address: 172.16.238.5
zabbix-web4:
container_name: zabbix-web4
image: zabbix/zabbix-web-nginx-mysql:alpine-4.0.5
ports:
- 127.0.0.1:11011:80
links:
- zabbix-server4
networks:
zbx_net:
aliases:
- zabbix-web4
- zabbix-web4-nginx-alpine
- zabbix-web4-nginx-mysql
ipv4_address: 172.16.238.10
zabbix-agent4:
container_name: zabbix-agent4
image: zabbix/zabbix-agent:alpine-4.0.5
links:
- zabbix-server4
networks:
zbx_net:
aliases:
- zabbix-agent4
ipv4_address: 172.16.238.15
networks:
zbx_net:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
ipam:
driver: default
config:
- subnet: 172.16.238.0/24
gateway: 172.16.238.1

Traefik: Aggregate multiple docker services into a single logical backend

I'm running minio using its official docker-compose file which creates 4 services (containers): minio1,minio2,minio3,minio4. Traefik treats them as 4 unique services, but in reality, they should be treated as a single backend, that is, I want Traefik to generate 1 frontend an 1 backend (with 4 servers) for minio.
I tried putting them into a single group(servicefabric.groupname) but to no avail.
I have the following labels set for each minio service:
labels:
- "traefik.servicefabric.groupname=minio"
- "traefik.basic.frontend.rule=Host:foo.bar.com"
- "traefik.weight=10" # 10,20,30,40 incremented per service
- "traefik.frontend.rule=Host:traefik"
- "traefik.port=9000"
container_name: minio*
Is there any way to achieve this?
#Riverman
I had the same issue as you and I solved it by playing around as it's not fully documented in Traefik documentation. What you need to do is specify the traefik.backend value for all the services to be the same name and set traefik.frontend.backend to that traefik.backend value. You can't use the service piece for this. Below is an example.
services:
minio01:
image: minio/minio
hostname: minio01
restart: always
volumes:
- minio01-data:/export
networks:
- minio
- traefik
command: server http://minio01/export http://minio02/export
labels:
- 'traefik.enable=true'
- 'traefik.docker.network=traefik'
- 'traefik.frontend.rule=Host:minio.local'
- 'traefik.frontend.backend=minio'
- 'traefik.port=9000'
- 'traefik.protocol=http'
- 'traefik.backend=minio'
minio02:
image: minio/minio
hostname: minio02
restart: always
volumes:
- minio02-data:/export
networks:
- minio
- traefik
command: server http://minio01/export http://minio02/export
labels:
- 'traefik.enable=true'
- 'traefik.docker.network=traefik'
- 'traefik.frontend.rule=Host:minio.local'
- 'traefik.frontend.backend=minio'
- 'traefik.port=9000'
- 'traefik.protocol=http'
- 'traefik.backend=minio'
All minio services have to have the same frontend rule and the same backend name.
labels:
- "traefik.frontend.rule=Host:minio.${DOMAIN}"
- "traefik.backend=minio"
- "traefik.port=9000"
Also I think you misunderstood the meaning of "backend". A backend is a server to which Traefik route traffic based on the frontend rules. Same as "upstream"/"location" in nginx.
Edit
As stated in the comment, this configuration creates multiple frontends all pointing to the same backend, although functional this looks ugly. A quick solution is to just have one service with ‘frontend’ but if that service goes down, the frontend will be gone too.
A better way to do this is to set it in the config file, traefik.toml:
[frontends]
[frontends.frontend1]
backend = "minio"
[frontends.frontend1.minio]
rule = "Host: minio.${DOMAIN}”

Rancher, public subdomains and nginx

I was running a complete CI stack on some local servers that I try to migrate to Rancher.
First, I have created the following configuration on one node with
docker-compose that seems to runs perfectly (i.e., I can access to
each elements separately via external public subdomains).
jwilder/nginx-proxy
jrcs/letsencrypt-nginx-proxy-companion:latest
registry:2.6.2
rancher/server:latest
Now, I want to access to some elements from brand new rancher stacks via
their respective external public subdomains. For instance,
https://gitlab.example.com, https://jenkins.example.com. Unfortunately, it doesn't work.
Actually, when I upload the following docker-compose.yml file when creating a stack, it looks like not being able to make the connection with the existing stack, the one which supports rancher itself and basically, I cannot access to the services which are running fine:
version: '2'
services:
gitlab:
image: gitlab/gitlab-ce:latest
labels:
io.rancher.container.pull_image: always
ports:
- "27100:80"
- "27143:443"
- "27122:22"
restart: always
volumes:
- /var/gitlab_volume/config:/etc/gitlab
- /var/gitlab_volume/logs:/var/log/gitlab
- /var/gitlab_volume/data:/var/opt/gitlab
environment:
VIRTUAL_HOST: "gitlab.example.com"
VIRTUAL_PORT: 80
LETSENCRYPT_HOST: "gitlab.example.com"
LETSENCRYPT_EMAIL: "admin#example.com"
What is the appropriate approach?
For info, I have already checked Rancher external subdomains but at this stage, I want to use my nginx server as load balancer.
Here the final docker-compose.yml file definition:
version: '2'
services:
gitlab:
image: gitlab/gitlab-ce:latest
network_mode: bridge
labels:
io.rancher.container.pull_image: always
ports:
- "27100:80"
- "27143:443"
- "27122:22"
restart: always
volumes:
- /var/gitlab_volume/config:/etc/gitlab
- /var/gitlab_volume/logs:/var/log/gitlab
- /var/gitlab_volume/data:/var/opt/gitlab
environment:
VIRTUAL_HOST: "gitlab.example.com"
VIRTUAL_PORT: 80
LETSENCRYPT_HOST: "gitlab.example.com"
LETSENCRYPT_EMAIL: "admin#example.com"
We just need to force the network_mode on each container definition.

Resources