I have docker stack running on a Raspberry Pi with docker-compose. It’s been going nicely for about a year now, but now I want to bring it to the next level.
The issue is, the stack contains a few services with website, which I access from the network. Obviously, that means I always have to remember the ports of each of those services, which has become tiresome after a while. And I do this from several devices in the network and sometimes several browsers on each device (I have my reasons :) ) so creating bookmarks isn’t an option.
So I thought I would solve this via DNS, as I already have pi-hole running in a container nicely as both a DNS and a DHCP server. For this to work I need, among others, the containers to listen to port 80.
Unfortunately, this is where the trouble shows.
The first thing I tried was to use ipvlan and macvlan networks. And it kind of works. But they still don’t solve the issue of remembering the ports, as the containers keep their current one. Port mapping doesn’t help here because of the reason below.
Another issue with this is that, as the containers also communicate to each other and there is a lot of existing configuration there, with IPs and ports, I have to connect them to 2 networks, a bridge for the inter-container communication, and an ipvlan for the outside communication. However, the port mapping is only one, and I don’t understand how it works when a container is connected to 2 networks. I thought this should have worked, but it didn’t.
So the next idea I had was to create several IPs on the host, then use the syntax “host_IP:port:container_port” to map as necessary.
So, for example, I have on the host
eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether dc:a6:32:07:f8:85 brd ff:ff:ff:ff:ff:ff
inet 10.0.0.10/24 brd 10.0.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet 10.0.0.50/24 scope global secondary eth0
valid_lft forever preferred_lft forever
inet 10.0.0.51/24 scope global secondary eth0
valid_lft forever preferred_lft forever
inet 10.0.0.52/24 scope global secondary eth0
valid_lft forever preferred_lft forever
inet6 fe80::185a:8f0e:78b0:a110/64 scope link
valid_lft forever preferred_lft forever
and then in docker-compose.yml I have (only relevant part):
grafana:
ports:
- “3000:3000”
- “10.0.0.50:80:3000”
nodered:
ports:
- “1880:1880”
- “10.0.0.51:80:1880”
Unfortunately, this throws a bunch of errors when I run docker-compose up -d
ERROR: for grafana Cannot start service grafana: driver failed programming external connectivity on endpoint grafana (b70ca36d6f0953ca16e046c7af561a638ce2fe537417600e6c7f7796fbf228c0): Error starting userland proxy: listen tcp4 10.0.0.50Recreating 922d1912d260_nodered … error
ERROR: for 922d1912d260_nodered Cannot start service nodered: driver failed programming external connectivity on endpoint nodered (6676c921fc83a1a521db50bce6ef128ec7811b4dae4d69cf0597b9f118199bfc): Error starting userland proxy: listen tcp4 10.0.0.51:80: bind: address already in use
ERROR: for grafana Cannot start service grafana: driver failed programming external connectivity on endpoint grafana (b70ca36d6f0953ca16e046c7af561a638ce2fe537417600e6c7f7796fbf228c0): Error starting userland proxy: listen tcp4 10.0.0.50:80: bind: address already in use
ERROR: for nodered Cannot start service nodered: driver failed programming external connectivity on endpoint nodered (6676c921fc83a1a521db50bce6ef128ec7811b4dae4d69cf0597b9f118199bfc): Error starting userland proxy: listen tcp4 10.0.0.51:80: bind: address already in use
ERROR: Encountered errors while bringing up the project.
It sounds a bit like docker can not share the same port even when it belongs to several IPs on the host. I have a limited understanding of this, but from what I read, they shouldn’t conflict. A NIC with several IPs assigned can handle all ports on each IP, as the port belongs to TCP and UDP. I googled this a lot and haven't been able to find any solution
I will appreciate any suggestions.