I’m sure this has come up before so sorry for duplicates I’m still new to Docker. I’ve been experimenting with it for a few months and generally speaking its going well. I have run into an issues however.
Setup is a basic wired\wireless network. Ubuntu server running wired to the network and Docker running on the Ubuntu HOST. Internally the containers talk to each other on the bridge network and use the HOST IP (192.168.0.99 in my case) for “external” connectivity. From what I am reading this is all normal so far.
I have encountered a case where a container needs a port to be open to accept incoming requests (this port cannot be changed as its an industry used port like 25 for SMTP or 53 for DNS).
However the HOST machine (in this case Ubuntu) is also using this port so the container wont start. I need to keep the port on the HOST. I first thought I might be able to assign the container an IP in a new bridge network or by the IP its assigned on the default bridge network. From what I am reading it sounds like even though the HOST O\S is assigned the default GW IP for that bridge network its only accessible from within the bridge network. i.e. I cant ping the GW IP or the bridge IP’s from a machine on my physical network.
I tried running the container with HOST network but this just seems to use the HOST IP similar to bridge with port mapping.
I also run into a problem where I want to run 2 containers (using HOST IP is fine) however the service on these two containers require the same port.
Is there anyway to give a contain an IP from my wired network e.g. 192.168.0.100
tl;dr Add additional IPs to your host-computer, ensure that the service on the host-computer is only bound to of these IPs and bind the container’s ports to one of the added IP-addresses
Let’s assume (for better readability) that MySQL is the service that we are talking about.
You want to run dockerized MySQL-instances in parallel to one running directly on the host-computer and all of them should be accessible on Port 3306 (MySQL’s default port)?
My idea is to add additional IPs to your host-computer (i.e. 192.168.0.100, 192.168.0.101, …), configure the MySQL-instance running on your host-computer to only bind to 192.168.0.99:3306 and use each additional IP for one dockerized MySQL-instance (instead of docker run … -p 3306:3306 mysql:latest which binds to all available interfaces you can use docker run … -p 192.168.0.100:3306:3306 mysql:latest to bind only to one ip-address/interface).
Some other ideas that might be worth thinking about:
to access one container from another container you can use the container’s name without exposing the port (:3306 for MySQL) to the world outside of Docker. So you can name a container with docker run … –name mysql_2 mysql:latest (the same is possible using docker-compose.yml) and access it from another container using the hostname mysql_2. But here the dockerized MySQL is not accessible from the outside world.
If you use docker-compose you can use a links: within your client-service to be able to access the oder container using its service name (instead of knowning th container name)
for some protocols (http/https is a good example) you can use a loadbalancer in front of your dockerized webservers and let the loadbalancer decide according to the hostname requested by the clients which docker-container to use for this request. Docker Hub is a loadbalancer, that I’m using for a bunch of containerized webserver/webservices all to be served on the same port :443 but dependend on the hostname/path a different container is used for this request.
The search term you are looking for is “macvlan”. Give it a try.
Whatever you do, keep in mind that docker does “application virtualization”, if you are looking for a “os virtualization”, you might be better of with lxd. Or if you need hardware/server virtualisation: good old vm’s. Use whatever suits your requirements