NathanVaughn / powerpanel-business-docker

Docker image for CyberPower PowerPanel Business
https://hub.docker.com/r/nathanvaughn/powerpanel-business
MIT License
24 stars 14 forks source link

404 with Traefik #32

Open mattsnowboard opened 2 weeks ago

mattsnowboard commented 2 weeks ago

I use Traefik as a reverse proxy and couldn't get this working yet.

Here are the hopefully relevant parts of my docker compose file:

version: "3.9"

networks:
  default:
    driver: bridge
  t2_proxy:
    name: t2_proxy
    driver: bridge
    ipam:
      config:
        - subnet: $T2_PROXY_SUBNET

volumes:
  powerpanel_app_data:
    driver: local

services:
  # UPS
  powerpanel:
    image: ghcr.io/nathanvaughn/powerpanel-business:both-latest
    container_name: powerpanel
    networks:
      - t2_proxy
    # build: .
    ports:
      # Ports: ???, http, https, ???, snmp, snmp
      # See https://dl4jz3rbrsfum.cloudfront.net/documents/CyberPower_UM_PowerPanel-Business-490.pdf
      - 2003:2003
      - 3052:3052 # HTTP access, see traefik settings below
      - 53568:53568/tcp # HTTPS access
      - 53566:53566/udp
      - 161:161/udp
      - 162:162/udp
    devices:
      # sharing /dev/usb is sufficient for debian and ubuntu,
      # but other distributions might also need access to
      # /dev/bus/usb/*
      - "/dev/usb:/dev/usb"
      # - "/dev/bus/usb:/dev/bus/usb"
    restart: unless-stopped
    volumes:
      - powerpanel_app_data:/data
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    labels:
      - "traefik.enable=true"
      ## HTTP Routers
      - "traefik.http.routers.powerpanel-rtr.entrypoints=https"
      - "traefik.http.routers.powerpanel-rtr.rule=Host(`ups.$DOMAINNAME`)"
      ## Middlewares
      - "traefik.http.routers.powerpanel-rtr.middlewares=chain-authelia@file"
      - "traefik.http.routers.powerpanel-rtr.middlewares=powerpanelHeaders@file"
      ## HTTP Services
      - "traefik.http.routers.powerpanel-rtr.service=powerpanel-svc"
      - "traefik.http.services.powerpanel-svc.loadbalancer.server.port=3052"

Traefik middleware to set origin (hopefully):

File Edit Options Buffers Tools Help
http:
  middlewares:
    powerpanelHeaders:
      headers:
        customRequestHeaders:
          Origin: ""

But when I visit "https://ups.MYDOMAIN" I get redirected to https://ups.MYDOMAIN/local and get a 404 response. Hopefully I'm just missing something simple

NathanVaughn commented 2 weeks ago

I have had nothing but problems with PowerPanel myself. I use Traefik as well, and what I ended up doing was to run a nginx container alongside to do the request header rewrites:

events {}

http {
    server {
        listen 80;
        listen [::]:80;

        access_log /var/log/nginx/reverse-access.log;
        error_log /var/log/nginx/reverse-error.log;

        location / {
            proxy_pass http://{{ env "NOMAD_ADDR_powerpanel_http_port" }};
            proxy_set_header Origin '';
        }
    }
}

With that, I find that everything seems to work correctly, and I get the login page and eventually redirected to https://powerpanel.mydomain/local/dashboard

mattsnowboard commented 2 weeks ago

Ah, can you share your docker compose which sets up nginx in that way? I have a couple nginx containers for static content, but don't have the nginx file like you have above. I assume if I get it working through nginx, I can just expose the nginx part in traefik

mattsnowboard commented 2 weeks ago

Interestingly I tried "local-490" instead of "both-latest" and got this nginx config similar to the above working.

But, I'm on Debian so I think my usb settings are correct, but the dashboard says: "Local communication with the device has been lost."

I tried "both-490" and it wouldn't load the web page at all.

mattsnowboard commented 2 weeks ago

One more interesting note:

If I run lsusb from the container I get:

Bus 002 Device 002: ID 174c:3074 Asmedia ASM107x Bus 002 Device 001: ID 1d6b:0003 Linux 5.10.0-28-amd64 xhci-hcd xHCI Host Controller Bus 001 Device 005: ID 0764:0601 CPS CP1500PFCLCDa Bus 001 Device 002: ID 174c:2074 Asmedia ASM107x Bus 001 Device 004: ID 26ce:01a2 ASRock LED Controller Bus 001 Device 001: ID 1d6b:0002 Linux 5.10.0-28-amd64 xhci-hcd xHCI Host Controller

But on the host I get:

Bus 002 Device 002: ID 174c:3074 ASMedia Technology Inc. ASM1074 SuperSpeed hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 005: ID 0764:0601 Cyber Power System, Inc. PR1500LCDRT2U UPS Bus 001 Device 002: ID 174c:2074 ASMedia Technology Inc. ASM1074 High-Speed hub Bus 001 Device 004: ID 26ce:01a2 ASRock LED Controller Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

mattsnowboard commented 2 weeks ago

Well, adding "/dev/bus/usb" worked! I guess the instructions about Debian not needing it were incorrect. I guess I'm unblocked with local-490

NathanVaughn commented 2 weeks ago

Glad you got it sorted out. I use Nomad + Consul so this is my current setup:

job "powerpanel_job" {
  datacenters = ["dc1"]
  type        = "service"
  constraint {
    attribute = "${meta.type}"
    value     = "head_node"
  }

  group "powerpanel_group" {
    count = 1

    network {
      port "powerpanel_http_port" {
        to = 3052
      }
      port "nginx_port" {
        to = 80
      }
      // port "powerpanel_watchdog_port" {
      //   static = 2003
      // }
      // port "powerpanel_unknown_port" {
      //   static = 53566
      // }
    }

    task "nginx_task" {
      driver = "docker"

      service {
        name = "powerpanel-nginx"
        port = "nginx_port"

        tags = [
          "traefik.enable=true",
          "traefik.http.routers.powerpanel.rule=Host(`powerpanel.MYDOMAIN`)",
          "traefik.http.routers.powerpanel.service=powerpanel-nginx",
          "traefik.http.routers.powerpanel.entrypoints=secure",
          "traefik.http.routers.powerpanel.tls=true",
          "traefik.http.routers.powerpanel.tls.certresolver=le",
          "traefik.http.routers.powerpanel.tls.domains[0].sans=*.MYDOMAIN",
          "traefik.http.routers.powerpanel.middlewares=authentik"
        ]

        check {
          type     = "http"
          path     = "/"
          interval = "30s"
          timeout  = "10s"
        }
      }

      config {
        image   = "docker.io/library/nginx:latest"
        volumes = ["local/nginx.conf:/etc/nginx/nginx.conf"]
        ports   = ["nginx_port"]
      }

      template {
        data        = file("powerpanel/nginx.conf")
        destination = "local/nginx.conf"
      }

      resources {
        memory = 100
      }

      restart {
        attempts = 5
        delay    = "60s"
      }
    }

    task "powerpanel_task" {
      driver = "docker"

      config {
        image      = "ghcr.io/nathanvaughn/powerpanel-business:both-486"
        ports      = ["powerpanel_http_port"]
        privileged = true

        // due to how bind mounts overwrite the contents in the container
        // only volume mount will work. Even bind mount of db_local directory refused
        // to work
        mount {
          type     = "volume"
          source   = "powerpanel-data"
          target   = "/usr/local/PPB/"
          readonly = false
        }

        mount {
          type     = "bind"
          source   = "/etc/localtime"
          target   = "/etc/localtime"
          readonly = true
        }

        mount {
          type     = "bind"
          source   = "/etc/timezone"
          target   = "/etc/timezone"
          readonly = true
        }
      }

      env {
        ENABLE_LOGGING = "false"
      }

      resources {
        cpu    = 3000
        memory = 4000
      }

      restart {
        attempts = 5
        delay    = "60s"
      }
    }
  }
}