How to I get the host address using dockerpy of container? - python

I am trying to figureout from where to get the hostname of a running docker container that was started using docker-py.
Based on presence of DOCKER_HOST= file the started docker container my be on a remove machine and not on the localhost (machine running docker-py code).
I looked inside the container object and I was not able to find any information that would be of use for as 'HostIp': '0.0.0.0' is the remote docker host.
I need an IP or DNS name of the remote machine.
I know that I could start parsing DOCKER_HOST myself and "guess" that but this would not really be a reliable way of doing it, especially as there are multiple protocols involved: ssh:// and tcp:// at least.
I guess it should be an API based way of getting this information.
PS. We would assume that the docker host does not have firewall.

For the moment I ended up creating a bug on https://github.com/docker/docker-py/issues/2254 as I failed to find that information with the library.

The best method is probably to use a website like wtfismyip.com.
You can use
curl wtfismyip.com
to print it in terminal, and can then extract the public ip from the output.

Related

Looking up hostnames from Docker container

I'm currently trying to get lookup hostnames from inside a docker container using python. My example script is exceedingly simple, so here we go:
import sockets
print(socket.gethostbyaddr('8.8.8.8'))
It works fine from my Windows machine, and it works fine from the Ubuntu instance using WSL2. However, inside the Docker container, no dice. I've verified that it has internet access, it should be able to reach all the same servers my physical machine can access, and I've verified that by pinging those servers from inside the docker container.
However simply looking up the hostname of an IP doesn't work. Any advice?
Edit: The docker container I am running is based on Debian Bullseye
Edit 2: Executing nslookup inside the container is not able to resolve the hostnames either. Do I need to specify a DNS server inside the container?
Edit 3: I got a lot closer to actually solve it. The default nameserver in my resolv.conf is unable to resolve those lookups.
However checking what which nameserver my Ubuntu/Windows use, and manually setting it to be used inside of docker enabled me to at least use nslookup.
So echo "nameserver [ip of host nameserver]" > /etc/resolv.conf got me mostly there.
Okay, I've found the proper solution.
Obviously the proper way to do is, is to add the add --dns [ip of host nameserver] to the docker run arguments.
Edit: Or change it inside the python script in order to not need any arguments other than run to properly start the container for ease of use.

How to know the host IP by running the docker-compose

I have a docker-compose file. Through my docker-compose, I'm running multiple services. For each service, I'm running the different containers. Among these containers, I have one container which is responsible to get the hardware and network info of the host machine. When I'm running the container in a standalone mode the container is able to provide me with the host IP. But unfortunately, when I'm running it along with other containers (most precisely through the docker-compose file), then I'm not able to get the host network information, rather than I'm always getting the bridge network information (i.e., the docker-compose internal network information). I tried to set the network_mode:host in my service, but unfortunately, when I set it, stops communicating with the other containers. Can anyone please suggest me the way of getting the host network information without tampering the internal communication between different service containers.
You could, perhaps, have this container in two networks. One with the host information, and the other for the 'internal' communication with the containers.
For example:
https://success.docker.com/article/multiple-docker-networks
Without a dockerfile and a docker-compose it's hard to test but I think that if you have a container with network_mode:host, you have to access other container trough the host only, that mean port forwarding, so if you have your container in host mode, and another binded to localhost 8080, I think you should be able to ping localhost:8080 from the host mode container.
Give me feedback about this, please!
Have fun!

visdom.server inside Docker

I am running a pytorch training on CycleGan inside a Docker image.
I want to use visdom to show the progress of the training (also recommended from the CycleGan project).
I can start a visdom.server inside the docker container and access it outside of the container. But when I try to use the basic example on visdom inside a bash session, of the same container that is running the visdom.server. I get connection refused errors such as The requested URL could not be retrieved.
I think I need to configure the visdom.Visdom() in the example in some custom way to be able to send the data to the server.
Thankful for any help!
Notes
When I start visdom.server it says You can navigate to http://c4b7a2be26c4:8097, when all the examples mentions localhost:8097.
I am trying to do this behind a proxy.
I realised that, in order to curl localhost:8097, I need to use curl --noproxy localhost, localhost:8097. So I will have to do something similar inside visdom.
When setting http_proxy inside a docker container, you need to set no_proxy=localhost, 127.0.0.1 as well in order to allow connections to local host.
Got the same problem, And I found when you use a docker container to connect server, then you can not use the same docker container to run you code

Python automated test that involve firewall or blocking IP

I have to write some specific automated tests using Python that should block all outbound traffic to a certain host or ip range. On windows I achieved this via the windows hosts file and the effect is the desired one but on Mac OSX this does not work as somehow the hosts file is ignored.
How could I do this programmatically? Netfilter but the lack of documentation and examples is keeping me from using it. Could anyone give me an idea? for example how i could block access to google.com

How to make Django's devserver public ? Is it generally possible?

I'm currently trying out the Django framework and I would share/present/show some stuff I've made to my workmate/friends. I work in Ubuntu under Win7 via VMware. So my wish/desire is to send my current pub-IP with port (e.g http://123.123.123.123:8181/django-app/) to my friends so they could test it.
the Problem is - I use django's Dev server (python /path-to-django-app/manage.py runserver $IP:$PORT).
How do I make the devserver public?
EDIT:
Oh, there's something I forgot to mention. As I sad I use VMware with Ubuntu. I have a shellscript that returns me my current int-IP 192.168.xx.xx and saves it in a environment-variable ($CUR_IP)
So, each time I want to run django's devserver I simply execute
python /path-to-django-site/manage.py runserver $CUR_IP:8080
At this way I become an http-adress (e.g.http://192.168.40.145:8080/app-name/) which I CAN USE OUTSIDE my virtual machine. I could test it on my host (win7) machine. That's actually the reason why I asked the question. I thought there's a way to use the ext-IP and make runserver usable outside too
python manage.py runserver 0.0.0.0:8181
This will run development server that should listen on all IP's on port 8181.
Note that as of Jun 17, 2011 Django development server is threaded by default (ticket #1609).
From docs:
Note that the default IP address,
127.0.0.1, is not accessible from other machines on your network. To
make your development server viewable
to other machines on the network, use
its own IP address (e.g. 192.168.2.1)
or 0.0.0.0.
Assuming you have ruby installed, you just have to get localtunnel:
gem install localtunnel
then start your python development server with:
python manage.py runserver 0.0.0.0:8000
in another shell, start localtunnel:
localtunnel -k ~/.ssh/id_rsa.pub 8000
That will output an url to access your local server.
Port 8000 is now publicly accessible from http://xxxx.localtunnel.com
That's it.
192.168.*.* is a LAN-private address -- once you've done the proper VMWare (or other VM manager) and firewall incantations to make it accessible from the LAN, it still won't be accessible from outside the LAN, i.e., from the internet at large (a good thing too, because such development servers are not designed for security and scalability).
To make some port of a machine with a LAN-private IP visible to the internet at large, you need a router with a "virtual servers" ability (many routers, even cheap ones, offer it, but it's impossible to be specific about enabling it since each brand has its own idiosyncratic way). I would also recommend dyndns or other similar service to associate a stable DNS name to your always-varying public IP (unless you're splurging for a static IP from your connectivity provider, of course, but the latter option is becoming costlier all the time).
superuser.com or serverfault.com may provide better answers and details (once you give every single little detail of your configuration in a question) since the question has nothing much to do with software development and everything to do with server administration and configuration.
I had to add this line to settings.py in order to make it work (otherwise it shows an error when accessed from another computer)
ALLOWED_HOSTS = ['*']
then ran the server with:
python manage.py runserver 0.0.0.0:9595
Also, make sure that your firewall allows communication to the chosen port (9595 in this case)
Already answered but adding npm alternate of same localtunnel
sudo npm install -g localtunnel
lt --port 8000 --subdomain yash
If you are using Virtualbox, You need to change the network setting in VB from "NAT" to "Bridged Adaptor". Then restart the linux. Now if you run sudo ifconfig you are able to see your IP address like 192.168.*.* . The last step is runserver
python manage.py runserver 192.168.*.*:8000
Cheers!
You need to configure bridged networking in VMWare and also grant access to the target port in Ubuntu firewall.
Alternatively, you can use cotunnel, Just run cotunnel in your ubuntu (in VMware) change your tunnel port in cotunnel dashboard which port you are using in local side. It gives public url and you can share the url with your friends.
Your Django server can listen to 127.0.0.1 or 0.0.0.0 (I prefer 0.0.0.0) it does not matter for cotunnel.
Might I suggest trying something like pyngrok to programmatically manage an ngrok tunnel for you? Full disclosure, I am the developer of it. Django example here, but it's as easy as installing pyngrok:
pip install pyngrok
and using it:
from pyngrok import ngrok
# <NgrokTunnel: "http://<public_sub>.ngrok.io" -> "http://localhost:8000">
http_url = ngrok.connect(8000)
No messing with ports or firewalls or IP addresses, and now you can also inspect the traffic (which is useful since what you're doing here is ongoing development, not running a prod-ready server).

Categories