Making Chromedriver and Chrome versions match in a Docker image
Tags: automation, chrome, chromedriver, docker
Published: 2021-08-23 21:05:01

---
title: Making Chromedriver and Chrome versions match in a Docker image
published: true
date: 2021-06-15 14:00:00 UTC
tags: Automation,chrome,chromedriver,docker
canonical_url: https://gerg.dev/2021/06/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
```

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')
```

That regex just pulls out [the numeric portion of the version before the first dot](https://regexper.com/#Google%20Chrome%20%28%5B0-9%5D*%29.*). Then we can use this major version to look up the latest chromedriver release from [https://chromedriver.storage.googleapis.com/](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
```

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/
```

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
```

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
```

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.