Nginx docker IP not a trusted proxy to HA

Docker would take care of the bridging. All you should need to do is create the docker network and then adjust your docker-compose for the containers you want to be part of this network.

so - ?? - where is the gateway , 172.0.3.1 ??

and if I use my ‘own’ network in each docker-compose, what does that actually do , do I still need the ports mappings for example?

port mapping is for external devices to connect to port in docker container. it opens port into docker network same as you opening port in your router

if you create a docker network nothing can access it except another container in that docker network.

Gateway has no meaning here. its containers on a network connecting to each other directly.

Your original problems was compose created a new network with new IPs and removed the old. to prevent this you will create a docker network, not managed by compose, that will survive compose up/down (stack restarts)

when this new network is created you just need to tell compose to use that network


service:
  homeassistant:
    hostname: homeassistant
    networks:
      that_network_you_made:
      zwavejs: #this is a network that was created to use with a seperate zwavejs container
  nginx:
    hostname: nginx
    networks:
      that_network_you_made:
        ipv4_address: 172.18.0.4 #give it a static ip on that network you created
networks:
  that_network_you_made:
    external: true
  zwavejs:
    external: true

with this nginx will keep a static IP on the network and you can just trust the single IP.
Also, in nginx you can reach HA at homeassistant:8123. You cannot trust hostnames but HA will still be able to ping nginx at nginx. And as an addional example if you have a seperate zwavejs container and created a network for that homeassistant could be seen on that network but nginx would not since that network was not defined for it

if you don’t use portainer, use portainer. it makes all this easier to do.

2 Likes

excellent. i understand now. and reading the docker guides it NOW makes sense. thank hou so.much @tmjpugh

that’s EXACTLY what I’m after… a segregated networkjsu for all the docker containers

portainer? i will google that…

Q1…
so i suppose this is the inverse of the insanley insecure network_mode: host

Q2.
whats difference between this

networks:
  that_network_you_made:
    external: true
  zwavejs:
    external: true

and this...

networks:
   external:
      that_network_you_made
      zwavejs

both seem to be accepted

Q3. so to share port 443 across two contIners would it be…


ports:
- 127.0.0.1:443:127.0.0.1:443

…to limit connections only from the host (dockers)
EDIT: nope, if i create my own docker network and connect dockers to it…ports are all accessible inter-containers … yes?

yes. this is just the standard docker bridge.

There are comments on both side re: host networking. I dont think it is insecure, just dont like to give unnecessary access. For years I avoided it for HA. In the end i created mac vlan and prefer this. macvlan also allows discovery, mdns and other stuff.

unsure. not sure if that is option. used docker 7 years and only 2 day ago started using compose. I believe your 2nd option is just wrong but truly do not know.

NO. Docker containers on same docker network can access all container ports. if HA and NGINX are both using a docker network called “smarthome” and you defined HA hostname as “homeassistant”. NGINX could access HA at port 443 using “homeassistant:443”. No need to use IP and best you dont as IP can change with exception being my example for NGINX above where a static IP is defined for the network

looks like you figured out #3 on your own

1 Like

@tmjpugh
tha nk younfor sharing your experience and inight. it is all working now after a few.tweaks. and thanks tonyou the topic is easier to understand
:ok_hand:

Well, I did as you said, created my own network 'daz_docker_network"

then I have this yaml:


version: '3.4'
services:
  energenie_mqtt_client:
    image: gpbenton/engmqttclient:1.0.0
    restart: unless-stopped
    container_name: energenie_mqtt_client
    privileged: true
    working_dir: /opt/energenie_mqtt_client/
    command: ["-h", "localhost"]
    volumes:
      - $PWD/engMQTTClient/log4c:/etc/log4c
      - /dev/mem:/dev/mem
    environment:
      LOG4C_RCPATH: '/etc/log4c/log4crc'
      LOG4C_PRIORITY: info
      LOG4C_APPENDER: stdout
    networks:
      -  daz_docker_network

  mosquitto:
    container_name: mosquitto
    restart: unless-stopped
    image: eclipse-mosquitto
    volumes:
      - ./config:/mosquitto/config
      - mosquitto_persistence_database:/mosquitto/data
      - /etc/localtime:/etc/localtime:ro
    networks:
      - daz_docker_network

volumes:
  mosquitto_persistence_database:

networks:
  daz_docker_network:
    external: true
    driver: bridge

but it doesnt work. Each service cannot see each other.

If I add network_mode: host then all is well.

What have I done wrong?

Presuming you manually created daz_docker_network, remove “driver: bridge”

If you Did Not manually create daz_docker_network, remove “external: true”

EDIT
Just to be clear, only the 2 service above will work on daz_docker_network based on above

1 Like

Mmmm…i created using the instruction above

…using daz_docker_network as the name

so bridge is incorrect? extrrnal is correct? and if I use the same network config in other docker_-compiose files, why will only these two services see it nexus i want that network to be for all containers.?

yes. Keep external: true and remove driver: bridge

You can add any container to the network at docker run, adding it in compose, or using docker network connect command.

All working. This is the final config:

version: '3.4'
services:
  energenie_mqtt_client:
    image: gpbenton/engmqttclient:1.0.0
    restart: unless-stopped
    container_name: energenie_mqtt_client
    privileged: true
    working_dir: /opt/energenie_mqtt_client/
    command: ["-h", "172.0.1.100"]
    volumes:
      - $PWD/engMQTTClient/log4c:/etc/log4c
      - /dev/mem:/dev/mem
    environment:
      LOG4C_RCPATH: '/etc/log4c/log4crc'
      LOG4C_PRIORITY: info
      LOG4C_APPENDER: stdout
    networks:
      - daz_docker_network

  mosquitto:
    container_name: mosquitto
    restart: unless-stopped
    image: eclipse-mosquitto
    volumes:
      - ./config:/mosquitto/config
      - mosquitto_persistence_database:/mosquitto/data
      - /etc/localtime:/etc/localtime:ro
    networks:
      daz_docker_network:
        ipv4_address: 172.0.1.100

volumes:
  mosquitto_persistence_database:

networks:
  daz_docker_network:
    external: true

Where I was going wrong was using localhost as the argument to the command in the mosquito client. After reading the docker network reference and only on the back of your help and explanations, did I grasp that localhost is the container and not the docker host. So I had to assign an IP to the broker and use that in the client. I also had to set the IP as a listener in mosquitto.conf

All good now. Thanks muchly

However, MQTT/HA problem…
I have locked in the IP to the broker in this docker. I could not take the docker to another setup and have it working. So the issue is that in daz_docker_network the mqtt broker for home assistant is in the container whose network IP is 172.0.1.100. I dont want to have to configure HA to ‘see’ the broker so can I set the broker listener to 0.0.0.0 - i.e. any IP in daz_docker_network can connect at default port 1883?
(well what I mean is - is it ok? or bad practice? I mean it seems to work fine as I tried it but…?)
and i probably should move mosquitto to its own container.

EDIT: I do not believe I can get away without using the broker IP in HA MQTT integration. I was using localhost but of course that is scoped only to the container HA is running in. Kind of need a reference to the docker network as docker_local or something?? Then I can use docker_local:1883 in the mqtt integration and if the IP changes for the broker then it wont break anything. Not sure if this is possible though?

If you put all the containers in the same bridge network, then you can access them by name rather than by ip address. So with this docker-compose HA references MQTT using “mqtt” as the host name and “zwave” as the zwave host name. Also I’d recommend specifying specific versions of container images, such that an upgrade is a decision you make by changing the version vs just happens when you rebuild your docker. You can put all these constants in a .env file, so that’s the one place you go to change versions, subnets, etc.

version: '3'

networks:
  local_network:
    ipam:
      driver: default
      config:
        - subnet: ${SUBNET}.0/24

        
services:
  ha:
    container_name: ha
    image: homeassistant/home-assistant:${HA_VERSION}
    volumes:
      - ${DOCKER_FOLDER}/${HA_FOLDER}/config:/config
      - /etc/localtime:/etc/localtime:ro
    restart: unless-stopped
    environment:
      PROXY_IP: ${SUBNET}.1
      TZ: America/New_York
    networks: 
      local_network:
        ipv4_address: ${SUBNET}.2
    depends_on:        
      - zwave
      - mariadb
    ports:
      - 8123:8123
      - 1400:1400
      - 1401:1401
  zwave:
    container_name: zwave
    image: zwavejs/zwave-js-ui:${ZWAVE_VERSION}
    volumes:
      - ${DOCKER_FOLDER}/${ZWAVE_FOLDER}:/usr/src/app/store
      - /etc/localtime:/etc/localtime:ro
    devices:
      - /dev/ttyACM0:/dev/ttyACM0
    restart: unless-stopped
    environment:
      TZ: America/New_York
    networks: 
      local_network:
        ipv4_address: ${SUBNET}.3
    ports:
      - 3000:3000
      - 8091:8091
        
  mqtt:
    container_name: mqtt
    image: eclipse-mosquitto:${MQTT_VERSION}
    # chown 1883:1883
    volumes:
      - ${DOCKER_FOLDER}/${MQTT_FOLDER}/config:/mosquitto/config
      - ${DOCKER_FOLDER}/${MQTT_FOLDER}/log:/mosquitto/log
      - ${DOCKER_FOLDER}/${MQTT_FOLDER}/data:/mosquitto/data
    restart: unless-stopped
    user: "1883:1883"
    environment:
      TZ: America/New_York
    networks: 
      local_network:
        ipv4_address: ${SUBNET}.6
    ports:
      - 1883:1883
      - 9001:9001
       
  mariadb:
    container_name: mariadb_ha
    image: mariadb:10.11.2
    volumes:
      - ${DOCKER_LOCAL_FOLDER}/${MARIADB_FOLDER}:/var/lib/mysql
      - ${DOCKER_LOCAL_FOLDER}/mariadb_conf:/etc/mysql/conf.d
      - /etc/localtime:/etc/localtime:ro
      
    restart: unless-stopped
    environment:
      MARIADB_ROOT_PASSWORD: ${MARIADB_PWD}
      MARIADB_MYSQL_LOCALHOST_USER: "yes"
      MARIADB_MYSQL_LOCALHOST_GRANTS: "yes"
      MARIADB_AUTO_UPGRADE: "yes"
      MARIADB_DISABLE_UPGRADE_BACKUP: "yes"
      TZ: America/New_York
      PUID: 1037
      PGID: 100
    networks: 
      local_network:
        ipv4_address: ${SUBNET}.4
    ports:
      - 3316:3306
  phpmyadmin:
    container_name: phpmyadmin
    image: phpmyadmin:5.2.1
    restart: unless-stopped
    environment:
      - PMA_HOST=mariadb_ha
    hostname: phpmyadmin
    domainname: phpmyadmin.st.home.arpa
    networks: 
      local_network:
        ipv4_address: ${SUBNET}.5
    ports:
      - 8088:80

a display of rather impressive docker skill - but I don’t see where you are referring to dockers by name rather than IP… can you post just the salient lines :slight_smile: please

Shell into one of your docker containers and try to ping by name, you will see it resolves to an ip address as docker runs its own DNS for you.

Here is how I have MQTT in HA configured. It just uses the host name mqtt which the docker dns resolves to the appropriate container ip.

I usually point these to direct IP addresses rather than relying on mDNS. You can use the IP address to the host (ie, your 192.168.x.x) there. I have reserved this IP (eth0 from my host) on my router, so this remains constant.

ah, you mean use the container name in the host config. i thought to were talking asmr about using names inside containers to reference IPs in other containers

what’s mDNS do that DNS doesn’t btw ?

I’m not sure I understand your question. You do not need a host file with host name and ip addresses. Anywhere in the application configuration that requires a host name you can use the container name and docker DNS will resolve it to the ip address - or you can just use the ip address.

Mdns is a local discovery protocol for finding stuff like printers, music players, etc. It only works on a LAN segment and does not work across routers. When using a docker bridge network, there is the equivalent of a router running between the bridge and your host network. So for example, the HA Sonos integration does not discover stuff when running in a bridge network and hence you need to configure the ip addresses of those devices…

I’m not sure i understand your response​:laughing::laughing:
never mind
soberingly, another topic i dont understand abs need to learn 🫠

This post is gold and extremely helpful.

Before I was getting Bad 400 and 502 errors - all caused by hosting Home Assistant and Nginx on the same device.

A few points to add:

  1. Using the docker networks will disable “network_mode: host” for home assistant.
  2. Disabling host networking will break network discovery on home assistant

I couldn’t poke enough port holes in the container to overcome the problems without network discovery, so ultimately I had to migrate from nginx and certbot containers to swag.

1 Like

Macvlan solves this