jonashackt / traefik-docker-windows-server-2016

Example project showing how to run Traefik in a Windows Docker Container in Windows Server 2016 without the support of bind-mounting named pipes
MIT License
3 stars 4 forks source link

Trying to use this.. #1

Closed julianflapper closed 6 years ago

julianflapper commented 6 years ago

Hi, I'm trying to apply this to get Traefik to work on Docker for Windows (Regular Windows, that is).

However, while I can connect to the Traefik dashboard on localhost:8080,

I was hoping you'd know more about setting up Traefik on Windows, as nobody in the Traefik slack channel seems to know how to fix this.. I'm running Linux on my production servers but I need Docker and Traefik to work on my PC and laptop, both running Windows, for development.

jonashackt commented 6 years ago

Hi @julianflapper, I worked quite a while with Docker on Windows, maybe I can help you :) First question: We need to exactly know which version of Windows 10 you´re using - so please run

(Get-ItemProperty -Path c:\windows\system32\hal.dll).VersionInfo.FileVersion

in an evelated Powershell and come back with the output here please.

julianflapper commented 6 years ago

Hi, That's great to hear! I'd really like to use Traefik so I can easily route traffic to my development containers instead of using different ports or having only one open.

I'm running: Windows 10 Pro, version 10.0.17134.285 (WinBuild.160101.0800) Docker CE 18.06.1-ce-win73 (19507) Traefik 1.7.0

In the Docker settings, I have enabled "Expose daemon on tcp://localhost:2375 without TLS", so the daemon should be exposed. Do I need to run it manually or is the daemon equal to Docker itself? If it runs when Docker runs, then I would think the endpoint is exposed properly on Docker's side. Running 'ipconfig', the DockerNAT IPv4 is 10.0.75.1

Using either that IP or localhost as endpoint in Traefik results in the above errors. I can access the Traefik dashboard on localhost:8080 on both those endpoints, but a 'whoami' container as a test couldn't connect to it. The Traefik dashboard doesn't shop up as backend in the dashboard either.

I've been changing the docker-compose file for Traefik a lot to test some stuff but I toned it down to a very basic one:

version: '3.4'

services:
  proxy:
    image: traefik:latest
    command: --api --docker --debug --docker.endpoint=tcp://10.0.75.1:2375
    ports:
      - "80:80"
      - "8080:8080"
    restart:
      always
jonashackt commented 6 years ago

Ah, so you have a current Windows 10 version with all updates turned on!! Welcome to the fun world with Docker on Windows 😄 - This will make your experience much better.

Then you don´t need the "workaround" I needed for old Windows Server 2016 - you can use named pipes:

Running Docker on Linux, the Docker API is usually hosted on Unix domain socket, and since these are in the filesystem namespace, sockets can be bind-mounted easily into containers. On Windows, the Docker API is available on a named pipe. Previously, named pipes where not bind-mountable into Docker Windows containers, but starting with Windows 10 and Windows Server 1709, named pipes can now bind-mounted.

So you can go with the example provided at the top of the README: https://github.com/jonashackt/traefik-docker-windows-server-2016#problem:

services:
  proxy:
    image: stefanscherer/traefik-windows
    command: --api --docker --logLevel=WARN --docker.endpoint=npipe:////./pipe/docker_engine
    networks:
      - default
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - \\.\pipe\docker_engine:\\.\pipe\docker_engine
    restart:
      always
jonashackt commented 6 years ago

Ah - and another question: Do you really need Windows Containers? With a Win32 environment, Powershell, .Net etc inside of them? Or couldn´t you just switch to Linux Containers and use the standard Traefik image for Linux? This would again make life much easier ;)

julianflapper commented 6 years ago

Ah I thought only Windows server had this pipe. I will try it out right now. Though, shouldn't the way I did it work too? Exposing the tcp port of the daemon and then using that as endpoint?

Ah - and another question: Do you really need Windows Containers? With a Win32 environment, Powershell, .Net etc inside of them? Or couldn´t you just switch to Linux Containers and use the standard Traefik image for Linux? This would again make life much easier ;)

I need Docker to run on Windows, but all containers are the Linux containers. So Traefik too. I don't think I'm using any Windows containers or ever have.

Docker runs on Windows so I can't mount the "/var/run/docker.sock:/var/run/docker.soc", I guess?

julianflapper commented 6 years ago

So I just tried applying your code (didn't use your traefik-windows image though, if that's not a problem.)

Got this error:

Creating traefik_proxy_1 ... error

ERROR: for traefik_proxy_1  Cannot create container for service proxy: b'Mount denied:\nThe source path "\\\\\\\\.\\\\pipe\\\\docker_engine:\\\\\\\\.\\\\pipe\\\\docker_engine"\nis not a valid Windows path'

ERROR: for proxy  Cannot create container for service proxy: b'Mount denied:\nThe source path "\\\\\\\\.\\\\pipe\\\\docker_engine:\\\\\\\\.\\\\pipe\\\\docker_engine"\nis not a valid Windows path'
ERROR: Encountered errors while bringing up the project.

EDIT: This is my docker-compose now:

version: '3.4'

services:
  proxy:
    image: traefik:latest
    command: --api --docker --debug --docker.endpoint=npipe:////./pipe/docker_engine
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - \\.\pipe\docker_engine:\\.\pipe\docker_engine
    restart:
      always
jonashackt commented 6 years ago

Ok, so we have another root problem 😄

Docker runs on Windows so I can't mount the "/var/run/docker.sock:/var/run/docker.soc", I guess?

No, Linux Containers do not run directly on Windows in Docker for Windows, there´s a small Linux layer whatsoever left to provide a full blown Linux environment within the Docker containers. So the exact standard way of using Traefik on Linux should apply to your use case - and this repository is not at all of use to you 👻

If that´s of any help, you can have a look at https://github.com/jonashackt/ansible-windows-docker-springboot/blob/master/step5-deploy-multiple-spring-boot-apps-to-mixed-os-docker-swarm/templates/docker-stack.j2 - where Traefik is used inside a Mixed OS Docker Swarm, but runs itself on Linux:

  traefik:
    image: traefik
    ports:
      - target: 80
        published: 80
        protocol: tcp
      - target: 8080
        published: 8080
        protocol: tcp
    tty:
      true
    restart:
      unless-stopped
    deploy:
      replicas: 1
      placement:
        constraints: [node.labels.os==linux]
        constraints: [node.role == manager]
    command:
      - --docker
      - --docker.swarmmode
      - --docker.domain={{ docker_domain }}
      - --docker.watch
      - --web
      - --logLevel=INFO
    volumes:
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock

Simply using /var/run/docker.sock should be all you need then.

julianflapper commented 6 years ago

Oh shit I feel like such an idiot now. I thought I tried the var/run/docker.sock endpoint and when it didn't work I figured it was because the source of that volume (/var/run/docker.sock) does not exist on Windows.

It works now, just not with the subdomain working right away but probably need to modify my hosts file for that :)

Thanks!

jonashackt commented 6 years ago

Oh I don´t think "feeling like an idiot" is a good thing to do 👹 (done that too often) Focus on what you managed to do - and I can assure you: There´s really something in the sentence: "An expert is somebody who did all possible mistakes in one field" ;) Closing the issue then.