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.