Docker app to host mysql connection not working (host os & image = windows) - docker

My app from container wants to access Mysql from host machine, but is not able to connect. I googled a lot and tried many solutions but could not figure the error, could you please help me on this.
It is a windows image
IIS Website works
Website pages that use DB Connection does not work
Mysql DB is install in local machine (same pc where docker desktop is installed in)
Connection string in app uses 'host.docker.internal' with port 3306.
Tried docker uninstall, reinstall, image prune, container prune, WSL stop and start, host file commenting for below lines:
192.168.1.8 host.docker.internal
192.168.1.8 gateway.docker.internal
Below is the ipconfig from container
Nslookup and Ping commands:
network LS:
Docker Compose:
version: "3.9"
services:
web:
container_name: dinesh_server_container
image: dinesh_server:1
build: .
ports:
- "8000:80"
- "8001:81"
volumes:
- .\rowowcf:c:\rowowcf
- .\rowowcf_supportfiles:c:\rowowcf_supportfiles
- .\rowocollectionsite:c:\rowocollectionsite
environment:
TZ: Asia/Calcutta
Build image uses: FROM mcr.microsoft.com/dotnet/framework/aspnet:4.8
Host OS: Win 10 Pro 10.0.19043 Build 19043
HyperV is enabled too.
Tried the below too:
extra_hosts:
- "host.docker.internal:host-gateway"
Since it is on windows OS - host network mode is not supported (per my research)
EDIT:
MYSQL Bind Address is 0.0.0.0:

Maybe the problem is not directly related to docker but to mysql.
Please, try making your local mysql database listen in all the network interfaces of your host: by default it only listens in 127.0.0.1 and for this reason perhaps docker is unable to connect to it.
I am not sure about how to do it in Windows but typically you need to provide the value 0.0.0.0 for the bind-address configuration option in mysqld.cnf:
bind-address = 0.0.0.0
Please, consider review as well this article or this related serverfault question.
From a totally different point of view, I found this and this other related open issues in the Docker for Windows repository that in a certain way resembles your problem: especially the first one provides some workaround for the problem, like shutting down the wsl backend and restarting the docker daemon. I doesn't look like a solution to me, but perhaps it could be of help.

Related

Correct IP address to access web application in apache docker container

I have an easy apache docker setup defined in a docker-compose.yml:
services:
apache:
image: php:7.4-apache
command: /bin/bash -c "/var/www/html/startup.sh && exec 'apache2-foreground'"
volumes:
- ./:/var/www/html
- /c/Windows/System32/drivers/etc/hosts:/tmp/hostsfile
ports:
- "80:80"
From the startup.sh script I want to modify the hosts file from the host OS through the volume. Here I want to dynamically add an entry to resolve the hostname test.local to the ip address of the docker web application like so:
<ip-address> test.local
This way I should be able to open the application with the specified hostname http://test.local in my local browser.
Before writing the startup.sh script I wanted to try to manually open the application at http://172.19.0.2 via the containers IP address I got from
docker inspect apache_test
But the page won't open: ERR_CONNECTION_TIMED_OUT
Shouldn't I be able to access the application from that IP? What am I missing? Do I use the wrong IP address?
BTW: I am using Docker Desktop for Windows with the Hyper-V backend
Edit: I am able to access the application via http://localhost but since I want to add a new entry to the hosts file this is not the solution.
Apparently in newer versions of Docker Desktop for Windows you can't access (ping) your linux containers by IP.
Now there is some really dirty workaround for this that involves changing a .ps1 file of your Docker installation to get back the DockerNAT interface on windows. After that you need to add a new route in your windows routing table as described here:
route /P add <container-ip> MASK 255.255.0.0 <ip-found-in-docker-desktop-settings>
Then you might be able to ping your docker container from the windows host. I didn't test it though...
I found a solution to my original issue (resolution of test.local to container IP via hosts file) while reading one of the threads linked above here
That involves setting a free loopback IP in the 127.0.0.0/8 IP range in your ports section of the docker-compose.yml:
ports:
- "127.55.0.1:80:80"
After that you add the following to your hosts file:
127.55.0.1 test.local
And you can open your application at http://test.local
To do that for other dockerized applications too just choose another free loopback address.

Can't connect to WSL2 localhost server from WSL2 docker container

I am running a simple web server on https://0.0.0.0:4000 (accessible also as https://local.phx-cd.shoepping.at:4000 with mapping to 127.0.0.1 in Ubuntu hosts file) on my WSL2 Ubuntu. I can connect to it from both Ubuntu and Windows host - so far so good. But additionally, in my Docker for Win with WSL2 integration, I run a selenium chrome container which is connecting and testing stuff on that web server (using bridge), but it can't connect to it!
I connected to the container and tried to curl to the web server - connection refused. Since I have dual boot on my computer, I tried to switch to my Linux distro, run web server there and selenium in Linux Docker and connection to the local web server worked. So I think it has something to do with the WSL2.
My docker-compose.yaml (I left out my selenium hub config)
selenium-chrome-local:
image: selenium/node-chrome-debug:3.141.59
restart: always
ports:
- 5901-5902:5900
volumes:
- /dev/shm:/dev/shm
- ../../temp:/home/seluser/Downloads
depends_on:
- selenium-hub-local
environment:
- SCREEN_WIDTH=1920
- SCREEN_HEIGHT=1080
extra_hosts:
- "local.phx-cd.shoepping.at:10.99.99.1"
networks:
- selgrid
- dockerhost
networks:
selgrid:
dockerhost:
driver: bridge
ipam:
config:
- subnet: 10.99.99.0/24
Let me know if you need more config. Thanks.
Are you sure that the Ubuntu WSL2 instance is running bridged? By default, WSL2 instances run NAT'd (whereas WSL1 instances ran bridged). So, while yes, the Docker network is bridged, it still can't access the NAT'd WSL2 VM without some extra work.
I'm fairly sure that you are running into the root problem described in WSL issue #4150. If so, here are some things to try ...
Option #1 - Port forwarding to the WSL2 instance
There are several workarounds suggested in that GitHub issue, but the basics that would work for your case boil down to forwarding port 4000 from the Windows host interface to the WSL2 instance's private IP address. In PowerShell:
netsh interface portproxy delete v4tov4 listenport="4000" # Delete any existing port 4000 forwarding
$wslIp=(wsl -d Ubuntu -e sh -c "ip addr show eth0 | grep 'inet\b' | awk '{print `$2}' | cut -d/ -f1") # Get the private IP of the WSL2 instance
netsh interface portproxy add v4tov4 listenport="4000" connectaddress="$wslIp" connectport="4000"
Note that you'll need to do this after each reboot, or else set up a script that runs at logon as described in the GitHub issue (see this comment).
Option #2 - WSL1
I would also propose that assuming it fits your workflow and if your web app runs on it, you can simply use WSL1 instead of WSL2. You can try this out by:
Backing up your existing distro (from PowerShell or cmd, use wsl --export <DistroName> <FileName>
Import the backup into a new WSL1 instance with wsl --import <NewDistroName> <InstallLocation> <FileNameOfBackup> --version 1
It's possible to simply change versions in place, but I tend to like to have a backup anyway before doing it, and as long as you are backing up, you may as well leave the original in place.
Possible Option #3 - socat forwarding or tunnel
While I haven't tested your particular use case directly, I have played around with socat in WSL2 with success. From the looks of it socat could be used for port forwarding from WSL2 to (at the least) the Windows host (which would be accessible to the Docker container). See this comment an example on GitHub about a similar use-case as yours.
Possible Option #4 - WSL2 in bridge mode
The GitHub thread referenced above also has some details on how to enable bridge-mode on the WSL2 interface using Hyper-V. I believe this requires Windows 10 Professional or Enterprise. It also has to be done after each reboot, as with Option 1. Again, probably overkill for this case, if port forwarding or WSL1 can accomplish what you need.
Run this command on PowerShell as Administrator:
Replace {#requiredWindowsPort} with the port that will be used in the browser
Replace {#requiredWSL2Port} with the port running in WSL2 you want to connect to.
netsh interface portproxy add v4tov4 listenport={#requiredWindowsPort}
listenaddress=0.0.0.0 connectport={#requiredWSL2Port}
connectaddress=$($(wsl hostname -I).Trim());

Set docker toolbox container to receive information sended to host

I have a prototype that sends information to the host machine, and with Docker for Windows, the container grabs that information and everything works fine.
My docker-compose.yml file:
version: '3'
services:
middleware:
container_name: middleware
image: hyperloopupv:middleware
build: './receta'
ports:
- "5672:5672"
- "15672:15672"
- "1338:1338/udp"
- "5556:5556/udp"
But others from my team are using Docker Toolbox, and Docker Toolbox can not use localhost. I have tried to send the information from the prototype to the IP of the container(192.168.99.100), but the packets are lost.
Is there a way, that my team(using Docker Toolbox) and I(using Docker for Windows) can get this running without problems with the same compose file?
Thanks
Docker Desktop and Toolbox are completely different products. Docker Desktop runs on Hyper-V, Docker Toolbox on Virtualbox. Desktop is the actual product, Toolbox is the “legacy desktop solution”.
It is possible to manipulate its IP address. If you look a the docs under ‘Options’ you find an option called virtualbox-hostonly-cidr that you can use to manipulate the IP address when you create a new machine. But before you try this notice that it is called ‘hostonly’. This means it uses the Virtualbox Host-Only adapter and “the virtual machines cannot talk to the world outside the host since they are not connected to a physical networking interface” (from the Virtualbox docs).
So unfortunately it seems there is no simple solution to your problem.

Issue on connecting local mysql-workbench with docker mariadb

Currently I'm facing an issue trying to connect to my mariadb database running in an docker-container.
My Local Information:
OS: Windows 10
Docker-Toolkit
Trying to connect from MySql Workbench
Workbench config
Docker ps returns following:
Docker List
Testing the connection I only get the error message "Failed to Connect to MySQL at 127.0.0.1:3306 with user root. Can't connect to MySQL server on '127.0.0.1' (10061)".
Error Message
Trying to connect using MySql-Workbench from my virtual machine (Ubuntu) it works without problems.
Does someone have an idea how to solve that issue?
Update:
I started the docker container using docker-compose:
mysql:
image: mariadb:10.1
ports:
- "127.0.0.1:3306:3306"
environment:
MYSQL_DATABASE: databasename
MYSQL_ROOT_PASSWORD: pw
volumes:
- myproject-mysqldata:/var/lib/mysql
networks:
- back
logging:
options:
max-size: "25m"
max-file: "4"
Update 2:
Also tried to connect using Squirel with MariaDB Driver. Also doesn't work. It seems, that windows can't find the 127.0.0.1:3306.
"Telnet 127.0.0.1 3306" also responded with a not found message.
What I'm doing wrong here?
Is it maybe due to the docker-toolbox and Virtualbox usage?
Solution:
Hey all, thank you for your help. I tried to put my won information into a blog-post hoping that it can help someone: Solution
What I'm doing wrong here? Is it maybe due to the docker-toolbox and Virtualbox usage?
One of the Cons mentioned here: Should You Install Docker With the Docker Toolbox or Docker for Mac / Windows? states:
Docker Toolbox
Cons
Not a native solution, so you’ll need to access your Docker Machine’s IP address if you’re developing web apps. Example: 192.168.99.100 instead of localhost.
and I think the same is also mentioned here: Docker Toolbox - Localhost not working
In Toolbox, nothing will be localhost, and will be 192.168.99.100 by default, since it's running a Linux VM in VirtualBox.

Host network access from linked container

I've following coder-compose configuration:
version: '2'
services:
nginx:
build: ./nginx
links:
- tomcat1:tomcat1
- tomcat2:tomcat2
- tomcat3:tomcat3
ports:
- "80:80"
tomcat1:
build: ./tomcat
ports:
- "8080"
tomcat2:
build: ./tomcat
ports:
- "8080"
tomcat3:
build: ./tomcat
ports:
- "8080"
So, the question is, how to get access to the host network from the linked container(s):tomcat1, tomcat2, tomcat3. Here is the diagram:
Update
Seems, my diagram doesn't help much. Nginx is a load balancer, Tomcat 1-3 are application nodes. Deployed web. app needs to get access to internet resource.
Internet access is by default active on all containers (in bridge mode). All you need to check is if the http(s)_proxy variables are set if you are behind a proxy.
If your question if how to access docker host from a container (and not the reverse: access a container from the local docker host), then you would need to inspect the routing table of a container: see "From inside of a Docker container, how do I connect to the localhost of the machine?"
export DOCKER_HOST_IP=$(route -n | awk '/UG[ \t]/{print $2}')
There is a recent (June 2016) effort to add a adding a dockerhost as an entry in /etc/hosts of all running containers: issue 23177.
Update March 2020: this issue has been closed, and redirect to PR 40007: "Support host.docker.internal in dockerd on Linux"
This PR allows containers to connect to Linux hosts by appending a special string "host-gateway" to --add-host e.g. "--add-host=host.docker.internal:host-gateway" which adds host.docker.internal DNS entry in /etc/hosts and maps it to host-gateway-ip
This PR also add a daemon flag call host-gateway-ip which defaults to
the default bridge IP
Docker Desktop will need to set this field to the Host Proxy IP so DNS requests for host.docker.internal can be routed to VPNkit
This will be in Docker for Linux (and Docker Desktop, which runs the Linux daemon, although inside a lightweight VM).
Difference between this and the current implementation on Docker Desktop is that;
the current Docker Desktop implementation is in a part of the code-base that's proprietary (i.e., part of how Docker Desktop is configured internally)
this code could be used by the Docker Desktop team in future as well (to be discussed)
this PR does not set up the "magic" host.docker.internal automatically on every container, but it can be used to run a container that needs this host by adding docker run --add-host host.docker.internal:host-gateway
(to be discussed); setting that "magic" domain automatically on containers that are started could be implemented by adding an option for this in the ~/.docker/config.json CLI configuration file.

Resources