I have a docker container running jenkins. As part of the build process, I need to access a web server that is run locally on the host machine. Is there a way the host web s
For docker-compose
using bridge networking to create a private network between containers, the accepted solution using docker0
doesn't work because the egress interface from the containers is not docker0
, but instead, it's a randomly generated interface id, such as:
$ ifconfig
br-02d7f5ba5a51: flags=4163 mtu 1500
inet 192.168.32.1 netmask 255.255.240.0 broadcast 192.168.47.255
Unfortunately that random id is not predictable and will change each time compose has to recreate the network (e.g. on a host reboot). My solution to this is to create the private network in a known subnet and configure iptables
to accept that range:
Compose file snippet:
version: "3.7"
services:
mongodb:
image: mongo:4.2.2
networks:
- mynet
# rest of service config and other services removed for clarity
networks:
mynet:
name: mynet
ipam:
driver: default
config:
- subnet: "192.168.32.0/20"
You can change the subnet if your environment requires it. I arbitrarily selected 192.168.32.0/20
by using docker network inspect
to see what was being created by default.
Configure iptables
on the host to permit the private subnet as a source:
$ iptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT
This is the simplest possible iptables
rule. You may wish to add other restrictions, for example by destination port. Don't forget to persist your iptables rules when you're happy they're working.
This approach has the advantage of being repeatable and therefore automatable. I use ansible's template
module to deploy my compose file with variable substitution and then use the iptables
and shell
modules to configure and persist the firewall rules, respectively.