Cannot get traefik to forward my domain to my internal wireguard IP (using VPS for public IP)

I'm attempting to make Immich accessible outside my home via the VPS tunneling with Wireguard into my home network. For context, I'm behind a CG-NAT at home (VM running Ubuntu with Immich on it via Docker) with no static IP or IPv6 available. My workaround has been to purchase a cheap VPS (Ubuntu 20) with a public IP.

I have installed Docker, Docker compose, and Wireguard on both machines (Traefik on just the VPS).

After configuring with help from ChatGPT, my VPS can successfully see my homelab (Immich app) by using the curl command to request the internal Wireguard IP and the Immich port (for example, 10.0.0.1:2283). It pulls up what looks like the Immich login page in html form in the terminal, so that's encouraging. Wireguard seems to be working great.

The issue is that my custom domain isn't pointing to Immich or a Traefik screen. Instead, I get a 404 error (better than timing out like earlier, lol).

I bought the domain on Cloudflare and created an A record pointing to the public IP of my VPS (DNS only, Cloudflare proxy turned off). Not sure why that isn't making its way through Traefik. I also have my traefik.yml file configured to work with Let's Encrypt for a cert. Let's Debug says I'm in the green, but my logs indicate that the ACME challenge is not working and it's falling back on a self signed cert or something.

Any ideas?

My docker-compose.yml

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--api.insecure=true"                   # Enable the dashboard (optional)
      - "--providers.docker=true"                # Enable Docker provider
      - "--entrypoints.web.address=:80"          # Listen on port 80
      - "--entrypoints.websecure.address=:443"   # Listen on port 443
      - "--entrypoints.dashboard.address=:8080"  # Dashboard entry point
    ports:
      - "80:80"                                  # HTTP
      - "443:443"                                # HTTPS
      - "8080:8080"                              # Dashboard (optional)
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"  # Access Docker socket
      - "./traefik.yml:/traefik.yml"              # Traefik config

My traefik.yml

api:
  dashboard: true

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

certificatesResolvers:
  letsencrypt:
    acme:
      email: EMAIL@email.com  # Replace with your email address
      storage: acme.json  # File to store the certificates
      httpChallenge:
        entryPoint: web  # Entry point for HTTP challenge

http:
  routers:
    myrouter:
      rule: "Host(`DOMAIN.com`)"
      entryPoints:
        - websecure
      service: myservice
      tls:  # This enables HTTPS; make sure you have Let's Encrypt set up if using this
        certResolver: letsencrypt  # Make sure you have a cert resolver defined

  services:
    myservice:
      loadBalancer:
        servers:
          - url: "http://10.1.0.1:2283"  # Point to the Immich application

log:
  level: DEBUG

My Traefik logs seem to indicate an ACME issue:

time="2024-08-23T15:05:17Z" level=error msg="Cannot retrieve the ACME challenge for DOMAIN.com (token \"letsdebug-test\")" providerName=acme time="2024-08-23T15:05:17Z" level=error msg="Cannot retrieve the ACME challenge for DOMAIN.com (token \"**********<TOKEN>**********")" providerName=acme

You can’t provide static config via traefik.yml and command, decide for one.

Traefik http routers and services need to be configured in dynamic config, either in labels with providers.docker or in a separate dynamic config file, loaded via providers.file.

1 Like

Thanks for your help! I'm pretty new to all this, so bear with me. It sounds like you're saying I can delete my traefik.yml file and just add the necessary configurations to my docker-compose.yml file. Is that accurate? ChatGPT gave me this example edit of my docker-compose.yml, though it appears to run Immich in the VPS, which isn't necessary since it's already set up on my homelab VM and reachable via Wireguard:

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--api.insecure=true"                   # Enable the dashboard (optional)
      - "--providers.docker=true"               # Enable Docker provider
      - "--entrypoints.web.address=:80"         # Listen on port 80
      - "--entrypoints.websecure.address=:443"  # Listen on port 443
      - "--certificatesresolvers.letsencrypt.acme.email=EMAIL@email.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"                                 # HTTP
      - "443:443"                               # HTTPS
      - "8080:8080"                             # Dashboard (optional)
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"  # Access Docker socket
      - "./letsencrypt:/letsencrypt"            # Persist Let's Encrypt data

  immich:
    image: ghcr.io/immich-app/immich-server:v1.112.1
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.immich.rule=Host(`DOMAIN.com`)"
      - "traefik.http.routers.immich.entrypoints=websecure"
      - "traefik.http.routers.immich.tls.certresolver=letsencrypt"
      - "traefik.http.services.immich.loadbalancer.server.port=2283"

I would use an explicit Docker network, see simple Traefik example.

Got it working, finally! Thanks for setting me in the right direction. I was right about the previous yml file running Immich in the VPS, which I did not want. I was able to point to the one running on my homelab pretty easily.

For future reference, here are my working files (both on my VPS):

/etc/traefik/docker-compose.yml

services:
  traefik:
    image: traefik:v3.0
    ports:
      - 80:80
      - 443:443
    networks:
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - letsencrypt:/letsencrypt
      - /etc/traefik/dynamic:/etc/traefik/dynamic
    command:
      - --api.dashboard=true
      - --log.level=INFO
      - --providers.file.directory=/etc/traefik/dynamic
      - --providers.file.watch=true
      - --providers.docker.network=proxy
      - --providers.docker.exposedByDefault=false
      - --entrypoints.web.address=:80
      - --entrypoints.web.http.redirections.entrypoint.to=websecure
      - --entryPoints.web.http.redirections.entrypoint.scheme=https
      - --entrypoints.websecure.address=:443
      - --certificatesresolvers.myresolver.acme.email=EMAIL@EMAIL.com
      - --certificatesresolvers.myresolver.acme.tlschallenge=true
      - --certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json

networks:
  proxy:
    name: proxy

volumes:
  letsencrypt:
    name: letsencrypt

/etc/traefik/dynamic/dynamic.yml

http:
  routers:
    immich:
      rule: "Host(`DOMAIN.com`)"
      entryPoints:
        - websecure
      service: immich-service
      tls:
        certResolver: myresolver

  services:
    immich-service:
      loadBalancer:
        servers:
          - url: "http://10.0.0.1:2283"  # The WireGuard IP and port of Immich on your homelab

v3.1 is current, don’t stay behind :wink:

1 Like