Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add slim build support #276

Closed

Conversation

fabiocarneiro
Copy link

@fabiocarneiro fabiocarneiro commented Mar 10, 2020

Motivation

I was trying to use Alpine (node:10-alpine ~25mb), but after spending some time fighting with Glibc I saw that you are already aware that it does not seem to be possible. This was discussed here on #110 and #206.

The second-best option for me is slim images. While node:10 (the base image for cypress/base) is based on the full Debian (~330mb), there are node images available that come from Debian slim (45mb).

Additional info

I am also including the Cypress binaries. Although it makes the image much heavier, the binary will have to be downloaded anyway.

In my opinion, this is essential for proper CI. Downloading cypress after the application code is transferred to the container (with npm/yarn) adds time to the build that is not needed. Even if the image gets much heavier with Cypress already in it, it saves time in the end.

When using CIs that are based on docker, it is essential to build a docker image also for cypress. By using this image with slim and cypress already installed, I was able to reduce my build times by 50% (from 10 minutes to 5)

Proposed image naming

cypress/slim:10-4.0.2

Sizing

$ DOCKER_BUILDKIT=1 docker build -t cypress/slim:10-4.0.2 .
[+] Building 152.0s (6/6) FINISHED                                                                                                                                                                                                                                                          
 => [internal] load .dockerignore                                                                                                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                                        0.0s
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                                                   0.1s
 => => transferring dockerfile: 744B                                                                                                                                                                                                                                                   0.0s
 => [internal] load metadata for docker.io/library/node:10-slim                                                                                                                                                                                                                       11.3s
 => CACHED [1/2] FROM docker.io/library/node:10-slim@sha256:ce0b8ec37c669bb12da1683a265a2aa6f85cdd7a692d959f7c48e8c26cc37585                                                                                                                                                           0.0s
 => [2/2] RUN apt-get update &&     apt-get install --no-install-recommends -y         libgtk2.0-0         libgtk-3-0         libnotify-dev         libgconf-2-4         libnss3         libxss1         libasound2         libxtst6         xauth         xvfb         wget         132.1s
 => exporting to image                                                                                                                                                                                                                                                                 8.4s
 => => exporting layers                                                                                                                                                                                                                                                                8.4s
 => => writing image sha256:4b18f200e840dca65ccab68f4882ae5c893c856716b7ee1cf3283ecf47728361                                                                                                                                                                                           0.0s 
 => => naming to docker.io/cypress/slim:10-4.0.2 
REPOSITORY                                                 TAG                     IMAGE ID            CREATED             SIZE                                                                                                                                                             
cypress/slim                                               10-4.0.2                4b18f200e840        30 seconds ago      847MB

Remaining work

  • Approval of the idea
  • Figure out why wget on the cypress download link fails certificate
  • Integration with CI
  • Build for more versions

@CLAassistant
Copy link

CLAassistant commented Mar 10, 2020

CLA assistant check
All committers have signed the CLA.

@bahmutov
Copy link
Contributor

I am not sure the image size has much to do with CI system UNLESS CI system does not cache images. For example GitHub Actions https://github.com/bahmutov/cypress-gh-action-included/runs/498639926?check_suite_focus=true just spends 1 minute to get the image cypress/included:4.1.0 up and running

GitLab CI takes 1 min and 22 seconds to pull cypress/included:3.8.3 image https://gitlab.com/cypress-io/cypress-example-included/-/jobs/421129280

So I don't think the size of the Docker image matters that much - it depends on the CI caching a lot more.

@fabiocarneiro
Copy link
Author

fabiocarneiro commented Mar 11, 2020

@bahmutov I'm on CircleCI and I agree, the image is often cached and pulling the image is usually fast.

That is one more point for having Cypress binaries embedded in the image. Downloading them in a separate step takes much longer than downloading a heavier image. By doing this, it got 50% faster on my builds.

@bahmutov
Copy link
Contributor

@fabiocarneiro
Copy link
Author

@bahmutov Yeah. Although now is very obvious, I didn't realize included meant with cypress. I thought it was with browsers or something else. (Which is also true, since it extends from cypress/browsers)

The Slim option could still be a valid idea, but...

I'm very curious how your images can achieve 830mb with so many added layers, browsers, and when you start from 300 mb+. This one starting from 45mb, no browsers, and a single layer added is going to 850mb.

@archfz
Copy link

archfz commented Oct 4, 2020

I have managed to achieve a whopping 3x smaller cypress base image. This is significant enough to validate for an additional officially supported image. I have only made a few changes to the current base image. The base image is 1266mb (docker inspect cypress/base:12 | grep Size) and the image below is 419mb.

Image size is often very important. Gitlab CI using shared runners doesn't quite cache effectively the image, especially if you are using your own built images (based on cypress base image you add additional libraries), also using DIND runners (docker in docker) which is quite popular, you don't get any caching of the images. I think a lot of bandwidth is wasted with docker images in these times.

FROM node:12.18.3-slim

RUN apt-get update && \
  apt-get install --no-install-recommends -y \
  libgtk2.0-0 \
  libgtk-3-0 \
  libnotify-dev \
  libgconf-2-4 \
  libgbm-dev \
  libnss3 \
  libxss1 \
  libasound2 \
  libxtst6 \
  xauth \
  xvfb \
  # clean up
  && rm -rf /var/lib/apt/lists/*

RUN npm install -g npm@latest && rm ./opt/yarn-v1.22.4/ -rf && rm /usr/local/bin/yarn
RUN npm --version

# a few environment variables to make NPM installs easier
# good colors for most applications
ENV TERM xterm
# avoid million NPM install messages
ENV npm_config_loglevel warn
# allow installing when the main user is root
ENV npm_config_unsafe_perm true

# Node libraries
RUN node -p process.versions

I have change the base image to the slim node one. I have also removed the Chinese fonts. I strongly believe this should be an optimized image with the most basic things, so chinese fonts shouldn't be included here, especially since they were bloating the image size with 100mb. I have also removed yarn as that's another thing that is extra and should not be in such an image.

Since this is such an easy change I think it could be easily added to the official ones. I have only marginally tested this image though. @bahmutov What do you say? Should I create a separate issue?

@archfz
Copy link

archfz commented Oct 4, 2020

With this simple change managed to reduce my cypress-dind image from 2.1gb to 1.3gb.

@Romiko
Copy link

Romiko commented Nov 15, 2020

This is a no brainer. What is the status of this PR?

@bahmutov
Copy link
Contributor

I still need to build one of these slim images and try to run the full set of tests using it

@kautkata
Copy link

kautkata commented Dec 1, 2020

@archfz You actually can go even further xauth is actually not needed as you can disable all Xvfb authentication.

As our CI tests will run in k8s cluster I'm going even further I'm splitting Xvfb into dedicated image based on alpine with size 26.8MB

@admah
Copy link
Contributor

admah commented Mar 2, 2022

Closing this as slim images are now supported with the merging of #597. If you need specific images, you can generate those and submit per the contribution guide.

@admah admah closed this Mar 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants