Embedded http iframe on HTTPS page

I'm currently using the Grafana module Powerwall-Dashboard to show local stats for my Tesla Power wall.

It uses an embedded iFrame which is over http, which seems to have this issue:

The problem does have a solution but I am unsure how to do this with Traefik. The solution the author wrote was for lighthttpd:

$SERVER["socket"] == "0.0.0.0:8675" {
     ssl.engine                  = "enable"
     ssl.cipher-list             = "aRSA+HIGH !3DES +kEDH +kRSA !kSRP !kPSK"
     ssl.pemfile                 = "/mnt/kd/ssl/webinterface.pem"
     ssl.ca-file                 = "/mnt/kd/ssl/https_ca_chain.pem"
     server.document-root        = ""
     proxy.server += ( "" =>
       ((
         "host" => "192.168.29.48",
         "port" => "8675"
       ))
     )
}

So now in my webpage, instead of pointing the iFrame at the pyPowerwall host, port 8675, I point it at my lighttpd host (as https), same port number, which is then proxy'd over to the non-secure pyPowerwall host. Works like a charm.

Replace the pem and ca-files to point at your own certificates, and the IP address of the pyPowerwall server to point at your server address.

Now for accessing weather data at port 8676 I ran into another problem which is that javascript / http requests (which I use to get the weather JSON data) to a different host may also get blocked by the browser with an Access-Control-Allow-Origin error. Again the web server has to be configured to permit that.

Again lighttpd has a config setting for that...

$SERVER["socket"] == "0.0.0.0:8676" {
    setenv.add-response-header = (
      "Access-Control-Allow-Origin" => "*"
    )
    ssl.engine                  = "enable"
    ssl.cipher-list             = "aRSA+HIGH !3DES +kEDH +kRSA !kSRP !kPSK"
    ssl.pemfile                 = "/mnt/kd/ssl/webinterface.pem"
    ssl.ca-file                 = "/mnt/kd/ssl/https_ca_chain.pem"
    server.document-root        = ""
    proxy.server += ( "" =>
    ((
      "host" => "192.168.29.48",
      "port" => "8676"
    ))
    )
}

And now my web page can retrieve weather data as well.

Just thought I would post this in case others attempt to do the same and run into similar problems.

My docker-compose:

services:
    grafana:
        image: grafana/grafana:9.1.2-ubuntu
        container_name: grafana
        hostname: grafana
        restart: always
        user: "1003:1003"
        volumes:
            - type: bind
              source: /mnt/container_data/grafana
              target: /var/lib/grafana
        ports:
            - target: 9000
              published: 9000
              # host_ip: 127.0.0.1
              mode: host
        env_file:
            - grafana.env
        depends_on:
            - influxdb
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.grafana.tls=true"
          - "traefik.http.routers.grafana.tls.certresolver=stepca"
          - "traefik.http.routers.grafana.rule=Host(`grafana.$MY_DOMAIN`)"
          - "traefik.http.routers.grafana.entrypoints=websecure"
          - "traefik.http.services.grafana.loadbalancer.server.port=9000"

    pypowerwall:
        image: jasonacox/pypowerwall:latest
        container_name: pypowerwall
        hostname: pypowerwall
        restart: always
        ports:
            - target: 8675
              published: 8675
              # host_ip: 127.0.0.1
              mode: host
        env_file:
            - pypowerwall.env

    weather411:
        image: jasonacox/weather411:latest
        container_name: weather411
        hostname: weather411
        restart: always
        user: "1000:1000"
        volumes:
            - type: bind
              source: ./weather
              target: /var/lib/weather
              read_only: true
        ports:
            - target: 8676
              published: 8676
              host_ip: 127.0.0.1
              mode: host
        environment:
            - WEATHERCONF=/var/lib/weather/weather411.conf
        depends_on:
            - influxdb

networks:
  default:
    external: true
    name: ${DEFAULT_NETWORK}

Have you checked your browsers developer tools networking tab what the invalid response looks like?

What do you want to achieve? Only Traefik needs to expose ports, all other services are normally only attached to a Docker network and Traefik forwards all requests throught the network, no ports exposed. loadbalancer.server.port tells Traefik which port the service uses internally. Traefik handles TLS/SSL termination. Your other services are missing labels, so Traefik won't recognize them.

Can you share your Traefik static and dynamic configuration and docker-compose.yml if used?

So the way this seems to work, is that pypowerwall proxies the frontend to localhost on 8675.

[proxy] [INFO] pyPowerwall [0.6.2] Proxy Server [t25] - HTTP Port 8675.

I guess the reason for this is so the iFrame in grafana can be the same no matter what IP/Domain someone uses for their powerwall. That means I think they have to be on the same domain for example I cannot have pypowerwall.$MY_DOMAIN or it will fail because its expecting it to be on the same domain as Grafana (just a different port).

It seems to be blocked

I tried this but I don't think it will work on a seperate domain. I need to proxy both ports 8675 and 9000. I think they need to have the same certificate.

    pypowerwall:
        image: jasonacox/pypowerwall:latest
        container_name: pypowerwall
        hostname: pypowerwall
        restart: always
        ports:
            - target: 8675
              published: 8675
              # host_ip: 127.0.0.1
              mode: host
        env_file:
          - pypowerwall.env
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.pypowerwall.tls=true"
          - "traefik.http.routers.pypowerwall.tls.certresolver=stepca"
          - "traefik.http.routers.pypowerwall.rule=Host(`pypowerwall.$MY_DOMAIN`)"
          - "traefik.http.routers.pypowerwall.entrypoints=websecure"
          - "traefik.http.services.pypowerwall.loadbalancer.server.port=8675"

    grafana:
        image: grafana/grafana:9.1.2-ubuntu
        container_name: grafana
        hostname: grafana
        restart: always
        user: "1003:1003"
        volumes:
            - type: bind
              source: /mnt/container_data/grafana
              target: /var/lib/grafana
        ports:
            - target: 9000
              published: 9000
              # host_ip: 127.0.0.1
              mode: host
        env_file:
            - grafana.env
        depends_on:
            - influxdb
        labels: 
          - "traefik.enable=true"
          - "traefik.http.routers.grafana.tls=true"
          - "traefik.http.routers.grafana.tls.certresolver=stepca"
          - "traefik.http.routers.grafana.rule=Host(`grafana.$MY_DOMAIN`)"
          - "traefik.http.routers.grafana.entrypoints=websecure"
          - "traefik.http.services.grafana.loadbalancer.server.port=9000"

With that I get: SSL_ERROR_RX_RECORD_TOO_LONG:

If I turn TLS off, then the only thing which works is the iframe, which is now on https://grafana.bsmt-srv1.home.arpa. So I think I need to not have both sets of labels there.

Looking at this part of the docs, specifically "Specifying more than one router and service per container". I made

    grafana:
        image: grafana/grafana:9.1.2-ubuntu
        container_name: grafana
        hostname: grafana
        restart: always
        user: "1003:1003"
        volumes:
            - type: bind
              source: /mnt/container_data/grafana
              target: /var/lib/grafana
        ports:
            - target: 9000
              published: 9000
              # host_ip: 127.0.0.1
              mode: host
        env_file:
            - grafana.env
        depends_on:
            - influxdb
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.grafana.tls=true"
          - "traefik.http.routers.grafana.tls.certresolver=stepca"
          - "traefik.http.routers.grafana.rule=Host(`grafana.$MY_DOMAIN`)"
          - "traefik.http.routers.grafana.entrypoints=websecure"
          - "traefik.http.services.grafana.loadbalancer.server.port=9000"
          - "traefik.http.routers.pypowerwall.rule=Host(`pypowerwall.$MY_DOMAIN`)"
          - "traefik.http.routers.pypowerwall.service=pypowerwall"
          - "traefik.http.services.pypowerwall.loadbalancer.server.port=8675"

The problem with that now is that only the pypowerwall is available on port 8675 and grafana is not (giving me 404).

So I should have labels for pypowerwall:8675 and grafana:9000? or not? I'm still a bit confused.

My Traefik config is:

services:
  traefik:
    image: traefik:latest
    container_name: traefik
    hostname: traefik
    networks:
      - traefik-proxy
    ports:
      - 80:80
      - 443:443
      - 8080:8080
    environment:
      LEGO_CA_CERTIFICATES: "/etc/traefik/certs/root.crt"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./traefik.yml:/traefik.yml:ro"
      - "/mnt/container_data/traefik/certs:/etc/traefik/certs:ro"
      - "acme:/etc/acme"
volumes:
  acme:

networks:
  traefik-proxy:
    external: true

And traefik.yml:

# https://github.com/DoTheEvo/Traefik-v2-examples
# https://doc.traefik.io/traefik/operations/dashboard/

log:
  level: INFO

# https://doc.traefik.io/traefik/operations/api
api:
  insecure: true
  dashboard: true

# https://doc.traefik.io/traefik/routing/entrypoints/
entryPoints:
  web:
   address: ":80"
#  http:
#     redirections:
#      entrypoint:
#        to: "websecure"
#        scheme: "https"
  websecure:
    address: ":443"

providers:
  docker:
    endpoint: "unix:///var/run/docker.sock"
    exposedByDefault: false

# Setup with ACME using custom resolver
# https://smallstep.com/docs/tutorials/acme-protocol-acme-clients#traefik
# https://doc.traefik.io/traefik/user-guides/docker-compose/acme-tls/
# https://doc.traefik.io/traefik/https/acme/
certificatesResolvers:
  stepca:
    acme:
      caServer: "https://tinyca.bsmt-rpi1.home.arpa/acme/acme/directory"
      email: "admin@home.arpa"
      storage: "/etc/acme/acme.json"
      httpChallenge:
        entryPoint: web

Yeah I'm aware of this. That's my main reason for using it.

What I am unsure about is how to define that the iFrame at 8675 is the pypowerwall container, but is still expected to be on the same domain as the grafana container.

It looks like that can only be set to one port.

So that would lead me to believe I need some labels under the pypowerwall container but not sure what.

If I disable https entirely ie:

pypowerwall:
        image: jasonacox/pypowerwall:latest
        container_name: pypowerwall
        hostname: pypowerwall
        restart: always
        ports:
            - target: 8675
              published: 8675
              # host_ip: 127.0.0.1
              mode: host
        env_file:
          - pypowerwall.env

    grafana:
        image: grafana/grafana:9.1.2-ubuntu
        container_name: grafana
        hostname: grafana
        restart: always
        user: "1003:1003"
        volumes:
            - type: bind
              source: /mnt/container_data/grafana
              target: /var/lib/grafana
        ports:
            - target: 9000
              published: 9000
              # host_ip: 127.0.0.1
              mode: host
        env_file:
            - grafana.env
        depends_on:
            - influxdb
        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.grafana.tls=false" # Disabled TLS to show that it works without:
          - "traefik.http.routers.grafana.tls.certresolver=stepca"
          - "traefik.http.routers.grafana.rule=Host(`grafana.$MY_DOMAIN`)"
          - "traefik.http.routers.grafana.entrypoints=web"
          - "traefik.http.services.grafana.loadbalancer.server.port=9000"

Seems to be the only way I can make it work:

Note I blanked out the cookies.

Hmm, i wasn't able to figure out a way around this.. anyone got any ideas?

For anyone else who stumbles across this, the solution is at

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.