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
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
# 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 18.104.22.168; 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:22.214.171.124 --privileged --rm -it cypress-tests