So I have a Nginx running inside a docker container, I have a mysql running on localhost, I want to connect to the MySql from within my Nginx. The MySql is running on localhost and not exposing a port to the outside world, so its bound on localhost, not bound on the ip address of the machine.
Is there any way to connect to this MySql or any other program on localhost from within this docker container?
For Windows Machine :-
Run the below command to Expose docker port randomly during build time
In the above container list you can see the port assigned as 32768. Try accessing
You can see the mediawiki page
Simplest solution for Mac OSX
Just use the IP address of your Mac. On the Mac run this to get the IP address and use it from within the container:
As long as the server running locally on your Mac or in another docker container is listening to 0.0.0.0, the docker container will be able to reach out at that address.
If you just want to access another docker container that is listening on 0.0.0.0 you can use 172.17.0.1
Edit: I ended up prototyping out the concept on GitHub. Check out: https://github.com/sivabudh/system-in-a-box
First, my answer is geared towards 2 groups of people: those who use a Mac, and those who use Linux.
The host network mode doesn't work on a Mac. You have to use an IP alias, see: https://stackoverflow.com/a/43541681/2713729
What is a host network mode? See: https://docs.docker.com/engine/reference/run/#/network-settings
Secondly, for those of you who are using Linux (my direct experience was with Ubuntu 14.04 LTS and I'm upgrading to 16.04 LTS in production soon), yes, you can make the service running inside a Docker container connect to
localhost
services running on the Docker host (eg. your laptop).How?
The key is when you run the Docker container, you have to run it with the host mode. The command looks like this:
docker run --network="host" -id <Docker image ID>
When you do an
ifconfig
(you will need toapt-get install net-tools
your container forifconfig
to be callable) inside your container, you will see that the network interfaces are the same as the one on Docker host (eg. your laptop).It's important to note that I'm a Mac user, but I run Ubuntu under Parallels, so using a Mac is not a disadvantage. ;-)
And this is how you connect NGINX container to the MySQL running on a
localhost
.The CGroups and Namespaces are playing major role in the Container Ecosystem.
Namespace provide a layer of isolation. Each container runs in a separate namespace and its access is limited to that namespace. The Cgroups controls the resource utilization of each container, whereas Namespace controls what a process can see and access the respective resource.
Here is the basic understanding of the solution approach you could follow,
Use Network Namespace
When a container spawns out of image, a network interface is defined and create. This gives the container unique IP address and interface.
By changing the namespace to host, cotainers networks does not remain isolated to its interface, the process will have access to host machines network interface.
If the process listens on ports, they'll be listened on the host interface and mapped to the container.
Use PID Namespace By changing the Pid namespace allows a container to interact with other process beyond its normal scope.
This container will run in its own namespace.
By changing the namespace to the host, the container can also see all the other processes running on the system.
Sharing Namespace
This is a bad practice to do this in production because you are breaking out of the container security model which might open up for vulnerabilities, and easy access to eavesdropper. This is only for debugging tools and understating the loopholes in container security.
The first container is nginx server. This will create a new network and process namespace. This container will bind itself to port 80 of newly created network interface.
Another container can now reuse this namespace,
Also, this container can see the interface with the processes in a shared container.
This will allow you give more privileges to containers without changing or restarting the application. In the similar way you can connect to mysql on host, run and debug your application. But, its not recommend to go by this way. Hope it helps.
I doing a hack similar to above posts of get the local IP to map to a alias name (DNS) in the container. The major problem is to get dynamically with a simple script that works both in Linux and OSX the host IP address. I did this script that works in both environments (even in Linux distribution with
"$LANG" != "en_*"
configured):So, using Docker Compose, the full configuration will be:
Startup script (docker-run.sh):
docker-compose.yml:
Then change
http://localhost
tohttp://dockerhost
in your code.For a more advance guide of how to customize the
DOCKERHOST
script, take a look at this post with a explanation of how it works.Here is my solution : it works for my case
set local mysql server to public access by comment
#bind-address = 127.0.0.1
in /etc/mysql/mysql.conf.drestart mysql server
sudo /etc/init.d/mysql restart
run the following command to open user root access any host
mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;
create sh script : run_docker.sh
run with docker-composer