Skip to content

Commit

Permalink
Introduce the cypress/factory image (#812)
Browse files Browse the repository at this point in the history
* in progress

* latest updates

* latest changes

* Second attempt

* Latest changes

* Remove original docker factory

* Rename second factory iteration to factory

* Fixes for installing chrome and cypress standalone

* add test project

* more test cases

* readme updates mostly

* readme update

* remove unused factory test.

* naming docker images in docker compose

* Clean up some todos, add webkit install step

* rename install scripts

* minor updates

* use edge stable

* docs and edge version update

* add tags

* use ENV instead of yml anchors

* testing circle build

* new image???

* try again

* check envs

* experiment

* just update bash_env

* more testing

* maybe this

* i don't think this is going to work

* ?

* maybe we need to make it first?

* ?

* :/

* >:(

* derp

* use current directory

* buildx

* override platform

* load docker images

* more experiments

* target isn't a key word

* grumpy

* actually load arm64 version

* testing?

* circle syntax

* once again

* try this

* try testing arm64??

* random buildkit workaround???

* more robust env setting

* can't inspect i guess

* try it again without syntax errors

* try using buildx

* yml

* try docker driver because i don't want to run a local registry 😭

* make a new builder

* try with a local registry???

* testing

* Try pushing to a local repo

* fiddle fiddle

* wait longer i guess

* oops typo

* try it on an arm machine

* env

* yay it failed like it should have!

* lol, i bet this fails due to something dumb

* told you so

* typo

* colon

* schema violations, i'll be back

* maybe this?

* don't matrix resource class

* no s

* fix syntax

* lots of changes so low probability that this works right off.

* fix some typos and rename some things.

* run all commands on all included

* i <3 yaml

* combine again

* not a string

* combine into one workflow

* conditional testing

* alias

* alias in the right place

* changes around building images to get us ready for pushing.

* name syntax error?

* maybe this?

* yml is great

* remove dead end

* missed a colon

* omg

* use correct env

* fix browsers push job

* update halt if exist

* un-comment workflows

* don't use undeclared parameters

* circle cleanup

* more cleanup

* reduce more

* i had to mess something up

* minor updates

* update comment

* check versions

* remove params

* try again

* check against the right version

* check cypress version

* new included image version string

* clean up

* updated notes on env file

* Self review changes

* more self review changes

* remove test project and test folder

* Updated readme

* updating contributing guide

* tweak

* note

* Remove scripts

* Apply suggestions from code review

Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>

* pr updates

* update

* Apply suggestions from code review

Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>

* Moved api up

* specify further in api

* use inherit for logging

* adding example reducing the size of the docker container.

* update default version location

* Update factory/README.md

Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>

* changing command to docker compose from docker-compose

* Adding instructions to build locally to the contributing document.

* adding context to push jobs

* use newest cypress version

* add no_output_timeout for included container.

* move timeout

* release latest tag for the factory

* Apply suggestions from code review

Co-authored-by: Paul Jaffre <jaffrepaul@gmail.com>

* Update factory/README.md

* Update factory/README.md

Co-authored-by: Paul Jaffre <jaffrepaul@gmail.com>

* Update factory/README.md

* Update factory/README.md

* Update factory/README.md

* Apply suggestions from code review

Co-authored-by: Paul Jaffre <jaffrepaul@gmail.com>

* add brief one off release instructions.

* try quotes

* more quotes

* fix versions test

* try it again

* PR Feedback

Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
Co-authored-by: Paul Jaffre <jaffrepaul@gmail.com>
  • Loading branch information
3 people authored Jan 17, 2023
1 parent 5f5272a commit 4b2ebca
Show file tree
Hide file tree
Showing 77 changed files with 1,387 additions and 3,550 deletions.
82 changes: 24 additions & 58 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,79 +12,47 @@ All contributors are expecting to abide by our [Code of Conduct](https://github.

⚠️ As a rule, unless there are extraordinary circumstances, we do NOT replace the existing Docker images. Replacing the images already used by people is dangerous, since it replaces the versions of tools without warning. We have such failed experience once, and do not want to repeat this mistake. Thus instead of replacing an existing image, in 99% of the cases we publish a new Docker image.

### Add new base image
### Building locally

To create a new base image follow these steps
We use docker compose to build the factory locally.

1. run `yarn add:base -- <new version>` script. For example `yarn add:base -- 13.6.0`

It will create a new folder `base/<new version>` and output versions of tools installed: Node, npm, yarn, etc. See [generate-base-image.js](scripts/generate-base-image.js) file for details.

2. open a pull request.

The new image will be built and tested on CI and pushed to Docker Hub once the PR is approved and merged to `master`.

**note:** we install Chinese fonts in the base image to allow correct testing of [cypress-documentation](https://github.com/cypress-io/cypress-documentation) site that includes several translations of the Cypress docs. Without Chinese fonts the pages have broken rendering.

### Add new browser image

To create a new image with the specific browser versions needed to run your cypress tests.

1. Run `yarn add:browser <base image tag> --chrome=<chrome version> --firefox=<firefox version> --edge`. For example `yarn add:browser 16.5.0 --chrome=94.0.4606.71 --firefox=93.0`.

This will create a new folder `browser/node<node version>-chrome<chrome version>-ff<firefox version>-edge` See [generate-browser-image.js](scripts/generate-browser-image.js) file for details.

2. Open a pull request.

**Important ⚠️** In order to properly generate a browser image, you must specify a version of Chrome, or a version of Firefox, or a version of Edge.

**note:** The Edge browser will always default to the latest stable release. There is currently no way to specify the downloaded version. For this reason, when generating an image with Edge support users should only pass `--edge`.

**note:** No major browsers are currently compatible with `arm64`, so browsers images will be missing those browsers on `linux/arm64` architecture. As time passes and these become available, we will introduce them to the `arm64` images as well: https://github.com/cypress-io/cypress-docker-images/issues/695.

### Add new included image

To create a new image with Cypress pre-installed globally

1. Run `yarn add:included -- <Cypress version> <base image tag>`. For example `yarn add:included -- 9.4.1 cypress/browsers:node16.13.2-chrome97-ff96`.
```bash
cd factory
docker compose build factory
```

**Important ⚠️** please use `cypress/browsers` Docker image with the latest Node version matching the major version of Node included with Cypress. For example, if Cypress is shipping 16.5.0 and the latest 16.x is 16.14.0, ship the included image with Node 16.14.0.
With the factory image built, you can now build the other included images

This will create a new folder `included/<Cypress version>` See [generate-included-image.js](scripts/generate-included-image.js) file for details.
```bash
# This builds the 'included' image specified in the docker-compose file.
docker compose build included

2. Open a pull request.
# This builds all images specified in the docker-compose file.
docker compose build
```

#### Handling included images with different node versions
Or you can then run tests in the test-project

If there is already a `cypress/included` image with a specific version, but you need a different Node version or browser version, just create a new included image per the instructions above and a folder with the name `<Cypress version>-<base image tag> will be created.`
```bash
cd test-project

**Important ⚠️** This only applies if there is an existing `cypress/included` image with the same version.
# set the environment variables from factory/.env in your terminal.
set -a && . ../.env && set +a

## Tagging the latest image
# run the test in an image built on top of the factory.
docker compose run test-factory-all-included
```

We build individual base images that match Node versions: `10.18.1`, `12.12.0`, `12.18.2`, etc. We also tag some of the images with major version: `base:10`, `base:12`. We also tag one image `base:latest`. In general, you should use the explicit version like `base:12.18.0` because it guarantees that the Docker image will never be suddenly updated.
### Updating images

To tag new image, like `base:12.18.2` need to do the following from a local machine
To produce new updated images, simply open a PR with the desired version(s) updated in the `factory/.env` file. Once the PR is merged into master the corresponding images will be pushed to dockerhub.

```text
# pull the image to tag
$ docker pull cypress/base:12.18.2
# tag that image with major version
$ docker tag cypress/base:12.18.2 cypress/base:12
# tag that image with "latest"
$ docker tag cypress/base:12.18.2 cypress/base:latest
# push the new images (which are the same)
$ docker push cypress/base:12
$ docker push cypress/base:latest
```
In general, `factory/.env` master should contain the latest versions we officially support. If you need to release an older version please modify `circle.yml` to push releases from a feature branch instead of setting the version in master to older versions.

## Minimize image sizes

By default, the current base image is `bullseye-slim`. This dramatically decreases the size of all images. Other optimizations have been made to the Dockerfiles per Docker's recommendations.

In order to allow for older images to be smaller, you can run the scripts above using existing node versions, Cypress versions, and browser versions. The scripts will recognize that a folder already exists, and append `-slim` to the folder. You can then update the folder name in your workflow, and use the images like you already were.

Node versions less than or equal to Node 14 will use the `buster-slim` base image if they are recreated. Older images may still rely on `buster`.

To see the final size of an image, you can use command [`docker images`](https://docs.docker.com/engine/reference/commandline/images/)
Expand Down Expand Up @@ -157,8 +125,6 @@ In CI, the images are built and tested in real `arm64` and `x64` architectures.
└─────────────────────────────────────────────┘
```

It would be nice to re-publish the Docker Hub images verbatim to ECR instead of building twice, but more work needs to be done in this area - see the `push-images` step in `circle.yml` for details.

A current limitation is that no `arm64` images have browser binaries - see https://github.com/cypress-io/cypress-docker-images/issues/695 for details. [`global-profile.sh`](./scripts/for-images/global-profile.sh) is placed in `/etc/bash.bashrc`, so Arm Docker users will see a warning about this limitation.

### Updating images to add `linux/arm64`
Expand Down
18 changes: 12 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@

These images provide all of the required dependencies for running Cypress in Docker.

We build three main images, click on the image name to see the available tags and versions.
We build four images, click on the image name to see the available tags and versions.

| Image | Default | Description | Monthly pulls |
| ---------------------------- | --------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [cypress/base](base) | `cypress/base:16.13.0` | All operating system dependencies, no Cypress, and no browsers. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/base.svg?maxAge=604800)](https://hub.docker.com/r/cypress/base/) |
| [cypress/browsers](browsers) | `cypress/browsers:chrome69` | All operating system dependencies and some browsers. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/browsers.svg?maxAge=604800)](https://hub.docker.com/r/cypress/browsers/) |
| [cypress/included](included) | `cypress/included:9.4.1` | All operating system dependencies, Cypress, and some browsers installed globally. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/included.svg?maxAge=604800)](https://hub.docker.com/r/cypress/included/) |
| Image | Default | Description | Monthly pulls |
| -------------------------------------------------------------- | --------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| [cypress/factory](https://hub.docker.com/r/cypress/factory/) | `cypress/factory:1.0.0` | A base image template which can be used with ARGs to create a custom docker image. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/factory.svg?maxAge=604800)](https://hub.docker.com/r/cypress/factory/) |
| [cypress/base](https://hub.docker.com/r/cypress/base/) | `cypress/base:16.13.0` | All operating system dependencies, no Cypress, and no browsers. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/base.svg?maxAge=604800)](https://hub.docker.com/r/cypress/base/) |
| [cypress/browsers](https://hub.docker.com/r/cypress/browsers/) | `cypress/browsers:chrome69` | All operating system dependencies, no Cypress, and some browsers. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/browsers.svg?maxAge=604800)](https://hub.docker.com/r/cypress/browsers/) |
| [cypress/included](https://hub.docker.com/r/cypress/included/) | `cypress/included:9.4.1` | All operating system dependencies, Cypress, and some browsers installed globally. | [![Docker Pulls](https://img.shields.io/docker/pulls/cypress/included.svg?maxAge=604800)](https://hub.docker.com/r/cypress/included/) |

Of these images, we provide multiple tags for various operating systems and specific browser versions. These allow you to target specific combinations you need.

Expand All @@ -20,10 +21,15 @@ It is recommended to use a specific image tag, and not rely on the `default` tag

All of the images and tags are published to DockerHub under

- [https://hub.docker.com/r/cypress/factory](https://hub.docker.com/r/cypress/factory)
- [https://hub.docker.com/r/cypress/base](https://hub.docker.com/r/cypress/base)
- [https://hub.docker.com/r/cypress/browsers](https://hub.docker.com/r/cypress/browsers)
- [https://hub.docker.com/r/cypress/included](https://hub.docker.com/r/cypress/included)

## Cypress/Factory

Don't see the exact combination of cypress, node and browser versions you need for your test environment? Checkout our [cypress/factory](factory). You can use it to generate a custom image to fit your needs.

## Examples

These images have all dependencies necessary to install and run Cypress. Just install your NPM dependencies (including Cypress) and run the tests. We utilize many of these docker images in our own projects, with different CI providers.
Expand Down
Loading

0 comments on commit 4b2ebca

Please sign in to comment.