Dashboard Access Can't Connect to Server

I'm trying to setup dashboard on docker for my home server using ubuntu 20.04, and before I add any of my services, I'm trying to get it running with just the dashboard. I'm using lets encrypt with the dns challenge, and am able to get the certificates, but I can't access the dashboard. whenever I try to access the dashboard, it refuses to connect. Below, are my compose file and my middlewares file.

docker-compose.yml

version: "3.8"

########################### NETWORKS
networks:
  t2_proxy:
    external:
      name: t2_proxy
  default:
    driver: bridge

########################### SERVICES
services:
# Traefik 2 - Reverse Proxy
  traefik:
    container_name: traefik
    image: traefik:2.4
    restart: unless-stopped
    command: # CLI arguments
      - --global.checkNewVersion=true
      - --global.sendAnonymousUsage=true
      - --entryPoints.http.address=:80
      - --entryPoints.https.address=:443
      # Allow these IPs to set the X-Forwarded-* headers - Cloudflare IPs: https://www.cloudflare.com/ips/
      # ONLY FOR CF- --entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31>
      - --entryPoints.traefik.address=:8080
      # - --entryPoints.ping.address=:8081
      - --api=true
      # - --api.insecure=true
      # - --api.dashboard=true
      #- --ping=true
      #- --pilot.token=$TRAEFIK_PILOT_TOKEN
      # - --serversTransport.insecureSkipVerify=true
      - --log=true
      - --log.level=DEBUG # (Default: error) DEBUG, INFO, WARN, ERROR, FATAL, PANIC
      - --accessLog=true
      - --accessLog.filePath=/traefik.log
      - --accessLog.bufferingSize=100 # Configuring a buffer of 100 lines
      - --accessLog.filters.statusCodes=400-499
      - --providers.docker=true
      - --providers.docker.endpoint=unix:///var/run/docker.sock # Use Docker Socket Proxy instead for improved security
      # - --providers.docker.endpoint=tcp://socket-proxy:2375
      # Automatically set Host rule for services
      - --providers.docker.defaultrule=Host(`{{ index .Labels "com.docker.compose.service" }}.$DOMAINNAME`)
      - --providers.docker.exposedByDefault=false
      # - --entrypoints.https.http.middlewares=chain-oauth@file
#      - --entrypoints.https.http.tls.options=tls-opts@file
      # Add dns-cloudflare as default certresolver for all services. Also enables TLS and no need to specify on individual >
#      - --entrypoints.https.http.tls.certresolver=duck-dns
#      - --entrypoints.https.http.tls.domains[0].main=$DOMAINNAME
#      - --entrypoints.https.http.tls.domains[0].sans=*.$DOMAINNAME
      # - --entrypoints.https.http.tls.domains[1].main=$DOMAIN # Pulls main cert for second domain
      # - --entrypoints.https.http.tls.domains[1].sans=*.$DOMAIN # Pulls wildcard cert for second domain
      - --providers.docker.network=t2_proxy
      - --providers.docker.swarmMode=false
      - --providers.file.directory=/rules # Load dynamic configuration from one or more .toml or .yml files in a directory
      # - --providers.file.filename=/path/to/file # Load dynamic configuration from a file
      - --providers.file.watch=true # Only works on top level files in the rules folder
      - --certificatesResolvers.duck-dns.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory # LetsEncrypt>
      - --certificatesResolvers.duck-dns.acme.email=$DUCKDNS_EMAIL
      - --certificatesResolvers.duck-dns.acme.storage=/acme.json
      - --certificatesResolvers.duck-dns.acme.dnsChallenge.provider=duckdns
      - --certificatesResolvers.duck-dns.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53
#      - --certificatesResolvers.duck-dns.acme.dnsChallenge.delayBeforeCheck=90 # To delay DNS check and reduce LE hitrate
    # networks:
      # t2_proxy:
        # ipv4_address: 192.168.90.254 # You can specify a static IP
    networks:
      - t2_proxy
    security_opt:
      - no-new-privileges:true
    ports:
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - target: 443
        published: 443
        protocol: tcp
        mode: host
      - target: 8080
        published: 8080
        protocol: tcp
        mode: host
    volumes:
      - $DOCKERDIR/traefik2/rules:/rules
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - $DOCKERDIR/traefik2/acme/acme.json:/acme.json
      - $DOCKERDIR/traefik2/traefik.log:/traefik.log
      - $DOCKERDIR/shared:/shared
    environment:
      - DUCKDNS_TOKEN=$DUCKDNS_TOKEN
      - DUCKDNS_EMAIL=$DUCKDNS_EMAIL
    labels:
      - "traefik.enable=true"
      # HTTP-to-HTTPS Redirect
      - "traefik.http.routers.http-catchall.entrypoints=http"
      - "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
      - "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      # HTTP Routers
      - "traefik.http.routers.traefik-rtr.entrypoints=https"
      - "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAINNAME`)"
      - "traefik.http.routers.traefik-rtr.tls=true"
      - "traefik.http.routers.traefik-rtr.tls.certresolver=duck-dns" # Comment out this line after first run of traefik to >
      - "traefik.http.routers.traefik-rtr.tls.domains[0].main=$DOMAINNAME"
      - "traefik.http.routers.traefik-rtr.tls.domains[0].sans=*.$DOMAINNAME"
#      - "traefik.http.routers.traefik-rtr.tls.domains[1].main=$SECONDDOMAINNAME" # Pulls main cert for second domain
#      - "traefik.http.routers.traefik-rtr.tls.domains[1].sans=*.$SECONDDOMAINNAME" # Pulls wildcard cert for second domain
      ## Services - API
      - "traefik.http.routers.traefik-rtr.service=api@internal"
      ## Middlewares
      - "traefik.http.routers.traefik-rtr.middlewares=middlewares-basic-auth@file"

middlewares.toml

[http.middlewares]
  [http.middlewares.middlewares-basic-auth]
    [http.middlewares.middlewares-basic-auth.basicAuth]
#      username=user, password=mystrongpassword (listed below after hashing)
#      users = [
#        "user:$apr1$bvj3f2o0$/01DGlduxK4AqRsTwHnvc1",
#      ]
      realm = "Traefik2 Basic Auth"
      usersFile = "/shared/.htpasswd" #be sure to mount the volume through dock>

I've gone through the documentation online, and I used HtpcBeginner's tutorial to get started.

Hi @zsanders61

What error do you receive?

I get connection refused.

So you're in your network and addressing the https://traefik.$DOMAINENAME?

Unless you have overrides in your hosts file or local dns server this will transit your gateway/router/firewall. Some will have issues with this trumboning of connection.

Easiest test is to update your hosts file to resolve the hostname to the lan ip.
Next easiest is to use curl with --resolve flag.

e.g.
curl https://traefik.domain.name/ --resolve traefik.domain.name:443:192.168.10.1

If one of those works then you can pin this on the gateway. Otherwise you'll have to investigate issues on the server.

Yes, I'm in the home network and addressing the https://traefik.$DOMAINENAME. Whenever I use curl, I get an error that the was refused.


I'm not exactly sure about the host file and --resolve. Would I just insert the local server ip?
I have the subdomain for duckdns, but not the full thing. does it need to be the full domain name that's listed under $DOMAINNAME, do I also need to include traefik.$DOMAINNAME?

Yes. The host ip where traefik is running as a container.

Thats the proxy network that the containers communicate on correct? Or is it the server ip?

It would be the docker hosts ip. As this is where the port is exposed.

Ok, I've tried curl with --resolve using three different ip addresses, and it returned the same thing each time.

curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not 
establish a secure connection to it. To learn more about this situation and 
how to fix it, please visit the web page mentioned above.

ip a returns the snippet below, and I tried the wlp4s0, docker0, and the 5th network ip dresses.

So you've progressed(?) from connection refused to an invalid certificate.

Your configuration is using the acme staging server so I would call the certificate error expected for now. You can use curl's -k option to skip certificate validation.

If you have correct dns and portforwarding configured from your firewall/router then this is likely to work from the internet. Getting it to work on you internal network will require some local dns or hosts entries on the pc's you are using to access your services.

No, I still get connection refused when I don't include the --resolve flag

Do I need to add the duckdns ip as a trusted ip?

We just demonstrated that unless you are resolving these hostnames to internal(lan) ip addresses this won't work for you.

This is a "limitation" of the firewall/router you are using. It is generally not a good idea to be using an external ip address to access something on the lan you are currently on.

This is a networking issue that you need to fix.

Ok, I'm not sure what you mean about adding local dns or host entries on my computer. Is this the same as adding them to the hosts file on my server?

I have enabled port forwarding for my server on the router already.

Yes. however if you have a router that does dns for you, and you can add entries, this will solve for all clients on your network.

Test from the internet!! In lieu of a mobile device I like to use Opera Browser and use it's "VPN" mode.

Ok, I understand that this has to do with the hosts file, but I'm not sure I understand the hosts file. Am I correct in saying that I need to add the ip and web address of my duckdns domain to the hosts file?

No. If you do that it is no different then trying to as it is.

You need the lan ip of the docker host, just like with the curl command.

Ok, I think I've figured out resolving the host name. Do I need a separate entry for the domain and each subdomain?

I consistently get an invalid certificate when using curl on the server, but when I use my laptop on the local network, it just times out.