When you run a container on a Docker bridge network, it will be operating on a private virtual network on your Docker host server. Your Docker host will be able to ping each container, but your LAN hosts won't.
When you restart your host, unless you have Docker dependencies setup (i.e. some rudimentary start order) you may find that your containers change IP address on the bridge network. This is fine if you're hiding things behind URLS and Traefik routers (Traefik will auto-update) but if you have something obtuse that wants to use IP, this can cause problems when that IP changes.
The specific use case that triggered this was the author's use of OpenRemote running natively on the host, which uses HTTP calls to update EmonCMS. OpenRemote uses Tomcat, which cannot (without severe bother) communicate with HTTPS hosts - so it was setup to communicate with the Docker bridge IP natively - which caused problems for home automation if that IP changed.
This script will enable your server to update it's /etc/hosts file so that it can resolve containers by name locally. This can also be useful if you're using your Docker host as a DNS server. If you're using pihole (as a container) then you can extend this to run on
Note: This may be considered a pointless article by some, as defining your own Docker bridge network, rather than using the natively defined 'bridge' network can get around this - but either way it's a fun solution to a specific problem and may be useful for someone out there to extend
Copy and paste the following into a script somewhere on your Docker host (as root), i.e. /usr/sbin/updatedockerdns.sh
Note: You can update MinContainers to be one less than (or equal to) the number of containers you should typically have running. The script will basically loop until your Docker instance has that many containers running before it updates /etc/hosts.
Now ensure your script is executable, by typing
Copy/paste the following into /etc/systemd/system/dockernetcheck.service
Amend the location of your updatedockerdns.sh script if you put it somewhere else....
You've now created a service called dockernetcheck that will run at boot, and wait until it seems 19 containers running. It will then parse the output of docker ps to find all the bridge IP addresses, create a temporary file of hosts (with a .local suffix) and their respective IPs, before adding them to /etc/hosts
It puts the new host/IP mappings within a DOCKER block in /etc/hosts, so it can update them again if the script is manually run.
Depending on how often you reboot, or play around with containers, consider having CRON run the script periodically.
Depending on how complicated you've made your DNS setup, you may find your system appears to "hang" at boot - you'll get to a login prompt but docker may not start.
If you run
...and see any reference to "queued jobs" then you should run
If you see dockernetcheck.service is running, then docker is probably stuck pending...you can check this by running
If no images are returned, then it's definitely stuck. To remedy this, run:
We're currently checking if we need to move the dockernetcheck.service dependency to run after multi-user.target.
NB : This MAY also stop some shutdowns, as the service won't cleanly close off with DNS off. Again, not fatal, but we're checking.