Can Selenium + Chrome Dev-tools Recipe works inside a Docker Container

AMIT RAWAT
4 min readDec 7, 2019

This article is in continuation to my previous article “Selenium + Chrome Dev-tools makes a Perfect Browser Automation Recipe” where I talked about how we can debug a chrome instance using Chrome dev-tools protocol.

I will strongly recommend to read the previous article in case you are not familiar with chrome dev-tools protocol.

Recently a gentleman asked me if we can debug a chrome running inside a docker container using the same dev-tools protocol.

The very first thought came in to my mind was, why the dockerized environment would affect this solution and that’s what I replied to him.

But it seems the problem was not so simple as he still found it difficult to make it work. So I thought of exploring it on my own and fortunately after few tries I got the working solution.

The best thing about working on open-source tools is that you can contribute to other’s problem and in return you will also learn few new concepts.

So this blog will exclusively talk about, what are the things we have to take care when the chrome is running inside a docker container.

The problem which we have in hand is faced by many other people with-in the automation fraternity and there is already an opened issue on Puppeteer which also leverages the same dev-tools protocol to driver the browser.

So let’s get started and try to de-construct this whole problem.

We will use the standalone-chrome docker image under selenium account as it has chrome as well as all the selenium standalone dependencies packaged inside this image.

To run this image as a container, we will use this standard docker command.

docker run -d -p 4444:4444 --name selenium-standalone-chrome -v /dev/shm:/dev/shm selenium/standalone-chrome

As we know to interact with the chrome’s remote debugger protocol we would need to open another TCP port to build the websocket connection. Let’s update the above command to expose this port. I have used the 9222 as port which is the default port but it can be changed to any available port.

docker run -d --expose=9222 -p 4444:4444 -p 0.0.0.0:9222:9222 --name selenium-standalone-chrome -v /dev/shm:/dev/shm selenium/standalone-chrome

First we are exposing the port inside the container using “ — expose=9222” and then we are mapping this port with the same port on the host machine using “0.0.0.0:9222:9222”

The above command will make sure the chrome devtools port is properly exposed and now can be used in our selenium client code.

In our client code, we have to make sure when the chrome instance is launched, the devtools port should be used as 9222 and the remote debugging address should be “0.0.0.0"

ChromeOptions options = new ChromeOptions();
options.addArguments(Arrays.asList("--remote-debugging-port=9222"));
options.addArguments(Arrays.asList("--remote-debugging-address=0.0.0.0"));

Our client code should now be able to make the websocket connection to this port “9222” but somehow we will see this exception.

org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
java.net.SocketException: Connection reset

What could be the problem as fundamentally we have done everything right in configuring our docker environment ?? I wasted couple of hours to figure out the problem.

If we see our working environment, the chrome including the dev-tools is running inside a docker container which is like a remote machine with its own IP and network.

The selenium client code is running on another machine which uses a different IP so in theory we are trying to control a chrome session from a remote machine and it could be a big security risk. Think of a scenario where you are using your chrome to access your banking application and some intruder who managed to get in to your network can control your chrome remotely and can do all the transactions on your behalf.

Due to this security risk, the chromium team has disabled the dev-tools access from a remote IP and that’s the reason we were facing the SocketException.

Fortunately if the chrome is running in a headless mode then we can debug it from a remote machine. As no human will use a headless mode for their personal use :-) so which means the chrome is being used for some automation task.

By simply adding the following line of code in our client code, everything will start working.

options.addArguments(Arrays.asList("--headless","--disable-gpu"));

Hurray! now we can easily debug the chrome instance which are running on selenium grid inside docker containers and can easily scale this approach of mixing selenium with chrome dev-tools.

The entire code base can be seen here and this specific test related to docker container can be found here.

Thanks for reading this blog, please share your queries/thoughts in the comments section and I will try to answer them to best of my capability.

--

--

AMIT RAWAT

I am a Civil Engineer by qualification, an Engineering Manager by profession and a Developer by passion. (amitrawat.dev)