I am running selenium test in Gitlab CI, but have problem with setting remote URL correctly when using the gitlab runner instead of my computer.
The IP address of the runner is 192.168.xxx.xxx
. And when I run the pipeline, I got the IP address of selenium hub is 172.19.0.2/16
. I tried both, and both failed. I also tried to use the name of the selenium hub container http://selenium__hub
, but it also failed.
The docker-compose.yml is:
version: "3"
services:
chrome:
image: selenium/node-chrome:4.0.0-20211013
container_name: chrome
shm_size: 2gb
depends_on:
- selenium-hub
volumes:
- ./target:/home/seluser/Downloads
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_GRID_URL=http://localhost:4444
ports:
- "6900:5900"
edge:
image: selenium/node-edge:4.0.0-20211013
container_name: edge
shm_size: 2gb
depends_on:
- selenium-hub
volumes:
- ./target:/home/seluser/Downloads
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_GRID_URL=http://localhost:4444
ports:
- "6901:5900"
firefox:
image: selenium/node-firefox:4.0.0-20211013
container_name: firefox
shm_size: 2gb
depends_on:
- selenium-hub
volumes:
- ./target:/home/seluser/Downloads
environment:
- SE_EVENT_BUS_HOST=selenium-hub
- SE_EVENT_BUS_PUBLISH_PORT=4442
- SE_EVENT_BUS_SUBSCRIBE_PORT=4443
- SE_NODE_GRID_URL=http://localhost:4444
ports:
- "6902:5900"
selenium-hub:
image: selenium/hub:4.0.0-20211013
container_name: selenium-hub
ports:
- "4444:4444"
the gitlab runner's config file looks like this:
[[runners]]
name = "selenium"
url = "https://gitlab.myhost.at"
token = "xxxxxxxx"
executor = "docker"
privileged = true
links = ["selenium__hub:hub"]
[runners.docker]
image = "docker:stable"
privileged = true
The remote url I have tried are:
WebDriver driver = new RemoteWebDriver(new URL("http://192.168.xxx.xxx:4444/wd/hub"), cap);
WebDriver driver = new RemoteWebDriver(new URL("http://172.19.0.2:4444/wd/hub"), cap);
WebDriver driver = new RemoteWebDriver(new URL("http://selenium__hub:4444/wd/hub"), cap);
How can I get this to work with GitLab runner?
The issue here is when your job launches containers using docker-compose
, the hostnames in the docker network are not known to your job container.
Assuming you are using the docker:dind
service in your job to use docker-compose
and you are trying to connect to your services started with docker-cmpose
from your job, you would need to use the hostname docker
to reach your services through their mapped ports.
So your corrected code would be as follows:
WebDriver driver = new RemoteWebDriver(new URL("http://docker:4444/wd/hub"), cap);
The reason this is needed is because your containers are running 'on' a remote docker daemon service -- the docker:dind
container. When you invoke docker-compose
your job container talks to the docker:dind
container which in turn spins up a new docker network and creates the docker containers in your compose file on that network.
Your job container has no knowledge of (or route to) that network, nor does it know the hostnames of the services. The service daemon itself also is running on a separate network from your runner -- because it is another docker container that was created by the docker executor; so your runner IP won't work either.
However, the docker executor does create a link to your services:
I.E. the docker:dind
service. So you can reach that container by the docker
hostname. Additionally, your compose file indicates that the hub service should make a port mapping of 4444:4444
from the host -> continaer. The host, in this case, means the docker:dind
service. So calling http://docker:4444
from your job reaches the hub service.
Finally, to cover one last detail, it looks like in your runner configuration you expected your links
to allow you to communicate with the hub container by hostname:
links = ["selenium__hub:hub"]
In the runner configuration, it's true that the links
configuration, in general, would allow your job to communicate with containers by hostname. However, this configuration is errant for two reasons:
docker-compose
in your job by talking to the docker:dind
service daemon.selenium__hub
container as the FQDN hub
" -- but you never tried the hostname hub
.There is nothing to fix here because (1) is not a fixable error when using docker-in-docker.
Alternatively, you can utilize GitLab's services:
capability to run the hub and/or browser containers.
my_job:
services:
- docker:dind
- name: selenium/hub:4.0.0-20211013
alias: hub # this is the hostname
You could even do this as a runner configuration and give it a special tag and jobs needing remote browsers can just add the necessary tags:
key(s) to reduce the amount of job configuration needed.
You may also be interested to see one of my other answers on how FF_NETWORK_PER_BUILD
feature flag can affect how networking works between docker containers and jobs/services.