Traefik + Docker for Windows: Failed to create a client for docker, error: protocol not available & Provider connection error protocol not available - docker

I'm having troubles getting a basic Traefik routing setup to work.
My goal is to get basic routing with two helloworld apps (each different to tell apart), both on port 80, e.g.:
demo1.localhost -> helloworld1
demo2.localhost -> helloworld2
Each of the images works fine if I run them via docker run in isolation.
Using Powershell from my project dir, /app, when I run docker-compose up I get the following:
The Traefik service launches, I can visit the dashboard just fine but the routing table doesn't show my routes. demo1 and demo2 launch just fine, but obviously I can't connect to them because the routing isn't working.
Even though the services all launch successfully - I repeatedly get the following errors:
traefik | ... "Failed to create a client for docker, error: protocol not available" providerName=docker
traefik | ... "Provider connection error protocol not available, retrying ..." providerName=docker
I've included my docker-compose.yml file below, which is the only file in my dir, /app.
docker-compose.yml:
# app/docker-compose.yml
version: '3.8'
networks:
myweb:
driver: nat
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "8080:8080"
volumes:
- source: '\\.\pipe\docker_engine'
target: '\\.\pipe\docker_engine'
type: npipe
command:
- "--api.insecure=true"
- "--providers.docker"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
networks:
- myweb
labels:
- "traefik.http.routers.dashboard.rule=Host(`dash.localhost`)"
- "traefik.docker.network=app_myweb"
demo1:
image: helloworld:1
container_name: demo1
labels:
- "traefik.enable=true"
- "traefik.docker.network=app_myweb"
- "traefik.port=80"
- "traefik.http.routers.demo1.rule=Host(`demo1.localhost`)"
# Have tried this below, doesn't help.
# volumes:
# - source: '\\.\pipe\docker_engine'
# target: '\\.\pipe\docker_engine'
# type: npipe
networks:
- myweb
depends_on:
- proxy
demo2:
image: helloworld:2
container_name: demo2
labels:
- "traefik.enable=true"
- "traefik.docker.network=app_myweb"
- "traefik.port=80"
- "traefik.http.routers.demo2.rule=Host(`demo2.localhost`)"
networks:
- myweb
depends_on:
- proxy
I saw a suggestion somewhere that I should enable the setting "Expose daemon on tcp://localhost:2375 without TLS" in Docker Desktop settings, which I have done but doesn't help.
My setup is:
Docker Desktop (v19.03.12) for Windows
Docker using Windows Containers
Windows 10 (10.0.18363 Build 18363)
Question #1:
Anybody have any idea what might be causing the problem?
Question #2:
Notice in my file I also have a route set up for the dashboard, to route from dash.localhost to localhost:8080/dashboard, but even that doesn't work. Any idea how to get that working? Do I need to tell it to route from 80->8080 for the dashboard?

According to a ticket on their GitHub you seem to be:
Missing --providers.docker.endpoint=npipe:////./pipe/docker_engine in Traefik command line
Sharing \\.\pipe\docker_engine when Docker is expecting .\pipe\docker_engine
Try making those two changes and see if that helps Traefik connect to your Docker daemon. None of your routes will work until Traefik can talk to Docker to read the labels of your containers.

Related

Traefik with Docker-Compose not working as expected

I am fairly new to using traefik, so I might be totally missing something simple, but I have the following docker-compose.yaml:
version: '3.8'
services:
reverse-proxy:
container_name: reverse_proxy
restart: unless-stopped
image: traefik:v2.0
command:
- --entrypoints.web.address=:80
- --entrypoints.web-secure.address=:443
- --api.insecure=true
- --providers.file.directory=/conf/
- --providers.file.watch=true
- --providers.docker=true
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./scripts/certificates/conf/:/conf/
- ./scripts/certificates/ssl/:/certs/
networks:
- bnkrl.io
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`traefik.bnkrl.io`)"
- "traefik.docker.network=bnkrl.io"
bankroll:
container_name: bankroll
build:
context: .
ports:
- "3000"
volumes:
- .:/usr/src/app
command: yarn start
networks:
- bnkrl.io
labels:
- "traefik.http.routers.bankroll.rule=Host(`bankroll.bnkrl.io`)"
- "traefik.docker.network=bnkrl.io"
- "traefik.http.services.bankroll.loadbalancer.server.port=3000"
- "traefik.http.routers.bankroll-https.rule=Host(`bankroll.bnkrl.io`)"
- "traefik.http.routers.bankroll-https.tls=true"
networks:
bnkrl.io:
external: true
But for some reason the following is happening:
Running curl when ssh'd into my bankroll container gives the following:
/usr/src/app# curl bankroll.bnkrl.io
curl: (7) Failed to connect to bankroll.bnkrl.io port 80: Connection refused
Despite having - "traefik.http.services.bankroll.loadbalancer.server.port=3000" label set up.
I am also unable to hit traefik from my application container:
curl traefik.bnkrl.io
curl: (6) Could not resolve host: traefik.bnkrl.io
Despite my expectation to be able to do so since they are both on the same network.
Any help with understanding what I might be doing wrong would be greatly appreciated! My application (bankroll) is a very basic hello-world react app, but I don't think any of the details around that are relevant to the issue I'm facing.
EDIT: I am also not seeing any error logs on traefik side of things.
You are using host names that are not declared and therefore are unreachable.
To reach a container from another container, you need to use the service name, for example, if you connect to bankroll from the reverse-proxy it will hit the other service.
While if you want to access them from the host machine, you will have to publish the ports (which you did, it's all the stuff in ports in your Docker-compose file) and access from localhost or from your machine local IP address instead of traefik.bnkrl.io.
If you want to access from traefik.bnkrl.io, you will have to declare this host name, and point it to the place where the Docker containers are running from.
So either a DNS record in the domain bnkrl.io pointing to your local machine, or a HOSTS file entry in your computer pointing to 127.0.0.1.
Another note: For SSL you are going to need a valid certificate to use for the host name. While in local development, you can use the self-signed certificate provided by Traefik, but you may have to install it in the computer connecting to the service, or allow untrusted certificates from your browser, or wherever you are making the requests from (some browsers no longer support using self-signed certificates). For SSL on the Internet you will need to look at things like Let's Encrypt.

Traefik route 404

I am trying to host a few different websites on a single Raspberry Pi using Docker. I was told that I would need to use something like Traefik to route everything properly.
I tried using the Docker Basic Example under User Guides in their documentation as a test. I followed along with the example and created the docker-compose.yml file and copied in the example from the docs:
version: "3.3"
services:
traefik:
image: "traefik:v2.2"
container_name: "traefik"
command:
# - "--log.level=DEBUG"
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
whoami:
image: "containous/whoami"
container_name: "simple-service"
labels:
- "traefik.enable=true"
- "traefik.http.routers.whoami.rule=Host(`whoami.localhost`)"
- "traefik.http.routers.whoami.entrypoints=web"
Using this example going to the devices local IP I recieve a page that simply says:
404 Page not found
I've tried changing the Traefik container image version, and editing the example with my relevant information as well as recreating the example on another host and still I receive the above 404.
Am I doing something incorrect with Traefik to receive this 404?
In the user guide you have mentioned, there is this note:
Replace whoami.localhost by your own domain within the traefik.http.routers.whoami.rule label of the whoami service.
So, after you replace whoami.localhost with you local IP, you should be able to see whoami service responding correctly.

Traefik 2.0 and docker simple configuration doesnt work

I'm following some tutorial link_to_tutorial about traefik 2.0 and docker, and I have docker-compose file which starts up two containers: traefik and my-app. The problem is when containers up and running, I am not able to browse to localhost:8082, as suggested by configuration, I always get "unable to connect" in browser.
docker-compose.yml :
version: "3.3"
services:
traefik:
image: "traefik:v2.0.1"
command:
- --entrypoints.web.address=:80
- --providers.docker
- --api.insecure
ports:
- "80:80"
- "8080:8080"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock:ro"
my-app:
image: containous/whoami:v1.3.0
command:
# It tells whoami to start listening on 8082 instead of 80
- --port=8082
labels:
- "traefik.http.routers.my-app.rule=Host(`whoami.docker.localhost`)"
- "traefik.http.services.my-app.loadbalancer.server.port=8082"
However I am able to get localhost:8080 and traefik UI works well. As I understand all requests to "traefik" container normally should be redirected to "my-app":8082 container but it somehow fails. Help heeded.Thanks.
"traefik.http.routers.my-app.rule=Host(localhost,127.0.0.1)"

Traefik container fails with file rules

I am trying to run a simple Traefik container with a yml configuration to make some tests, but I cannot start it.
docker-compose.yml
version: '3.7'
services:
proxy:
image: traefik:v2.0.1
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ${PWD}/traefik.yml:/etc/traefik/traefik.yml
command:
- --providers.docker=true
- --providers.file.filename=/etc/traefik/traefik.yml
- --entryPoints.web.address=:7000
# - --providers.docker.swarmMode=true
- --log.level=DEBUG
ports:
- "9999:8080"
- "7000:80"
traefik.yml
http:
routers:
to-reg:
entryPoints:
- web
rule: Path(`/reg`)
service: srv-reg
services:
srv-reg:
loadBalancer:
servers:
- url: http://192.168.226.141:9900
When I run docker-compose up, I get:
proxy_1 | 2019/10/02 11:29:33 command traefik error: invalid node traefik: no child
I am pretty sure I am doing a silly error, but I cannot understand which from the log.
I finally found my error (and as expected is a silly one): I had not understood the distinction between static and dynamic configuration and I was mounting the dynamic one where traefik expects the static. This cause that strange error.
Once I renamed traefik.yml in dyn-traefik.yml I have been able to mount in /etc/traefik and start the proxy with expected routing configuration.

Docker-compose doesn't resolve DNS to correct service

I have two services, web and helloworld. The following is my docker-compose YAML file:
version: "3"
services:
helloworld:
build: ./hello
volumes:
- ./hello:/usr/src/app
ports:
- 5001:80
web:
build: ./web
volumes:
- ./web:/usr/share/nginx/html
ports:
- 5000:80
depends_on:
- helloworld
Inside the index.html in web, I made a button that opens http://helloworld when clicked on. However, my button ends up going to helloworld.com instead of the correct service. Both services work fine when I do localhost:5001 and localhost:5000. Am I missing something?
Docker's embedded DNS for service discovery is for container-to-container networking. For connections from outside of docker (e.g. from your browser) you need to publish the port (e.g. 5000 and 5001 in your file) and connect to that published port.
To use the container-to-container networking, you would need the DNS lookup to happen inside of the web container and the connection to go from web to helloworld, instead of from your browser to the container.
Edit: from your comment, you may find a reverse proxy helpful. Traefik and nginx-proxy are two examples out there. You can configure these to forward to containers by hostname or by a virtual path, and in your situation, I think path based routing would be easier. The resulting compose file would look something like:
version: "3"
services:
traefik:
image: traefik
command: --docker --docker.watch
volumes:
- /var/lib/docker.sock:/var/lib/docker.sock
ports:
- 8080:80
helloworld:
build: ./hello
volumes:
- ./hello:/usr/src/app
labels:
- traefik.frontend.rule=PathPrefixStrip:/helloworld
- traefik.port=80
web:
build: ./web
volumes:
- ./web:/usr/share/nginx/html
labels:
- traefik.frontend.rule=PathPrefixStrip:/
- traefik.port=80
The above is all untested off the top of my head configuration, but should get you in the right direction. With the PathPrefixStrip rule, you can make a link in web to "/helloworld" which will go to the other container. And since the link doesn't have a hostname or port, it will go to the same traefik hostname/port you are already using.

Resources