Add your Cypress tests into a docker container and run from a VPS

Add your Cypress tests into a docker container and run from a VPS

I have been writing a lot of tests lately with Cypress, and one thing that I noticed when running over night using a scheduled task is that they really slow down the whole server performance as it's taking huge amount of CPU and RAM.

Kind of expected as Cypress is running Electron.

I don't like having a single application crippling the server, so:

Why not "dockerize" the tests, and run on a powerful VPS and only pay the for time it needs to be run?

As of now my tests are running on a Windows server and upgrading the instance size wouldn't be cost effective, as I need that much CPU/RAM only for couple of hours per day.

Increase test performance while decreasing costs

We can achieve it following this steps:

  • Spin a powerful Linux VPS on the cloud (AWS, Azure, Google, Linode etc)
  • Install docker
  • Run the cypress tests inside the docker container
  • Delete the VPS we just created

Of course the above would be automated with some sort of script that start on a given time every day.

Create the project inside the new VPS

Login to the new VPS via ssh then:


# Create the project folder and cd into it

mkdir myproject && cd myproject

# Create an empty dockerfile

touch dockerfile

# Copy is_rsa from your local pc to the VPS or create a new one, this is needed to clone the repo later using ssh

# Copy your local openvpn file or create one. Ex: my-vpn-config.ovpn

Your folder structure should look like this:

#### myproject
   # dockerfile
   # id_rsa
   # my-vpn-config.ovpn

Dockerfile

The dockerfile in my case needed to accomplish this tasks:

  • Install required packages
  • Install Chrome
  • Create folders and set permissions
  • Run openvpn
  • Update HOST file
  • Clone a repository using ssh
  • Run tests

It's my first time messing with a dockerfile, I know that using root is not the best practice but this is just an example on how to achieve running tests on a docker container, use it just as an inspiration to forge your own dockerfile

nano dockerfile
# Using ubuntu base image
FROM ubuntu:latest

# Package install explanation:
# openvpn: OpenVPN client
# iputils-ping: ping command
# openssh-client: ssh command
# apt-utils: apt-get command
# curl: curl command
# gcc: gcc command, node dependency
# g++: g++ command, node dependency
# make: make command, node dependency
# libgtk2.0-0: Cypress dependency
# libgtk-3-0: Cypress dependency
# libgbm-dev: Cypress dependency
# libnotify-dev: Cypress dependency
# libgconf-2-4: Cypress dependency
# libnss3: Cypress dependency
# libxss1: Cypress dependency
# libasound2: Cypress dependency
# libxtst6: Cypress dependency
# xauth: Cypress dependency
# xvfb: Cypress dependency
# wget: wget command, chrome
# gnupg: gnupg command, chrome
# ca-certificates: ca-certificates command, chrome
# x11-utils: x11-utils command, chrome
# git: git command, clone repo
# nodejs: nodejs command, run cypress tests

RUN apt-get update && \
    apt-get install -y openvpn \
    iputils-ping \
    openssh-client \
    apt-utils \
    curl \
    gcc \
    g++ \
    make \
    libgtk2.0-0 \
    libgtk-3-0 \
    libgbm-dev \
    libnotify-dev \
    libgconf-2-4 \
    libnss3 \
    libxss1 \
    libasound2 \
    libxtst6 \
    xauth \
    xvfb \
    wget \
    gnupg \
    ca-certificates \
    x11-utils \
    git && \
    curl -sL https://deb.nodesource.com/setup_16.x | bash - && \
    apt-get install -y nodejs

# Get Google chrome and install

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

ENV DISPLAY=:99

# Copy the OpenVPN configuration file and the GitLab SSH key to the container

COPY my-vpn-config.ovpn /etc/openvpn/

COPY id_rsa /root/.ssh/id_rsa

# Set the permissions for the SSH key

RUN chmod 400 /root/.ssh/id_rsa

# Set the environment variables for the OpenVPN connection

ENV VPN_USERNAME=vpnUsernameHere

ENV VPN_PASSWORD=vpnPasswordHere

# Create a script to start the OpenVPN connection and run the Cypress tests

# cypress.env.json is base 64 encoded then decoded in the Dockerfile

RUN echo '#!/bin/bash\n\
openvpn --config /etc/openvpn/my-vpn-config.ovpn --auth-user-pass <(echo -e "$VPN_USERNAME\n$VPN_PASSWORD") &\n\
while ! ping -c1 -W 1 8.8.8.8; do sleep 1; done\n\
sleep 10\n\
ssh-keyscan myCompany.com >> /root/.ssh/known_hosts\n\
git clone --branch dev_sql [email protected]:user/cypress-automation.git\n\
cd cypress-automation\n\
mkdir ./cypress/logs/\n\
npm install\n\
npm run sd:test\n' > /root/start.sh

# Set the permissions for the script

RUN chmod +x /root/start.sh

# Expose the Cypress test results

VOLUME /root/myproject/cypress/results

# Start the Xvfb server and run the script

CMD /bin/bash -c "Xvfb $DISPLAY -screen 0 1024x768x16 -ac & /root/start.sh"

Build the image

docker build -t cypress-tests .

Run the container

docker run -p 8080:443  --add-host myCompany.com:192.100.23.222 --privileged --rm -it cypress-tests
Show Comments