Traefik without Docker - newbie question

Hello guys,

I am new to Traefik and have problems setting up Traefik without Docker on a Debian VM. I mainly find examples with docker and everything I found without docker, incl. the official docs doesn't work out for me somehow.

My main goal is to get a wildcarf certificate for my other services on several vms via let's encrypt by DNS-challenge.

For example I don't get where to put my provider code, API keys and passwords. I am even not able to access the dashboard right now. If i run traefik it loads the config and also version check show that it's running (v2.10.7 btw) so the basic installation seems fine, just struggeling with the config...

Can someone please provide a working basic setup which shows how get the dashboard work, set up the dns acme challenge and an example where I can see how one service with any IP is set up to get a valid ssl certificate?

Best regards!
Yann

Traefik works with two kinds of configs.

Static config includes api, log, entrypoints, providers, certresolvers. It can be in traefik.yml file or in command in docker-compose.yml.

Dynamic config included http, tcp and tls (for custom certs). Those configs need to be loaded via a provider (in static config), mostly from file or from Docker labels.

Static config can only be loaded by a single method, you can’t mix. Within the static config you can define multiple providers to load the dynamic configs.

β€”β€”β€”

Traefik provides a dashboard to be able to see the current state (doc).

β€”β€”β€”

Traefik LetsEncrpt certResolvers use environment variables for tokens etc. (doc), so you need to set those for the Traefik user (when not using Docker).

Ok thanks, I got it working. I can acces my Traefik Dashboard with a valid LE certificate.

my main question for now is how I handle other lxcs/vms to work with traefik, since in Docker I use labels for the several services. Or doesnt that matter here? Cause there is a VM running a service and it doesnt't work out if i create a router and a service for that.

Also have to say that right now treafik runs in a LXC container. It's an unprivileged lxc, may that be the reason? my main firewall has a any-rule for now on the traefik lxc, so thats not the reason, i can ping everything).

What do I have to consider here?

If you use two separation layers (VM plus container), I don’t think there is a simple solution.

You could connect your services in different VMs using Docker Swarm, then Traefik Configuration Discovery works.

Ehm, like I said in the title: right now there is no docker running at all and I try to avoid it. Sure in the long run there might be one VM providing a few services with docker or better podman, but that's it.

So if you say with VMs and LXCs it's not that simple, then let me put Traefik in a VM and only serve other VMs, so forget about LXCs. How do I connect Traefik (binary install) to the other VMs/services?

Can I simply put a second NIC to every VM in the same network like the Traefik VM and then it should work?

Sorry. Of course you can use any VM and LXC if you open the required ports and create Traefik route and service manually in a dynamic config file.

What I also don't get is why does it matter which technology (VM/LXC) is behind the URLs?

Why are people getting LE-certificates with traefik for their router webinterfaces, their synologys, their printer webinterfaces and so on, on several vlans, without changing anything on these systems?

That's all I want...

Like I said, there is no port to open since firewall is set to any right now.

Also like I said, I created a traefik route and service manually in my dyn. config.

But it still doesnt work...I basically (almost) copied the same from the working traefik entry and was wondering if there is something I didn't do right or forget about it:

My traefik dashboard is working fine, and I also see that the certificate for my other service is in acme.json. So that part should be fine, but I always get a connection refused error when I try to go to that service....

In my dyn. config i put:

routers:
    SERVICENAME:
      rule: Host(`SERVICENAME.DOMAIN`)
      entrypoints:
        - websecure
      service: SERVICENAME
      tls:
        certResolver: letsencrypt
        options: modern

services:
    SERVICENAME:
      loadBalancer:
        servers:
          - url: http://IP:PORT/

shouldnt it work then? I see that if I go to that service with http it redirects to https, so this also seem to work.

Please provide the full setup, not just pieces. Share your full Traefik static and dynamic config.

sure no problem, its pretty basic.
With this config my traefik dashboard works and I get my SSL certificate.
As first service I want semaphore to work, which is right now accessible at http://10.0.0.8:3000 - I can also ping the IP from the Traefik Host (in general, firewall is set to any (all destinations, all ports, all protocols)

traefik.yml

entryPoints:
  web:
    address: :80
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: :443
    http:
      tls:
        certResolver: letsencrypt
        domains:
          - main: "DOMAIN.net"
            sans:
              - "*.DOMAIN.net"
api:
  dashboard: true
  insecure: false

log:
  level: ERROR
  filePath: /var/log/traefik.log

certificatesResolvers:
  letsencrypt:
    acme:
      email: MYMAIL
      keyType: EC384
      storage: /etc/traefik/acme/acme.json
      caServer: https://acme-v02.api.letsencrypt.org/directory
      dnsChallenge:
        provider: netcup
        resolvers:
          - "root-dns.netcup.net:53"
          - "second-dns.netcup.net:53"
providers:
  file:
    filename: /etc/traefik/dynamic/dynamic.yml
    watch: true

dynamic.yml

tls:
  options:
    modern:
      minVersion: VersionTLS12
      curvePreferences:
        - CurveP521
        - CurveP384

http:
  middlewares:
    apiAuth:
      basicAuth:
        users:
          - user:$apr1$8d3/vHA7$P7BPK7TJyVYHUpdRvgQFT0

  routers:
    api:
      rule: Host(`traefik.DOMAIN.net`)
      entrypoints:
        - websecure
      middlewares:
        - apiAuth
      service: api@internal
      tls:
        certResolver: letsencrypt
        options: modern
    traefik:
      rule: Host(`traefik.DOMAIN.net`)
      service: traefik
      tls:
        certResolver: letsencrypt
        options: modern
    semaphore:
      rule: Host(`semaphore.DOMAIN.net`)
      entrypoints:
        - websecure
      service: semaphore
      tls:
        certResolver: letsencrypt
        options: modern
  services:
    traefik:
      loadBalancer:
        servers:
          - url: http://localhost:8080/
    semaphore:
      loadBalancer:
        servers:
          - url: http://10.0.0.8:3000/

I tried a lot but still nothing works :confused: also deleted the entrypoint line or tried with entrypoints -web. It doesnt work... if I uncomment everything regarding semaphore and open http://semaphore.mydomain.net:3000 it works... so everything fine from DNS side.

Besides that I tried other external services like my router webinterface. And it's exactly the same. At the dashboard, everything seems fine, changed to DEBUG mode also there nothing seems to be wrong.

I really wonder why It's not working :frowning: Actually have no idea anymore whatelse to try....I wish I saw a bad gateway error or something but all I get is that the website is not available ....

anyone an idea what I can do or how I can narrow down the problem?

Enable access log in JSON format to see if requests to semaphore.DOMAIN.net fail at Traefik or at your target service.

Check Traefik debug log if the router is recognized and what happens to the certs.

Check acme.json which certs have been created.

access.log doesnt show any requests. it only shows entries from my user logged in into the traefik dashoard.

In acme.json there are all certificates of all the services I tried.

Here is my debug log:

{"level":"debug","msg":"Adding certificate for domain(s) traefik.domain.net","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"Adding certificate for domain(s) semaphore.domain.net","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"Adding certificate for domain(s) cisco.domain.net","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"No default certificate, fallback to the internal generated certificate","time":"2024-01-28T23:02:54+01:00","tlsStoreName":"default"}
{"entryPointName":"web","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware noop@internal","routerName":"web-to-websecure@internal","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"web","level":"debug","middlewareName":"redirect-web-to-websecure@internal","middlewareType":"RedirectScheme","msg":"Creating middleware","routerName":"web-to-websecure@internal","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"web","level":"debug","middlewareName":"redirect-web-to-websecure@internal","middlewareType":"RedirectScheme","msg":"Setting up redirection to https 443","routerName":"web-to-websecure@internal","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"web","level":"debug","middlewareName":"traefik-internal-recovery","middlewareType":"Recovery","msg":"Creating middleware","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware api@internal","routerName":"api@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"apiAuth@file","middlewareType":"BasicAuth","msg":"Creating middleware","routerName":"api@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"apiAuth@file","msg":"Adding tracing to middleware","routerName":"api@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"pipelining","middlewareType":"Pipelining","msg":"Creating middleware","routerName":"cisco@file","serviceName":"cisco","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating load-balancer","routerName":"cisco@file","serviceName":"cisco","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating server 0 https://10.0.0.5:1410/","routerName":"cisco@file","serverName":0,"serviceName":"cisco","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"child https://10.0.0.5:1410/ now UP","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"Propagating new UP status","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware cisco","routerName":"cisco@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware 
middleware","routerName":"semaphore@file","serviceName":"semaphore","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating load-balancer","routerName":"semaphore@file","serviceName":"semaphore","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating server 0 http://10.0.0.8:3000/","routerName":"semaphore@file","serverName":0,"serviceName":"semaphore","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"child http://10.0.0.8:3000/ now UP","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"Propagating new UP status","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware semaphore","routerName":"semaphore@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"pipelining","middlewareType":"Pipelining","msg":"Creating middleware","routerName":"traefik@file","serviceName":"traefik","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating load-balancer","routerName":"traefik@file","serviceName":"traefik","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Creating server 0 http://localhost:8080/","routerName":"traefik@file","serverName":0,"serviceName":"traefik","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"child http://localhost:8080/ now UP","time":"2024-01-28T23:02:54+01:00"}
{"level":"debug","msg":"Propagating new UP status","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"tracing","middlewareType":"TracingForwarder","msg":"Added outgoing tracing middleware traefik","routerName":"traefik@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","middlewareName":"traefik-internal-recovery","middlewareType":"Recovery","msg":"Creating middleware","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Adding route for cisco.domain.net with TLS options modern@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Adding route for semaphore.domain.net with TLS options modern@file","time":"2024-01-28T23:02:54+01:00"}
{"entryPointName":"websecure","level":"debug","msg":"Adding route for traefik.domain.net with TLS options modern@file","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Trying to challenge certificate for domain [traefik.domain.net] found in HostSNI rule","providerName":"letsencrypt.acme","routerName":"traefik@file","rule":"Host(`traefik.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Trying to challenge certificate for domain [traefik.domain.net] found in HostSNI rule","providerName":"letsencrypt.acme","routerName":"api@file","rule":"Host(`traefik.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Trying to challenge certificate for domain [cisco.domain.net] found in HostSNI rule","providerName":"letsencrypt.acme","routerName":"cisco@file","rule":"Host(`cisco.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Trying to challenge certificate for domain [semaphore.domain.net] found in HostSNI rule","providerName":"letsencrypt.acme","routerName":"semaphore@file","rule":"Host(`semaphore.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Looking for provided certificate(s) to validate [\"semaphore.domain.net\"]...","providerName":"letsencrypt.acme","routerName":"semaphore@file","rule":"Host(`semaphore.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"No ACME certificate generation required for domains [\"semaphore.domain.net\"].","providerName":"letsencrypt.acme","routerName":"semaphore@file","rule":"Host(`semaphore.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Looking for provided certificate(s) to validate [\"traefik.domain.net\"]...","providerName":"letsencrypt.acme","routerName":"traefik@file","rule":"Host(`traefik.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"No ACME certificate generation required for domains [\"traefik.domain.net\"].","providerName":"letsencrypt.acme","routerName":"traefik@file","rule":"Host(`traefik.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Looking for provided certificate(s) to validate [\"traefik.domain.net\"]...","providerName":"letsencrypt.acme","routerName":"api@file","rule":"Host(`traefik.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"No ACME certificate generation required for domains [\"traefik.domain.net\"].","providerName":"letsencrypt.acme","routerName":"api@file","rule":"Host(`traefik.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"Looking for provided certificate(s) to validate [\"cisco.domain.net\"]...","providerName":"letsencrypt.acme","routerName":"cisco@file","rule":"Host(`cisco.domain.net`)","time":"2024-01-28T23:02:54+01:00"}
{"ACME CA":"https://acme-v02.api.letsencrypt.org/directory","level":"debug","msg":"No ACME certificate generation required for domains [\"cisco.domain.net\"].","providerName":"letsencrypt.acme","routerName":"cisco@file","rule":"Host(`cisco.domain.net`)","time":"2024-01-28T23:02:54+01:00"}

You say your domain points to Traefik, but there is no request in the access log. Something is really not right.

Is your app router shown in dashboard?

yes the router and service of semaphore is with "success "in dashboard.

I was btw deleting the whole LXC and created it from the scratch. And its exactly the same in the end. One last try would be maybe a real VM instead of LXC, but usually this shouldnt matter...

This time I did one thing different. I didn't create a seperate traefik user and tried everything with root. And one thing i noticed here.

From the beginning when I was starting traefik for the first time i received:

{"level":"debug","msg":"http: TLS handshake error from 10.1.0.2:53565: remote error: tls: bad certificate","time":"2024-01-29T12:11:36+01:00"}

IP 10.1.0.2 is my client where I am connected with SSH.

Then I thought, ok lets still move on and see what happens. Then I did the ACME Challenge and received my certificates.

After that I checkd again the debug log, and the message was gone and instead it says now:

{"level":"debug","msg":"http: TLS handshake error from 10.1.0.2:53633: remote error: tls: unknown certificate authority","time":"2024-01-29T12:13:12+01:00"}

these messages didn't appear when I ran traefik with a dedicated user.

But still... I don't know what else to do.... but I am willed to find the problem. I mean... I am almost there, again I received all my certificates for my services and dashboard works with valid LE-certificate.

ok forget about the error messages. They appeared since I used Staging certificates. I changed it to offical certificates and now theyre gone and debug log is clean.

But stil, my general problem persists...

If I open http://semaphore.mydomain.net:3000 it works, if I open http://semaphore.mydomain.net it doesn't work, but I see I get redirected to https, but I get ERR_CONNECTION_REFUSED message from my browser.

It seems the DNS entry is okay as you reach your target server. Port 80 and 3000 seem to work, but port 443 for https seems not to work. But also no other service seems to be listening on port 443.

Any firewall or router which might block the port? Are you running this at home and have port forwarding for 443 enabled?

I run this at home and are in full control.

On my hypervisor the firewall is deactivated, on the host itself there is no firewall right now. My main firewall (on this network) is fully open - any any any (protocols, destinations, ports). Even opened the firewall where semaphore sits with any rules. no difference.

But when you say port 443 doesnt seem to work, why the traefik dashboard works?

My dashboard for routers and services is also fine, here my router for semaphore:

i can also say that https works on this network (where semaphore sits) cause there is another service with a selfsigned cert which i enter via https.

Ok now i tried it again with a priviliged LXC, same problem. Then i deleted it, created a brand new debian VM. Same problem.

I get all my certificates, dashboard works with valid certificate, but cant get any other service (no matter if another VM or my router webinterface) to work with it.

This really makes no sense... I am really frustrated since I probably spend 10h per day for the last 5 days and it still doesnt work :frowning: