

By Tom Schwaller, Senior Technical Product Manager, Michael Roy, Product Line Marketing Manager, and Simone Morellato, Director Technical Product Management
One thing that makes containers great is their ability to rapidly spin up a browser-compatibility testing environment. There are plenty of great tools that can then be used to automate this testing, and Selenium is one of the most deployed and trusted solutions available.
In this post, we’ll look at deploying and running Selenium Grid with vSphere Integrated Containers, which allow you to consume resources when they are needed without pre-provision large VMs.
Selenium Grid is essentially an orchestrated, multi-node deployment of Selenium. With it, you can test multiple combinations of operating systems and browsers in parallel. If you’re just getting started with Selenium in general, using it to test multiple combinations might be overkill, but if you’re already familiar with running a single instance of Selenium, then going to Grid is a natural progression.
Previously, organizations had to configure testing on a per-machine basis, which meant manually creating a VM, installing an OS and a browser, setting a snapshot point, manually downloading the code to test, opening up a browser and testing the app. This process doesn’t scale well if you need to support many browsers and OS combinations. Further, once things were running, if there was a problem, it was difficult to troubleshoot and return to a known good state, even with snapshots in place.

Selenium Grid leverages docker-compose so environments are dictated as code through the compose file, thereby allowing them to be redeployed on the fly, always with the same configuration.
This on-the-fly model also saves resources because you can destroy the vSphere Integrated Container (VIC) VMs when testing is done, and deploy them only when actively testing instead of letting them sit idle for long periods of time with CPU, memory and disk resources being allocated. And the vSphere administrator has full visibility and control over the container VMs running in a virtual container host resource pool. This pool can be as large as you like, is extensible on the fly and is not constrained by the limits of a Docker Host VM based pool. VIC consumes resources only when containers are running, with no need for pre-allocation. Also, using Docker together with vSphere Integrated Containers lets you scale your Grid up and down from your local command line.
Because of these advantages, more and more enterprises are turning to VIC to run Selenium Grid. Let’s see how it works.
The Selenium Grid architecture comprises two main components: hubs and nodes. Nodes are where you actually run the tests themselves, whereas the hub is responsible for scheduling those tests on the appropriate node (i.e., the VM with an OS-browser combo that was specified in a test).

When building this out, we need to first stand up a single hub, and then register nodes to that hub. Thanks to the declarative nature of Docker containers, the process to get started is quite simple.
First, download this docker-compose file from our tutorial directory on GitHub, put it into a directory and then change directories to it from the command line.
Second, use this simple docker-compose command to read the docker-compose.yml file that you just downloaded. The tool will automatically download the containers, build the network and initialize the software. Don’t forget to set the environment variable COMPOSE_TLS_VERSION, otherwise, you will get an error message.
1 2 3 |
$ export COMPOSE_TLS_VERSION=TLSv1_2 $ export DOCKER_HOST=vch.corp.local:2376 # vch.corp.local is the FQDN of Virtual Container Host created in VIC $ docker-compose up -d |
Here’s an example:

Third, check that the Grid is running. If you check out the vSphere management console, you should see two new containers: “selenium_chrome_1-XXX” and “selenium_hub_1-XXX” (where XXX is some UUID).

Selenium Grid also provides a management console, which you can view from a browser at the following address:
1 |
http://{ip_of_vic_container_host_vm}:4444/grid/console |
Here’s an example:

And that’s it to get things running. You can now think about scaling the application using standard Docker commands as well:
1 |
$ docker-compose up --scale chrome=5 -d |
Here’s an example:

If you check out the vSphere management console, you can now see the results of your command:

The Selenium Grid console also shows the results of scaling the application:

What About Scaling Down?
Scaling down is just as easy. Simply specify the number of nodes you want in your docker-compose command (or file):
1 |
$ docker-compose up --scale chrome=1 -d |
Stopping and Removing
When you’re all done testing this test engine, you can easily stop the containers and destroy their images:
1 2 |
$ docker-compose down $ docker-compose rm |
Once you’re up and running, you can get to configuring Selenium to suit your needs by integrating it into your continuous integration and continuous delivery pipeline.
Security
In a continuously iterating development model, security can’t be considered an after-thought; it has to be an integral part of the process. Project Harbor, an open source private registry from VMware, enables this by actively reviewing containers, images and templates for known vulnerabilities from the CVE project database.
To illustrate, in the docker-compose example above, we pulled the latest images from Docker Hub. These images are quite popular, as you can see:

But how secure are these images? Let’s push them to our local Harbor registry and check the vulnerability scanning results.
When we check out of a repository without any tags given, we’ll always get :latest, but in this case, we want to check against a specific version, so we’ll pull that from Docker Hub.
To find out which version is the latest, you can visit the Docker Hub repo page for the given container image. For Selenium, the address would be:
https://hub.docker.com/r/selenium/hub/tags

Here we can see that besides the latest version, there is version 3.8.1 at the time of this writing.
Before we start to push images to Harbor, let’s first create a Docker Container Host(DCH) in VIC which will be used to push images. Alternatively, you can use your dev laptop or a linux VM to push images to Harbor
1 2 3 4 5 6 7 8 9 10 |
$ docker volume create --opt Capacity=10GB --name dchdisk # This will create a volume in VIC for # storing container images $ docker --tls run \ -v dchdisk:/var/lib/docker \ -d \ -p 12376:2376 \ --name dch-photon \ vmware/dch-photon \ -insecure-registry vic.corp.local \ -tls |
Now that our DCH is created, let’s authenticate with Harbor.
1 |
$ docker -H vch.corp.local:12376 --tls login vic.corp.local -u 'dev@vsphere.local' -p <password> |
1 2 3 4 5 6 7 8 |
-H vch.corp.local:12376 - This flag is used to specify the Host:Port where Docker Daemon socket is running. In our case, we started DCH in VCH and mapped port 12376 on the VCH to port 2376 on DCH. Hence, the FQDN of VCH is used with port 12376 --tls - Tells docker to use TLS authentication login - Login to docker registry vic.corp.local - This is the FQDN of our VIC appliance which is hosting our Harbor private registry -u 'dev@vsphere.local' - Username of the user which will be pushing docker images -p <password> - Password for the user |
Now we are ready to push images to Harbor with the following CLI commands:
1 2 3 |
$ docker -H vch.corp.local:12376 --tls pull selenium/hub:3.8.1 # Notice the change of port to 12376 $ docker -H vch.corp.local:12376 --tls tag selenium/hub:3.8.1 vic.corp.local/default-project/selenium/hub:3.8.1 $ docker -H vch.corp.local:12376 --tls push vic.corp.local/default-project/selenium/hub:3.8.1 |
1 2 3 4 |
$ docker -H vch.corp.local:12376 --tls pull selenium/node-chrome:3.8.1 $ docker -H vch.corp.local:12376 --tls tag selenium/node-chrome:3.8.1 \ vic.corp.local/default-project/selenium/node-chrome:3.8.1 $ docker -H vch.corp.local:12376 --tls push vic.corp.local/default-project/selenium/node-chrome:3.8.1 |
1 2 3 4 |
$ docker -H vch.corp.local:12376 --tls pull selenium/node-firefox:3.8.1 $ docker -H vch.corp.local:12376 --tls tag selenium/node-firefox:3.8.1 \ vic.corp.local/default-project/selenium/node-firefox:3.8.1 $ docker -H vch.corp.local:12376 --tls push vic.corp.local/default-project/selenium/node-firefox:3.8.1 |
If we check the UI of our Harbor Container Registry, we can see that it has already identified some vulnerabilities for us.

Thankfully, none of them are categorized as ‘severe’ (there are 8 ‘medium’ and 16 ‘low’ for selenium/hub:3.8.1).

Harbor also shows the CVE entries so that you can decide if you need to build clean images on your own.

The Selenium community is working on using images based on Alpine Linux, but that work hasn’t been released officially yet.
Back to Selenium Hub itself—from this point, there are a lot of possibilities for setting up your Grid and integrating it with various CI/CD systems, or scripting the browser behavior with Python, JavaScript, Ruby, etc. There are also Selenium Docker images available with integrated video recording or extensions like Zalenium. The sky’s the limit.
So there you have it—VIC makes it simple to deploy and secure Docker containers in the data center for development and testing on the fly, all backed by the power and control of vSphere.