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.
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
@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
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
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 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:
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:
- Using the docker networks will disable “network_mode: host” for home assistant.
- 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.
Macvlan solves this