So, this is going to be from an absolute beginners perspective, Cypress has great docs, but they assumed I had any idea how to set up docker before I started playing with it. So this is for those that want to experiment and get a better understanding of what does what.
From the beginning, what’s an image? and what does docker really do?
Docker creates ‘images’, and along with a ‘Dockerfile’, you can ‘run’ the image along with some commands in a ‘container’.
So, an image is a blueprint for the bare minimum files needed to run what you want to run (in this case a cypress testing suite). the benefits are you can put this ‘image’ anywhere, your local machine, in a CI agent machine, or if you’re wanting to be extra, an ECS instance (which I have another more detailed article about); these are your ‘containers’, when you mount your image there, then you are ready to run your tests without any drama; and they be created and torn down super quick.
This blueprint along with the commands needed are stored in the dockerfile, it’s actually pretty simple, especially in the case of Cypress, where they have base ‘images’ for you to steal and stick in your Dockerfile. let’s look at how a dockerfile is built for cypress.
My Cypress Dockerfile
So the first thing to do is go into your directory and create a ‘Dockerfile’ in the same place as your cypress.json file, at the base of the project.
Now we can start adding things into our file, ready to build and run.
So let’s work through this, top to bottom. firstly is the base Docker image, thankfully provided by cypress, this contains the meat of what cypress needs to run, here’s a link to all their images:
All of these will work, but know that you don’t actually NEED a ‘browser’ for it to work, base:10 will generally be the one you want, it’ll still record and do all the stuff it needs with base:10, but all I know is that the weird ones that include a browser didn’t work for me, feel free to experiment.
Now it’s at this point I thought I was done because this is where all the tutorials stop; but after nothing works, you find out you need a bit extra.
This is where we use COPY, this picks out all our important folder and files, you name where the folder is, then where you want it to go/what to be named, in this case, I wanted it to have the same folder structure so that’s why it looks like I just said the same thing twice.
Firstly I COPY my package.json and RUN ‘npm install’, this ensures all the extra packages needed for my tests are picked up, along with my custom commands used later on.
Next, we need to do the bulk of our copying before we make our final command, we need our config folder for all our environment configs etc so cypress knows where to send the browser when it’s testing. then we need the cypress folder, for all our specs and fixtures and commands etc; and lastly our cypress.json, this is for us to be able to use our custom timeouts, allow us to record our runs with our project ID, link an extra reporter if we need etc.
Lastly my CMD (command), this is just the same as ‘cypress run’, but for me, I have a custom command in my package.json to send my environment config and recording key. now we’re ready to BUILD
Now let’s Build!
Now for some commands, the hard part is done. Now we have a Dockerfile all ready to go, we can ‘build’ the image, ready to run. this is our build command, I’ll break it down
$ docker build -t cypress:1 .
docker build does what it says,
-t is our ‘tag’, its the name we want to give our image, in my case I called it
cypress:1 , lastly, we need to tell docker where to build, and in most cases, it's in the directory we’re sitting in so we use
To check we were successful, run
docker images , this lists all the images created, you should see the image you just made. it looks something like this:
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
cypress 4 3fd3245a6f64 5 minutes ago 1.1 GB
Now we can run!
It’s Run Time!
Now assuming we now have our image ready to go, and we haven’t done anything weird with our Dockerfile, we’re ready to go!
$ docker run -it cypress:1
And boom, now it should be setting up the container on your local machine and should start running your specs!
Congratulations! you are now running your cypress test suite in docker!
Warning: You may have to add
--ipc=host if the tests start breaking, this is a know cypress issue and may be resolved in the future (https://github.com/cypress-io/cypress/issues/350)