Running karma tests with headless Chrome inside Docker

Eirik Sletteberg
HackerNoon.com
3 min readAug 7, 2017

--

It can be useful to run build steps inside a Docker container, to handle isolation between environments (prevent conflicts between dependency versions), enable development on different operating systems (macOS, Linux, Windows) and reliable builds (a stable build environment).

There are some obstacles you will encounter when trying to setup such an environment. I went through them, and created an example boilerplate project which shows some of the setup. (Note that I have set up a project which uses yarn instead of npm; it is perfectly possible to create a similar setup that uses npm.)

You can check out the full code example on GitHub:

https://github.com/eirslett/chrome-karma-docker

Adding Google Chrome to the Docker image

From the official node.js image, it’s possible to install Chrome from the official .deb package.

Also note that I add dumb-init; it saves you from a lot of pain and annoyance, like when you’re trying to use Ctrl+C to stop your container.

Detect Docker, and configure Karma

It turns out there are some problems with running Chrome inside Docker. Unless you’re running the container in privileged mode, Chrome’s sandbox won’t work. We use the is-docker package to detect whether the process is running inside a Docker container or not. Based on that, we’ll have to tweak our build configuration:

Karma should be run with the ChromeCustom browser.

Bonus section/off topic: Webpack/webpack-dev-server inside Docker

If you want to run Webpack or webpack-dev-server inside a container, you should use the is-docker detection and tweak a few configurations:

  1. Set host for webpack-dev-server to “0.0.0.0" if running inside a container, so it’s accessible from the outside
  2. Set watchOptions to { aggregateTimeout: 300, poll: 1000 } if running inside a container

Setting up docker-compose

Instead of running docker run with an insane number of arguments, we can use docker-compose.yml to set configuration parameters:

This will let us run “docker-compose run dev XXX”, which will start the Docker container with “XXX” as a command, for example

  • docker-compose run dev yarn
  • docker-compose run dev yarn run test
  • docker-compose run dev yarn run build

For local development

If it’s possible to work on your project without running inside Docker, that might be preferable, since you can avoid the overhead of containerization. Then, you should be able to “yarn run [whatever-command]” directly.

If you prefer to work on the project within a container, you can use “docker-compose run dev yarn run [whatever-command]” to run inside a container.

Tip: add a helper script “container.sh” to your working directory:

Then you can run “./container.sh yarn run [whatever-command]”, which is a bit shorter.

Running on CI

Make sure Docker is installed on the CI instance. (duh!)

You probably want to rebuild the container for every CI run:

After that, you can run CI build scripts inside the container the same way;

That’s all. Good luck with your containerized builds!

--

--