Search code examples
dockerconnectionvirtual-machinefirewalldoccano

How to connect to a web application inside a container in a Virtual Machine, from outside it?


I have a setup that is:

PC > Fedora(Hyper-V VM) > Container running web application

The problem that i am facing is that i can not connect to the web app from my PC ( PC > Container web app)

When the service starts, it show that it is listening on http://0.0.0.0:8000

[2021-05-27 22:29:57 +0000] [23] [INFO] Starting gunicorn 20.1.0
[2021-05-27 22:29:57 +0000] [23] [INFO] Listening at: http://0.0.0.0:8000 (23)
[2021-05-27 22:29:57 +0000] [23] [INFO] Using worker: sync
[2021-05-27 22:29:57 +0000] [25] [INFO] Booting worker with pid: 25
[2021-05-27 22:29:57 +0000] [26] [INFO] Booting worker with pid: 26
[2021-05-27 22:29:57 +0000] [27] [INFO] Booting worker with pid: 27

Trying to connect to http://0.0.0.0:8000 do not work, rather that, I use the container IP:8000 to connect e.g.: 172.17.0.2:8000

Doing this on my VM works fine, i can connect and use the application, but it does not work on my PC. I tried to connect using the VM ip, the 0.0.0.0 and the container IP too, like in the VM. But none of this options works.

i tried to forward the ports using iptables, but i don't know how to use it exactly. I tried googleing some commands and using that but didn't get to the solution.

Any help? Maybe it would be related to another thing that i am not seeing


Solution

  • There are several ways to set VM, host, NAT or bridge.

    Reference: https://superuser.com/a/227508/282690

    Host-only only permits network operations with the Host OS.
    
    NAT mode will mask all network activity as if it came from your Host OS, although the VM can access external resources.
    
    Bridged mode replicates another node on the physical network and your VM will receive it's own IP address if DHCP is enabled in the network.
    

    so if you set your VM as bridge mode, it will get its own IP address, in same network as your host PC.

    with this way, you can connect any ports between them, no extra setup.

    If you go with host mode, you need redirect/forward ports. Use Vagrant as sample:

    Vagrant.configure("2") do |config|
      config.vm.network "forwarded_port", guest: 80, host: 8080
      # ... for more ports if need
      # ... for more ports if need
    end