2

I'm building a PHP web app based on micro-services, and currently, the routes into my app are on different ports. This is fine for development, but isn't going to be so reliable once I have launched. I have:

  • SPA frontend on port 10001
  • HTTP API on port 10000
  • Web Socket on 10002

I would like these all to be on the same port. I recently found Traefik which looks very flexible and would be able to accommodate my future needs. I appreciate I can do simple proxying with NginX but I quite like the idea of being able to tell the proxy to redirect traffic via an API (will be useful in the future).

However, I have set up a Traefik configuration and it does not seem to be proxying as I intend. I am struggling to get it to produce logs to say what it is wrong, and I am looking for a "quick win" to encourage me to persist with it further.

I have configured it with a host-to-container volume so it can explore Docker, using -v /var/run/docker.sock:/var/run/docker.sock). I don't really understand why it needs to know about my containers, since I was intending to set up all the configuration in my traefik.toml.

So, as I (dimly) understand it, I need to set up entrypoints (where traffic comes in), frontends (decisions on how to route it) and backends (servers that do stuff). My initial attempt looks like this:

# Entrypoints definition
#
# It looks like we have one entry point, and use
# frontends to filter WS/HTTP

[entryPoints]
  [entryPoints.everything]
  address = ":10005"

# Frontends definition

[frontends]
  [frontends.http]
    backend = "backend-spa"
  [frontends.http-api]
    backend = "backend-http-api"
    rule = "PathPrefix: /v1/captcha"
  [frontends.ws]
    backend = "backend-ws"

# Backends definition

[backends]
  [backends.backend-spa]
    url = "http://missive-interface:80"
  [backends.backend-http-api]
    url = "http://missive-controller:8080"
  [backends.backend-ws]
    url = "http://missive-controller:8081"

Presently I have just one container per service. I am differentiating the HTTP API on a pattern matcher, and I guess I would match the socket server on something as well (perhaps the Upgrade header).

So, when I visit http://localhost:10005/ I get 404 page not found. Well, fair enough, I've probably misconfigured something. So I reset the loglevel to INFO and I get this:

time="2017-09-06T13:45:35Z" level=info msg="Using TOML configuration file /etc/traefik/traefik.toml" 
time="2017-09-06T13:45:35Z" level=info msg="Traefik version v1.4.0-rc1 built on 2017-08-29_08:35:24AM" 
time="2017-09-06T13:45:35Z" level=info msg="Preparing server everything &{Network: Address::10005 TLS:<nil> Redirect:<nil> Auth:<nil> WhitelistSourceRange:[] Compress:false ProxyProtocol:false} with readTimeout=0s writeTimeout=0s idleTimeout=3m0s" 
time="2017-09-06T13:45:35Z" level=info msg="Starting provider *docker.Provider {"Watch":true,"Filename":"","Constraints":null,"Trace":false,"DebugLogGeneratedTemplate":false,"Endpoint":"unix:///var/run/docker.sock","Domain":"","TLS":null,"ExposedByDefault":true,"UseBindPortIP":false,"SwarmMode":false}" 
time="2017-09-06T13:45:35Z" level=info msg="Starting provider *web.Provider {"Address":":8080","CertFile":"","KeyFile":"","ReadOnly":false,"Statistics":null,"Metrics":null,"Path":"","Auth":null,"Debug":false,"CurrentConfigurations":{},"Stats":{"Uptime":"2017-09-06T13:45:35.383750945Z","Pid":1,"ResponseCounts":{},"TotalResponseCounts":{},"TotalResponseTime":"0001-01-01T00:00:00Z"},"StatsRecorder":null}" 
time="2017-09-06T13:45:35Z" level=info msg="Starting server on :10005" 
time="2017-09-06T13:45:35Z" level=error msg="No entrypoint defined for frontend frontend-Host-missive-controller-app, defaultEntryPoints:[]" 
time="2017-09-06T13:45:35Z" level=error msg="Skipping frontend frontend-Host-missive-controller-app..." 
time="2017-09-06T13:45:35Z" level=error msg="No entrypoint defined for frontend frontend-Host-missive-interface-app, defaultEntryPoints:[]" 
time="2017-09-06T13:45:35Z" level=error msg="Skipping frontend frontend-Host-missive-interface-app..." 
time="2017-09-06T13:45:35Z" level=error msg="No entrypoint defined for frontend frontend-Host-missive-storage-app, defaultEntryPoints:[]" 
time="2017-09-06T13:45:35Z" level=error msg="Skipping frontend frontend-Host-missive-storage-app..." 
time="2017-09-06T13:45:35Z" level=error msg="No entrypoint defined for frontend frontend-Host-missive-transmitter-app, defaultEntryPoints:[]" 
time="2017-09-06T13:45:35Z" level=error msg="Skipping frontend frontend-Host-missive-transmitter-app..." 
time="2017-09-06T13:45:35Z" level=info msg="Server configuration reloaded on :10005" 

However, when triggering the 404, no extra logs are output on stdout, so I cannot tell what the issue is. I don't think it is one of my services that is producing this.

I am guessing that maybe my backends should indicate the name of the container that handles that service, so I can remove the "Skipping" errors? I should note also that I am not using Kubernetes or anything like that - it's just plain Docker Compose for now.

What thing am I not spotting that would move me forward?

Update

Traefik seems to be very unhappy if I don't give it access to my Docker config. If I remove the -v volume switch on docker run then I get this added to logs, every second or so:

time="2017-09-06T17:18:20Z" level=error msg="Failed to retrieve information of the docker client and server host: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?" 
time="2017-09-06T17:18:20Z" level=error msg="Provider connection error Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?, retrying in 443.292653ms" 

I have also found how to turn on [accessLogs] in config, and I get this written to stdout. These show my requests are hitting the proxy, but they don't give any information as to how they are being routed, nor whether my frontend and backend definitions are recognised as valid.

172.17.0.1 - - [06/Sep/2017:17:57:44 +0000] "GET / HTTP/1.1" %!d(<nil>) %!d(<nil>) - "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0" 1 - - 0ms
172.17.0.1 - - [06/Sep/2017:17:57:49 +0000] "GET /index.php HTTP/1.1" %!d(<nil>) %!d(<nil>) - "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0" 2 - - 0ms
172.17.0.1 - - [06/Sep/2017:17:58:09 +0000] "GET /index.php HTTP/1.1" %!d(<nil>) %!d(<nil>) - "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:55.0) Gecko/20100101 Firefox/55.0" 3 - - 0ms
halfer
  • 19,824
  • 17
  • 99
  • 186

1 Answers1

1

OK, so first if you don't use Docker configuration then you don't need to provide the socket to it even if your services are running in containers (but when you are more comfortable with Traefik you should look into it as it's really useful)

The second thing is that the logs tells you exactly the issue, none of your frontends are actually used as they are not specifying the entrypoint. You can either add

defaultEntryPoints = ["everything"]

above your entrypoints definition or add

entrypoints = ["everything"]

to each of your frontends.

Another issue is that you have 2 frontends without any rules so it probably won't work because there's no way to tell them apart. You can either use a host rule or add a path prefix to the WS frontend.

Finally, you need to let Traefik know which configuration system to use. Put this before your [frontends]:

[file]

The schema on the basics page describe well how everything works together.

halfer
  • 19,824
  • 17
  • 99
  • 186
hlidotbe
  • 888
  • 2
  • 9
  • 17
  • Thanks for the various hints, appreciated. I added the connection to Docker since it repeatedly added new logs if I did not (see question update). It seemed to be the only way to get it to put a sock in it! `:=)` – halfer Sep 06 '17 at 17:20
  • I will try adding the `entrypoint` key as you suggest. I ignored the "No entrypoint defined" logs, since they refer to my containers, and given I am wanting (initially) to do things manually, I thought they might not be relevant. – halfer Sep 06 '17 at 17:24
  • Aha, I removed the `[docker]` key from my config file, and the Docker problem disappears. I was using the default Traefik config file, as the manual recommends. – halfer Sep 06 '17 at 17:42
  • I've updated the question with notes on turning on access logs, though that doesn't shed a lot of light. I have narrowed it down to one frontend and one backend, and am still getting 404. – halfer Sep 06 '17 at 18:02
  • I've also added `defaultEntryPoints = ["everything"]`. I guess it would be good to be able to query what Traefik thinks I have. Now the dashboard is empty, which I think does not bode well - perhaps it thinks there is nothing to route to? – halfer Sep 06 '17 at 18:08
  • You can also enable the web backend (https://docs.traefik.io/configuration/backends/web/) read-only so you can see what traefik understood of your configuration. – hlidotbe Sep 07 '17 at 07:48
  • Thanks, yes I think that's the dashboard I mentioned above. It's empty. I will repost my whole config. – halfer Sep 07 '17 at 08:20
  • [Here](https://gist.github.com/halfer/ccd168d7c05b06946095f94d0fb7193d) is my config. I just tried adding the load balancer in the backend, but no difference. As you can see I have commented things out, to produce just one frontend and one backend. It's as simple as possible, and still not a sausage! – halfer Sep 07 '17 at 08:41
  • Found it :) you didn't tell traefik which configuration backend to use. Add [file] above your frontend definitions – hlidotbe Sep 07 '17 at 09:15
  • Marvellous, that's cracked it! Thank you. Oddly that token is not in the [sample config file](https://raw.githubusercontent.com/containous/traefik/master/traefik.sample.toml) nor the Basics manual page. I now have a gateway error, but I think that's down to Traefik not being able to resolve the DNS names in the `url`s I have provided. – halfer Sep 07 '17 at 09:23
  • I have [added a docs suggestion](https://github.com/containous/traefik/issues/2082) to the Traefik issues page. I've now refined my request matchers and moved Traefik into a Docker Compose container, and it works very nicely so far. Thanks again. – halfer Sep 07 '17 at 16:42