DEV Community

Gregory Paciga
Gregory Paciga

Posted on • Originally published at gerg.dev on

Making Chromedriver and Chrome versions match in a Docker image

I keep running into this problem where UI test tools need a Chrome browser installed, but come packaged in npm with an outdated chromedriver dependency. Keeping the two in sync in any environment where these test tools run is a must, and I’ve long since given up on trying to do this manually on any system outside of a Docker image. What I do now is build a Docker image that installs the latest Chrome, checks which version it is, and then installs the specific version of chromedriver that is compatible.

The following should work on any Debian/Ubuntu-based image, but should be adaptable to others.

First, installed Chrome, including dependencies for puppeteer since that’s also often required.

RUN echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" | \
    tee -a /etc/apt/sources.list.d/google.list && \
    wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | \
    apt-key add - && \
    apt-get update && \
    apt-get install -y google-chrome-stable libxss1
Enter fullscreen mode Exit fullscreen mode

This isn’t anything special; any way of installing Chrome should work. Next, let’s go through step by step. First, we find out what the latest version of Chrome just installed is:

BROWSER_MAJOR=$(google-chrome --version | sed 's/Google Chrome \([0-9]*\).*/\1/g')
Enter fullscreen mode Exit fullscreen mode

That regex just pulls out the numeric portion of the version before the first dot. Then we can use this major version to look up the latest chromedriver release from https://chromedriver.storage.googleapis.com/. This is very convenient benefit of the relatively recent change to have the two programs follow the same versioning scheme.

wget https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${BROWSER_MAJOR} -O chromedriver_version
Enter fullscreen mode Exit fullscreen mode

and that version number saved in the chromedriver_version file to download and install the binary:

wget https://chromedriver.storage.googleapis.com/`cat chromedriver_version`/chromedriver_linux64.zip && \
unzip chromedriver_linux64.zip && \
mv chromedriver /usr/local/bin/
Enter fullscreen mode Exit fullscreen mode

The final mv here is just to make sure the binary is in the $PATH. Finally, I do a quick comparison of the installed versions of both, so I can abort the image build if something went wrong.

DRIVER_MAJOR=$(chromedriver --version | \
    sed 's/ChromeDriver \([0-9]*\).*/\1/g') && \
echo "chrome version: $BROWSER_MAJOR" && \
echo "chromedriver version: $DRIVER_MAJOR" && \
if [$BROWSER_MAJOR != $DRIVER_MAJOR]; then
    echo "VERSION MISMATCH";
    exit 1;
fi
Enter fullscreen mode Exit fullscreen mode

Putting the entire lookup, download, and verification into a single RUN looks like:

RUN BROWSER_MAJOR=$(google-chrome --version | sed 's/Google Chrome \([0-9]*\).*/\1/g') && \
    wget https://chromedriver.storage.googleapis.com/LATEST_RELEASE_${BROWSER_MAJOR} -O chrome_version && \
    wget https://chromedriver.storage.googleapis.com/`cat chrome_version`/chromedriver_linux64.zip && \
    unzip chromedriver_linux64.zip && \
    mv chromedriver /usr/local/bin/ && \
    DRIVER_MAJOR=$(chromedriver --version | sed 's/ChromeDriver \([0-9]*\).*/\1/g') && \
    echo "chrome version: $BROWSER_MAJOR" && \
    echo "chromedriver version: $DRIVER_MAJOR" && \
    if [$BROWSER_MAJOR != $DRIVER_MAJOR]; then echo "VERSION MISMATCH"; exit 1; fi
Enter fullscreen mode Exit fullscreen mode

So far everything I’ve done this with has successfully found chromedriver in the path automatically, but other tools may require passing an argument to point to the right binary. As usual, I’m sure this isn’t the only way to go about it. But at least this way, I am no longer dependent on npm packages for UI test tools finding just the right version of chromedriver.

Discussion (0)