job "traefik" {
  group "traefik" {
    count = 2

    network {
      mode = "bridge"
      port "http" {
        static = 80
      }

      port "https" {
        static = 443
      }

      port "api" {
        static = 8081
      }
    }
    service {
      connect {
        sidecar_service {
          proxy {
            upstreams {
              destination_name = "auth"
              local_bind_port  = 9091
            }
          }
        }
      }
    }

    service {
      name = "traefik"
      port = "api"

      check {
        name     = "alive"
        type     = "tcp"
        port     = "api"
        interval = "10s"
        timeout  = "2s"
      }
    }

    task "traefik" {
      driver = "docker"

      config {
        image = "traefik:v3.3"
        ports = ["http", "https", "api"]

        volumes = [
          "local/traefik.yml:/etc/traefik/traefik.yml",
          "local/configs/:/etc/traefik/configs/"
        ]
      }

      volume_mount {
        volume      = "unraid_appdata_traefik"
        destination = "/opt/traefik"
        read_only   = false
      }

      template {
        data = <<EOF
log:
  level: INFO
entryPoints:
  web:
    address: ":80"
    http:
      redirections:
        entryPoint:
          to: websecure
          scheme: https
  websecure:
    address: ":443"
    http:
      tls:
        certResolver: letsencrypt
  traefik:
    address: ":8081"

api:
  dashboard: true
  insecure: true

providers:
  file:
    directory: "/etc/traefik/configs/"

  consulCatalog:
    prefix: "traefik"
    exposedByDefault: false
    defaultRule: {{"Host(`{{ .Name }}.othrayte.one`)"}}
    endpoint:
      address: "{{ env "NOMAD_HOST_IP_http" }}:8500"
      scheme: "http"

certificatesResolvers:
  letsencrypt:
    acme:
      email: "othrayte@gmail.com"
      storage: "/opt/traefik/acme.json"
      httpChallenge:
        entryPoint: web
EOF

        destination = "local/traefik.yml"
      }

      template {
        data = <<EOF
http:
  serversTransports:
    ignorecert:
      insecureSkipVerify: true
  middlewares:
    auth:
      forwardAuth:
        address: "http://localhost:9091/api/authz/forward-auth"
        trustForwardHeader: true
    auth-allow-token:
      chain:
        middlewares:
          - auth
    inject-kopia-basic-auth:
      headers:
        customRequestHeaders:
          Authorization: "Basic {{ with nomadVar "nomad/jobs/traefik" }}{{ .kopia_basic_auth }}{{ end }}"
  routers:
    fallback:
      rule: "HostRegexp(`^.+$`)"
      entryPoints:
        - websecure
      middlewares:
        - auth
      service: noop@internal  # This router just applies middleware
      priority: 1
    traefik:
      rule: "Host(`traefik.othrayte.one`)"
      service: traefik
      middlewares:
        - auth
    nomad-ui:
      rule: "Host(`nomad.othrayte.one`)"
      service: nomad-ui
      middlewares:
        - auth
    consul-ui:
      rule: "Host(`consul.othrayte.one`)"
      service: consul-ui
      middlewares: 
        - auth
    unraid:
      rule: "Host(`unraid.othrayte.one`)"
      service: unraid
      middlewares:
        - auth
    kopia:
      rule: "Host(`kopia.othrayte.one`)"
      service: kopia
      middlewares:
        - auth
        - inject-kopia-basic-auth
    hass:
      rule: "Host(`hass.othrayte.one`)"
      service: hass
      middlewares:
        - auth
    hass-token:
      rule: "Host(`${hass_magic_token}-hass.othrayte.one`)"
      service: hass
    unifi-network:
      rule: "Host(`network.othrayte.one`)"
      service: unifi-network
      middlewares:
        - auth

  services:
    traefik:
      loadBalancer:
        servers:
          - url: "http://localhost:8081"
    nomad-ui:
      loadBalancer:
        servers:
          - url: "http://{{ env "NOMAD_HOST_IP_http" }}:4646"
    consul-ui:
      loadBalancer:
        servers:
          - url: "http://{{ env "NOMAD_HOST_IP_http" }}:8500"
    unraid:
      loadBalancer:
        servers:
          - url: "http://betelgeuse-seven-unraid.lan:80"
    kopia:
      loadBalancer:
        servers:
          - url: "http://betelgeuse-seven-unraid.lan:51515"
    hass:
      loadBalancer:
        servers:
          - url: "http://192.168.1.234:8123"
    unifi-network:
      loadBalancer:
        serversTransport: ignorecert
        servers:
          - url: "https://192.168.1.50:8443"
EOF

        destination = "local/configs/nomad.yml"
      }

      resources {
        cpu    = 100
        memory = 128
      }
    }

    volume "unraid_appdata_traefik" {
      type            = "csi"
      read_only       = false
      source          = "unraid_appdata_traefik"
      access_mode     = "multi-node-multi-writer"
      attachment_mode = "file-system"

      mount_options {
        mount_flags = ["file_mode=0600", "uid=1000", "gid=1000"]
      }
    }

    task "cloudflared" {
      driver = "docker"

      config {
        image = "cloudflare/cloudflared:latest"
        args = [
          "tunnel", "--no-autoupdate", "run"
        ]
      }

      template {
        data        = <<EOH
TUNNEL_TOKEN="{{ with nomadVar "nomad/jobs/traefik" }}{{ .cf_tunnel_token }}{{ end }}"
EOH
        destination = "secrets/tunnel.env"
        env         = true # Load the file as environment variables
      }
    }
  }
}
