Specify Selenium Firefox Node host as a variable inside a Docker container - selenium

I'm trying to set up Selenium in Docker Swarm. It's a standard setup, so hub + replicated Firefox nodes. Since I'm using different networks for different components of the Swarm I've encountered a problem with networking.
Although Firefox Node IP is let's say 10.0.1.19 it gets reported to the Selenium Hub as 172.19.0.4. Hub cannot connect to this IP since it's outside the network created for Selenium and node gets timeout.
I found out I can set host, port, and remoteHost arguments of Firefox containers but since everything is dynamic I cannot hardcode those values. Therefore I thought about doing something like this in my docker-compose.yml file inside Firefox Node definition:
environment:
- SE_OPTS="-host $$HOSTNAME -port 5555 -remoteHost http://$$HOSTNAME:5555"
If $HOSTNAME variable could be used this would solve my problem immediately. Unfortunately while checking Hub logs I see:
java.security.InvalidParameterException: Error: Not a correct url to register a remote : http://$HOSTNAME:5555"
Apparently the argument is not changed to its value before sending it to the hub. I'd like to send the right IP or hostname of the Firefox node. Any ideas?

The solution was editing Firefox Docker entrypoint file and manually adding
export MYIP="$(cat /etc/hosts | grep $HOSTNAME | sed 's/\s.*$//' | tr -d '\n')"
REMOTE_HOST="http://$MYIP:5555"
REMOTE_HOST_PARAM="-remoteHost http://$MYIP:5555"
This way the node always sends its correct IP based on the IP found inside /etc/hosts

Related

Selenium4 Dynamic Grid setup using different VM's

In the official documentation of selenium docker setup, I see a config.toml file which contains below info
[docker]
# Configs have a mapping between the Docker image to use and the capabilities that need to be matched to
# start a container with the given image.
configs = [
"selenium/standalone-firefox:4.3.0-20220706", "{\"browserName\": \"firefox\"}",
"selenium/standalone-chrome:4.3.0-20220706", "{\"browserName\": \"chrome\"}",
"selenium/standalone-edge:4.3.0-20220706", "{\"browserName\": \"MicrosoftEdge\"}"
]
# URL for connecting to the docker daemon
# Most simple approach, leave it as http://127.0.0.1:2375, and mount /var/run/docker.sock.
# 127.0.0.1 is used because interally the container uses socat when /var/run/docker.sock is mounted
# If var/run/docker.sock is not mounted:
# Windows: make sure Docker Desktop exposes the daemon via tcp, and use http://host.docker.internal:2375.
# macOS: install socat and run the following command, socat -4 TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock,
# then use http://host.docker.internal:2375.
# Linux: varies from machine to machine, please mount /var/run/docker.sock. If this does not work, please create an issue.
url = "http://127.0.0.1:2375"
# Docker image used for video recording
video-image = "selenium/video:ffmpeg-4.3.1-20220706"
# Uncomment the following section if you are running the node on a separate VM
# Fill out the placeholders with appropriate values
[server]
host = <ip-from-node-machine>
port = <port-from-node-machine>
What does the bottom two parameters represent host and port?
FYI- I am planning to run the hub container in one VM and nodes containers in another VM's.
Correct me if I am wrong, I am guessing config.toml file should be present in the VM's where we would be running the nodes
So, for host= should we need to give Ip of where hub is up and running?
and
for port= where we get the port number?
Expecting answers ASAP, thanks in advance
Yes, the host and port values are the details of where your Hub is running. Port number is 4444 if your hub is running on the default port.

How to make two docker containers running on the same local communicate?

I'm running to APIs through docker-compose on linux. I tried to pass them IPs that docker containers have, i checked with: docker inspect . They are on the same (docker)network. Should this work, and I'm mistaken, or is there simpler way to set each their address in some easy way. I went through docker docs, but nothing seems to resolve the problem.
Whenever you start docker containers and expose ports from each container, the default IP would be localhost or 0.0.0.0
So, containers can communicate via: localhost:<port_of_other_container>
If it doesn't work try with ifconfig -> en0 -> inet address instead of localhost.

How do I connect to a localhost site using Selenium Docker image?

I have a node application that I can start with node server.js and access on localhost:9000.
I have a series of e2e tests on selenium that run fine, but I am now looking to use the docker selenium image.
I start the docker image with docker run -d -p 4444:4444 selenium/standalone-chrome
and I changed my e2e test code to look like:
var driver = new webdriver.Builder().
usingServer('http://127.0.0.1:4444/wd/hub').
withCapabilities(webdriver.Capabilities.chrome()).
build();
// driver.manage().window().setSize(1600, 1000);
return driver.get('http://127.0.0.1:9000')
.then(function() {
// driver.executeScript('localStorage.clear();')
return driver
});
But selenium fails to connect to the app at all!
(If I uncomment the setSize line, the program fails right there)
I have the server up an running, and it's indeed accessible at localhost:9000. How can I get my test to properly use dockerized selenium, and properly point to a server on localhost?
If you want your container network behaviour to be like your host machines use docker run --network=host
From the host machine, Docker endpoints aren't accessible at localhost. Did you try using 0.0.0.0 instead of 127.0.0.1?
If you are using mac, you may try to get gateway from netstat inside docker image:
netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'
or write ifconfig from terminal, and get the inet address, try with that instead of 127.0.0.1.
What is docker ps command is returning for this container? Is it display like "0.0.0.0:4444->4444/tcp". ?
You can run sudo iptables -L -n and verify under "Chain DOCKER" section below line should come.
ACCEPT tcp -- 0.0.0.0/0 x.x.x.x tcp dpt:4444
Just to make sure I understand - the selenium runs in the docker, and tries to access the node app that runs on the server?
In this case, these are two different "servers", so you need to use real IP addresses (or dns names)
pass the ip of the server as a parameter to the dockerized selenium image the simplest thing would probably be as an environment variable

Can't reach Apache on Docker from Windows Server 2016 host machine

Heads up: I'm a novice in both general web administration and Docker. My errors could be caused by something very stupid.
I am running Docker for Windows Server 2016 (the native variant). I have pulled and built a simple Docker base image with Nano Server and Apache 2.4 (nanoserver/apache24). I have made a container from this image and mapped the container port 80 to my local port 8082.
From inside the container, I can use Invoke-WebRequest -uri http://localhost:80 and retrieve the default apache document. However, I would also expect Invoke-WebRequest -uri http://localhost:8082 from outside the container to retrieve the same file. This does not work. I have also tried using the container NAT address, running Invoke-WebRequest -uri http://172.23.58.7:8082. This does not work neither. What is it that I have misconfigured here?
Screenshot from my process below. PowerShell in host computer on the left, PowerShell inside container on the right.
EDIT: #Grimmy asked me in the comment section whether I do have EXPOSE 80 in my Dockerfile and whether docker ps command displays my container with the expected port mapping. It's yes on both counts. My container runs with arguments -d -it because it was a quick Google fix to the problem where the container exits immediately after launch. I know -i "keeps STDIN open" and -t "allocates pseudo-tty", but I frankly don't understand what either of those imply or whether it could be relevant to the problem.
EDIT2: I did not explicitly mention this in the original post, but it's worth noting that netstat -a -o does not display a PID listening on port 8082. I would expect this to be the case. Should it be the case?
The first 50 lines or so of output is displayed in the screenshot.
I got the answer from 'artisticcheese' in the Docker Forums.
You can not connect to mapped IP address within container host itself.
it’s bug in Windows implementation of WinNAT. You need get private IP
address of container and connect to it using port number. Or you can
access through public mapped port from another host on the same
network, that shall work.
I connected from another host, and it worked immediately. I frankly don't know what the "private IP address" of the container is as opposed to the NAT address, so I couldn't proceed on the other tip.

second ssh session can not connect to docker host

I have server with debian operating system. I installed docker on it and it works fine, as you can see as follow:
root#3053b0461a3c:/# which wget
/usr/bin/wget
root#3053b0461a3c:/#
An ubuntu based container is running.
Then I started a second terminal, connect via ssh to server and type in console
docker ps
But as output I've got the message:
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
Why the docker service is not running?
Unset the environment variable DOCKER_HOST and it should work.
https://github.com/docker/docker/blob/eff810aed688879f67a3730c41d9adce4637470f/docs/installation/ubuntulinux.md
Try unset DOCKER_HOST
In most unix-based (or -like) environments that I've seen there is the concept of environment variables, which can be considered as dynamic configuration. The 2 functions available are:
set which sets to an environment variable a special value
unset which removes an environment variable.
On the case of DOCKER_HOST, docker uses this variable to know whether it should attach to a network host, e.g. tcp://192.137.23.11 or to a local Unix socket.