Supervised docker-based installation with reverse proxy results in a 502 Bad Gateway error

Hi everybody!

I am performing a docker based installation on my server, via docker. If I run the following command, everything works:

docker run --name hassio_supervisor --privileged --security-opt apparmor=hassio-supervisor \
        --security-opt seccomp=unconfined -v /run/docker.sock:/run/docker.sock:rw \
        -v /run/dbus:/run/dbus:ro -v /run/udev:/run/udev:ro -v /etc/machine-id:/etc/machine-id:ro \
        -v /usr/share/hassio:/data:rw -e SUPERVISOR_SHARE="/usr/share/hassio" \
        -e SUPERVISOR_NAME=hassio_supervisor -e SUPERVISOR_MACHINE="raspberrypi3" \
        "homeassistant/armv7-hassio-supervisor"

the problem is that this does not support TLS or so, so I want to make it listen to the loopback interface and put it behind and nginx reverse proxy. Then, this is how I am running the container:

docker run --name hassio_supervisor --privileged --security-opt apparmor=hassio-supervisor \
        --security-opt seccomp=unconfined -v /run/docker.sock:/run/docker.sock:rw \
        -v /run/dbus:/run/dbus:ro -v /run/udev:/run/udev:ro -v /etc/machine-id:/etc/machine-id:ro \
        -v /usr/share/hassio:/data:rw -e SUPERVISOR_SHARE="/usr/share/hassio" \
        -e SUPERVISOR_NAME=hassio_supervisor -e SUPERVISOR_MACHINE="raspberrypi3" \
        -p 127.0.0.1:8123:8123 "homeassistant/armv7-hassio-supervisor"

And this is the config bit in nginx:

server {
    listen 443 ssl;
    server_name redacted.dyndns.site;
 
    # enable TLS
    ssl on;
    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1.2;
    ssl_ciphers "ECDH+AESGCM DH+AESGCM ECDH+AES256 DH+AES256 ECDH+AES128 DH+AES ECDH+3DES DH+3DES RSA+AESGCM RSA+AES RSA+3DES !aNULL !MD5 !DSS";

    # Enable HSTS (HTTP Strict Transport Security) for half a year
    add_header Strict-Transport-Security "max-age=15768000;includeSubDomains";

    # set the certificates
    ssl_certificate /etc/letsencrypt/live/redacted.dyndns.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/redacted.dyndns.site/privkey.pem;

    # enable OCSP stapling to speed up first connect
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/redacted.dyndns.site/chain.pem;

    location / {
        proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;        
        proxy_redirect off;
        proxy_pass http://127.0.0.1:8123/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off;
    }
}

And with this setup I am getting a “502 Bad Gateway” error… After a number of hours looking around I have run out of ideas. Has somebody faced this situation before?

Not really sure why you want to do it “manually” rather than using GitHub - home-assistant/supervised-installer: Installer for a generic Linux system

But anyway.HA doesn’t run inside the supervisor container. The supervisor launch the actual HA container, which listens on 8123. As you already bound 8123 to the supervisor, assuming the rest works as designed, HA couldn’t itself bind to 8123

Bottom line: remove -p 127.0.0.1:8123:8123

Indeed! But does this mean that my only solution is to set up the firewall at the OS level?

Firewall? You mean nginx?
You run it in a container?

No, what I mean is: I run nginx on the host, and I am forwarding the traffic from that nginx to the homeassistant container. Because homeassistant container is using the host network, it is not exposing a specific port, so I cannot force it to bind to 127.0.0.1. This means that I necessarily need to keep in mind this configuration bit (if you run docker container ps -a, it does not show homeassistant container as exposing any port… because is effectively speaking exposing all of them).

Mmm… Yeah, exactly. So 8123 will be taken on the host by HA.
With -p 127.0.0.1:8123:8123 you are trying to also listen to port 8123 on host, then forward to the supervisor container.

nginx is listening on 443, then forwarding to 8123 on the host, which, due to host networking, will be HA.

Bottom-line: You shouldn’t need to change anything on your HA docker setup from your 1st sample.

Do a netstat -tlnp to confirm:

  1. that 8123 is exposed by python/HA
  2. that 8123 is bound to 0.0.0.0 (or :::8123 in ipv6)