SensorsIot / IOTstack

Docker stack for getting started on IOT on the Raspberry PI
GNU General Public License v3.0
1.42k stars 303 forks source link

Change deconz web-socket port, currently 443 #748

Closed TomTom101 closed 6 months ago

TomTom101 commented 6 months ago

I'd like to change the default ws-port of deconz which by default is set to 443 – a imo terrible choice ;) – and play nice with Home Assistant.

HA documentation says:

The deCONZ integration uses the WebSocket port provided by the deCONZ REST API. If you’re running the deCONZ Docker container make sure that it properly configures the WebSocket port so deCONZ can report what port is exposed outside of the containerized environment. https://www.home-assistant.io/integrations/deconz/

Whatever "properly configure" means, I tried to map port 8443:443 in the docker compose and set the DECONZ_WS_PORT to 8443, hoping this would report, which port is used "outside of the containerized environment". However, HA still complains about the WS port not found. I want to avoid making any changes inside the container in order to having having to patch things after updates.

Any ideas how to accomplish that?

PS.: I want to add https-portal, maybe also a nice addition to IoTStack!?

Paraphraser commented 6 months ago

Well, I hope you don't mind but I'll start by responding to your editorialising with some of my own.

Other than not playing nice with HA, you didn't really elaborate on why you thought 443 was a poor choice. That kind of practical knowledge is "good stuff" for adding to the IOTstack doco.

I don't use deconz so I can't comment on the practical aspects of port choice but:

  1. It's been port 443 in IOTstack since deconz was added in Feb 2020 (ie you're the first to raise this); and
  2. Port 443 is what's recommended in the deconz documentation:

Even if deconz were only being added to IOTstack for the first time today, 443 would at least gain consideration if, perhaps not, implementation for the simple reason that the AdGuardHome service definition also claims 443.

In other words, right now, 443 is currently being used by both deconz and AdGuardHome. All by itself that's a reason (at least for me) to agree that something should be done to resolve that conflict.

No other service definition is currently using 8443 so it's as good a choice as any.

As I read the deconz documentation, I think the default service definition will need to look like this:

deconz:
  image: deconzcommunity/deconz
  container_name: deconz
  restart: unless-stopped
  ports:
    - "8090:80"
    - "8443:8443"
    - "5901:5900"
  volumes:
    - ./volumes/deconz:/opt/deCONZ
  devices:  # This list is replaced during the build process. Modify the list in "build_settings.yml" to change it.
    - /dev/null
  environment:
    - DECONZ_VNC_MODE=1
    - DECONZ_VNC_PASSWORD=%randomPassword%
    - DEBUG_INFO=1
    - DEBUG_APS=0
    - DEBUG_ZCL=0
    - DEBUG_ZDP=0
    - DEBUG_OTAU=0
    - DECONZ_WS_PORT=8443

Two changes are needed:

  1. Add the DECONZ_WS_PORT environment variable. That instructs the container to listen on internal port 8443.
  2. Map external port 8443 to internal port 8443 so that NAT will cause the host to listen on port 8443 and forward to the container's port 8443.

If you can give those changes a try and see if it works, we can think about moving to a pull request to make this the default.

TomTom101 commented 6 months ago

Thanks for the quick reply! I just think that claiming standard ports like 80 and 443 should be reserved for services that can only run on those ports, primarily a web server for example. Just like pihole needs to run on port 53, no other service should claim it! deconz could run on absolutely any port.

As for you suggestion, I left the port mapping "8443:443" untouched as I did not expect settingDECONZ_WS_PORT would actually lead to deconz actually using it but only used to "report what port is exposed outside of the containerized environment". I'll try that!

Thanks and Merry Christmas!! 🎄

TomTom101 commented 6 months ago

And the default port 80 is also remapped to 8090 – rightfully so! It is imo inconsistent to leave 443 as-is.

Paraphraser commented 6 months ago

Well, a number of containers want port 80 so we always steer clear of that when adding service definitions (unless, perhaps, the template being added was something like Apache and was intended to run a standard web site).

Otherwise, IOTstack's convention is first come, first served. deconz was first (Feb 2020) so it got 443. AdGuardHome was second (Apr 2021) and it should have been given something other than 443. That was my bad. Either I forgot to do the check or fouled-up.

Kinda why I think it's a good idea to resolve the conflict now - hiding my earlier mistake. 🥵

Anyway, I agree that it's inconsistent; just for a slightly different value of consistency.


I can see why "8443:443" might seem logical but I don't think it's going to work like that.

Think about it from the container's perspective.

The container only knows what's baked into the image, plus what it can learn from information sources like environment variables and (in some cases) configuration files in its persistent store. But, whatever a container knows and however it learns it, the only view it has is that of the container. It has zero knowledge of the host on which it is running and no way of learning anything about the host.

According to the deconz documentation:

I read that as saying that the "websockets service" (which, by definition, is running inside the container) listens to the container port 443 by default. If you use DECONZ_WS_PORT to set 8443 then the "websockets service" will listen on 8443 but that's still the container's port.

In other words, given the basic pattern:

ports:
  - "external:internal"

DECONZ_WS_PORT only defines the "internal" side:

ports:
  - "external:8443"

If there's a good reason why "what the container knows" (ie the internal port 8443) has to be the same as "what the rest of the world knows" then the only possible way of doing that is to make the external port the same number:

ports:
  - "8443:8443"

I hope that makes sense.

TomTom101 commented 6 months ago

Totally makes sense, you are absolutely correct, and I should have read the deconz docs for that part:

By default, the websockets service listens on port 443; only set this environment variable if you wish to change the listen port.

And it does work indeed, setting said env variable and map "8443:8443" – 443 is now avail, and Home Assistant still happy!

Thanks again!