Access docker-machine VM ports without port forwarding - docker

I'm trying to learn Docker and so far I have run into a lot of "work arounds" that are needed in docker-machine but not in boot2docker.
My current issue is accessing my docker containers from my host.
I have my Windows host, running a VM created with docker-machine, and inside that docker VM I'm running a simple nginx server container.
The nginx container is ran to expose it's 80 port to the docker-machine's 8000.
docker run -d -p 8000:80 nginx
And what I'm trying to achieve is being able to open this server from my Windows using a browser.
If I in Windows use curl (Git bash, not ssh-ed into the docker-machine VM) using the IP that docker-machine ip gives me, then it works. But using my browser doesn't (I'm using Microsoft Edge currently), I can get the browser to work if I set up a NAT port forwarding.
curl $(docker-machine ip dev):8000
As I've read it should be possible to access the VM ports without specifying port forwarding rules for every port, that VirtualBox should expose and forward those automatically.
What am I doing wrong or do I have to specify port forwarding rules for every port between my VM and host OS that I want to use?

After another day of digging I had the wild and crazy idea to try another browser and it works fine.
So for anyone running into this issue and you're using Microsoft Edge (to try it out like me), switch browser. Chrome and even old IE works fine.

In Bash, $(docker-machine ip dev) means "run the command docker-machine ip dev, take the output of that command and insert it into the command-line here".
If you run
docker-machine ip dev
in your shell, it will print an IP address which you can use in your web browser.
If you put this address in /etc/hosts (or your platform's analog) you can use a friendly alias for the IP address.

In my case, it was because my browser was configured with a proxy pac (Proxy_auto-config file) which did not include 192.169.x.y internal boot2docker machines ips.
That means:
the browser tries to contact the enterprise proxy (and that fails),
while a regular CMD shell session, with a NO_PROXY environment variable set to 192.168.x.y, would allow a curl http://192.168.x.y/... to work without a glitch.

Related

Docker nodejs server running in VirtualBox guest OS (Ubuntu Server 20.04): access via host (Win10) localhost

I'm using docker inside VirtualBox (Ubuntu Server 20.04), since I cannot use Docker Desktop in the host (Windows 10).
I have a docker nodejs container on port 3000. In my host I can access it through 192.168.56.110:3000, where 192.168.56.110 is the IP address of the VM but I need to access it through localhost:3000.
The setup is of course similar to a docker-toolbox installation (as in this question), for which I've found that the host localhost also does not work, to put it simple.
I've tried to map localhost in Windows 10, as suggested in a few answers like this one adding to C:\Windows\System32\Drivers\etc\hosts:
192.168.56.110 localhost
192.168.56.110 dev.com
But while dev.com works right away as expected, localhost doesn't.
Is there a workaround?
When I run an Angular development server in the guest, I can access it via localhost:4200 from the host but it is not completely clear to me what happens behind the scenes. Side question, how does ng serve lead to the "redirection" of localhost in the host OS?
Run as administor a windows command prompt and enter:
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=3000 connectaddress=<replace with docker ip address> connectport=3000
To confirm, run
netsh interface portproxy show all
Good luck.

How can I access a service running on WSL2 from inside a Docker container?

I am using Windows 10 1909 and have installed WSL2, using Ubuntu 20.04, the 19.03.13-beta2 docker version, having installed Docker for Windows Edge version using the WSL2 option. The integration is working pretty great, but I have one issue which I cannot solve.
On the WSL2 instance, there are services running, exposing some ports (3000, 3001, 3002,...). From one of the docker containers, I need to access the services for a specific development scenario (API Gateway), and this I cannot get to work.
I have tried using the WSL2 IP address directly, but then the connect just times out. I have also tried using host.docker.internal, which resolves to something else than the WSL2 IP address, but it still doesn't work.
Is there a special trick I need to pull, or is this kind of routing currently not supported, but will be, or is this for some other reason not possible?
This illustrates what I am trying to achieve:
The other routings work - i.e. I can access all the service ports coming from the node.js processes inside WSL2 from the Windows browser, and also I can access the exposed service ports from the containers both from inside WSL2 and from Windows. It's just this missing link I cannot make work.
So what you need to do in the windows machine port forward the port you are running on the WSL machine, this script port forwards the port 4000
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"
And on the container docker run command you have to add
--add-host=host.docker.internal:host-gateway
or if you are using docker-compose:
extra_hosts:
- "host.docker.internal:host-gateway"
Then inside the container you should be able to curl to
curl host.docker.internal:4000
and get a response!
For what it's worth: This scenario is working if you use the WSL2 subsystem IP address.
It does not work if you use host.docker.internal - this DNS alias is defined in the containers, but it maps to the IP address of the Windows host, not of the WSL2 host, and that routing back inside the WSL2 host does not work.
The reason why this (probably temporarily) did not work is somewhat unclear - I will revisit this answer if the problem should reappear and I manage to track down what the actual problem may have been.
I ran into this problem with the latest Docker Desktop. I rolled it back to 4.2 and it worked.
Docker Desktop 4.2
Windows 19044.1466
Ubuntu 20.04
I have a java service running on a linux local host (accessing the IP address using ifconfig command), my other containers running on docker desktop using the WSL2 based engine, which can communicate to my java service using the IP address.
This sounds like the issue which is discussed here. For me the only thing that worked was running the docker container with --net=host and then using [::1] instead of localhost in the container to access other containers running in WSL.
So for example, container1 is started with docker run --net=host and then calls container2 like this: http://[::1]:8000/container2 (adjust port and path to your specific application)

Nifi install using Docker - CanĀ“t access the webserver

I'm new to both docker and Nifi, I found this command that installs via docker and used it on a virtual machine that I have in GCP but I would like to access this container via webserver. In docker ps this appears to me:
What command do I need to execute to gain access to the tool via port 8080?
The container has already exposed port 8080 on the host, as evidence by the output 0.0.0.0:8080->8080/tcp. You read that as {HOST_INTERFACE}:{HOST_PORT}->{CONTAINER_PORT}/{PROTOCOL}.
Navigate to http://SERVER_ADDRESS:8080/ (or maybe http://SERVER_ADDRESS:8080/nifi) using your web browser. You may need to modify the firewall rules applied to your VM to ensure that you can access that port from your local machine.

Run docker container on localhost via VM

I'm new to Docker and Containers, and I'm trying to run a simple asp.net web app in a container but running into issues. My OS is Windows 10 Home, so I have to use the Docker Toolbox, which runs on a VM that only includes a basic Linux OS. When I spin up the container, it seems to start fine, but I can't view the app on the localhost.
$ docker run -p 8342:5000 -it jwarren:project
Hosting environment: Production
Content root path: /app
Now listening on: http://*:5000
Application started. Press Ctrl+C to shut down.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98cc4aed7586 jwarren:project "dotnet run" 8 minutes ago Up 8 minutes 0.0.0.0:8342->5000/tcp naughty_brattain
I've tried several different recommendations that I found on the web, but none have helped so far. However, my knowledge of networking is very limited, so maybe I'm not fully understanding what needs to be done. I've tried accessing it with the default VM machine IP and the container IP. I understand that the port forwarding does not carry over to the container. Any assistance would be great, as this project is due on Tuesday, and this is the last road block before finishing.
I found the following post that was really helpful: How to connect to a docker container from outside the host (same network) [Windows]. Following the steps below worked perfectly:
Open Oracle VM VirtualBox Manager
Select the VM used by Docker
Click Settings -> Network Adapter 1 should (default?) be "Attached
to:NAT"
Click Advanced -> Port Forwarding Add rule: Protocol TCP, Host Port
8080, Guest Port 8080 (leave Host IP and Guest IP empty)
You should now be able to browse to your container via localhost:8080 and your-internal-ip:8080.
Started up the container (Dockerfile EXPOSES 5000):
docker run -p 8080:5000 -it jwarren:project
Was able to connect with http://localhost:8080
There are few things to consider when working with a VM networking.
Virtual Box has 3 types of networking options NAT, Bridged and Host Only.
NAT would allow your VM to access internet through your internet. But won't allow your HOST machine to access the VM
Host Only network will create a network where the VM can reach the host machine and the Host can reach the VM. No internet using this network
Bridged network will allow your VM to assign another IP from your Wifi router or the main network. This IP will allow VM to have net access as well as access to other machines on the network. This will allow even the host machine to reach the IP
Now in most cases when you want to run Docker inside a VM and access that VM using the host machine you want the VM to have both NAT and Host only bridges
Now accessing your app on port 8342 needs few things checked
seliunx, firewalld, ufw are disabled on your VM (or properly configured to allow the port)
Your VM has a host only network or bridged network
iptables -S should not show REJECT rules
Some VMs come pre-configure to only allow port 22 from external network. So you should try access the app on <hostonlyip>:8342 or <bridgedip>:8342.
If you want to test if the app is up or not you can do the following
docker inspect <containerid> | grep IPA
Get the IP from this and run the command
curl http://<containerip>:5000/
This command needs to be execute inside the VM and not on your machine. If this command doesn't work then your container is not listening on 5000. Sometimes app listen to only 127.0.0.1 inside the container. This means they will work only inside the container and not outside. The app inside the container needs to listen to 0.0.0.0
If nothing works you can try an ssh tunnel approach
ssh -L 8342:127.0.0.1:8342 user#<VMIP>
And then you should be able to access the app on localhost:8342

Allow a container running via docker-machine to connect with Mysql or XDEBUG port on parent OSX system without using an OSX DHCP assigned ip address?

I've got the following setup:
OSX running MySQL listening on all network adaptors at port 3306
XDEBUG enabled IDE listening on port 9000 on the base OSX system.
docker-machine host running on the OSX system with the host ip 192.168.99.100
A debian based docker container with a mysql client running on the docker host and HHVM running with xdebug looking to connect to some lucky remote host on port 9000.
The ip addresses change frequently on the OSX system due to being assigned via DHCP, so I want the docker container to be able to somehow be able to hit the mysql server regardless of what IP the native OSX network adaptors get assigned (without manually updating it). Also, I need a stable ip I can provide my HHVM server.ini file a remotes host for Xdebug.
With running a base system of linux this isn't an issue as the docker host and the actual native machine running docker are one-and-the-same. Also, there are several ways for a container to learn of the host's ip so the issue isn't hitting the docker host.
However, in OSX running docker-machine, the host ain't the native OSX system, but instead is a VM running in virtual box (assuming you're using the vb driver, and who the sam hill blazes isn't?).
The only thing I could think of was to port forward request on 3306 to the docker-machine host (192.168.99.100 which never changes) to the OSX's port 3306. Then have the container hit the docker-machine host for Mysql requests. IF this works, I could rinse and repeat for any port I port I need to link like xdebug on port 9000.
Does anyone know how to accomplish this or have another suggestion?
Figured a way out without needing to make any changes that provides a consistent ip to connect to on the base OSX system. Docker machine sets things up in such a way to make this possible.
Docker machine creates a virtualbox VM with 2 network adaptors, one set up as host-only, the other set as NAT. Don't know why it creates 2, but
The host-only adaptor provides the OSX an ip of 192.168.99.1 and the various VM's using it get addresses starting with 192.168.99.100. However, inside the VM network, you can't use the address 192.168.99.1 to hit ports on the parent OSX system (not sure why, but guessing host only intends to be only communication between the VMs).
The NAT network adaptor is set so the OSX get's the ip 10.0.2.2 and the VM get's 10.0.2.15. With a NAT, you can route to the OSX system at 10.0.2.2 from both the docker host VM and containers running on the host.
Since this 10.0.2.2 address for the OSX machine doesn't change (unless you screw with the virtual box networking settings) bingo, got what I need.

Resources