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