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

cypress docker image root user misconfiguration #914

Open
ViliusS opened this issue Jul 12, 2023 · 11 comments
Open

cypress docker image root user misconfiguration #914

ViliusS opened this issue Jul 12, 2023 · 11 comments

Comments

@ViliusS
Copy link

ViliusS commented Jul 12, 2023

We tried to run cypress docker image under Jenkins which runs all docker images with non-root account. Unfortunately, this is not possible without hack and modifications in the image itself.

I've investigated this a bit and it seems that the source of this issue is that cypress is installed under /root folder by default. This is misconfiguration because /root folder is not designed to host global libraries or software. It translated then to all sorts of problems, like libraries not resolving, difficulties to run images under SaaS CI providers, etc.

My proposal is to have cypress installed into /usr/local or whatever is provided by default npm configuration under used OS.

@MikeMcC399
Copy link
Collaborator

MikeMcC399 commented Jul 14, 2023

@ViliusS

There are Jenkins examples listed in the table:

cypress-io/cypress-example-kitchensink > CI Workflow Examples

The Jenkins examples use cypress/base Docker images.

Which type of Docker images were you having problems with (base/browsers/included)?

If you were not using cypress/base perhaps you would like to try that out.

@MikeMcC399
Copy link
Collaborator

Closing due to inactivity.

@MikeMcC399 MikeMcC399 closed this as not planned Won't fix, can't repro, duplicate, stale May 24, 2024
@ViliusS
Copy link
Author

ViliusS commented May 28, 2024

@MikeMcC399 sorry, I've totally missed your previous question. We were actually using cypress/factory image. We could in theory probably use base but we really don't want to take care of installing cypress ourselves. IMHO cypress (or any software for that matter) should not be installed into /root by default, be it custom or official image.

@MikeMcC399 MikeMcC399 reopened this May 28, 2024
@MikeMcC399
Copy link
Collaborator

Thanks for your feedback and I have re-opened your issue.

@MikeMcC399
Copy link
Collaborator

The Cypress binary installs in /root

CYPRESS_CACHE_FOLDER=/root/.cache/Cypress

The Cypress npm module installs in /usr/local/lib/node_modules which is standard for npm global installation.

# Allow projects to reference globally installed cypress
# This is only set if the cypress version is passed in (thats what the + syntax stuff does.)
ONBUILD ENV NODE_PATH=${CYPRESS_VERSION:+/usr/local/lib/node_modules}

@MikeMcC399
Copy link
Collaborator

@ViliusS

Are you still experiencing problems running a custom-built Cypress Docker image with a non-root user?

If yes, could you please provide more details, as some related issues are currently being addressed and I would like to know if there are any additional problems which are not yet dealt with.

@ViliusS
Copy link
Author

ViliusS commented Jan 5, 2025

I don't remember the exact issues we have encountered previously as we don't use cypress anymore, but I tried a simple factory image test just now and this is what I've got.

20:47:22  + npx cypress run -- run --headless --e2e -b chrome -s cypress/e2e/tests/**/*.cy.ts
20:47:22  npm error code EACCES
20:47:22  npm error syscall mkdir
20:47:22  npm error path /.npm
20:47:22  npm error errno EACCES
20:47:22  npm error
20:47:22  npm error Your cache folder contains root-owned files, due to a bug in
20:47:22  npm error previous versions of npm which has since been addressed.
20:47:22  npm error
20:47:22  npm error To permanently fix this problem, please run:
20:47:22  npm error   sudo chown -R 1002:1002 "/.npm"

Steps to reproduce

  1. Make the following Dockerfile (almost carbon copy of the example):
ARG NODE_VERSION='20.18.1'
ARG CHROME_VERSION='125.0.6422.141-1'
ARG FIREFOX_VERSION='126.0.1'

FROM cypress/factory

COPY . /opt/app
WORKDIR /opt/app

RUN npm install cypress --save-dev
RUN npx cypress install
  1. Create the custom image, tag it and upload to Docker artifactory.
  2. Run the following Jenkins CI pipeline:
pipeline {
  agent {
      docker {
        image 'your-custom-image-name-and-tag'
      }
  }
  stages {
    stage('Run E2E tests') {
      steps {
          sh "npx cypress run -- run --headless --e2e -b chrome -s \"cypress/e2e/tests/**/*.cy.ts\""
      }
    }
  }
}

Jenkins is configured to run under non-root user, as most CI servers are.

As far as I remember we have encountered similar issues with included image too. At that time we have used USER 1002, WORKDIR and some other tricks in our custom image to actually make it workable in our CI environment.

To correctly solve all the issues I've seen throughout the years I think:
a) Cypress should not be installed in /root folder.
b) NPM/Cypress caching folders in base images are configured appropriately.
c) Maybe have cypress data folder defined, appropriate permissions set, and described in documentation, which can be used for all storage purposes needed. The folder can even be set in docker images with VOLUME directive, so it can be set for persistence if needed.

@MikeMcC399
Copy link
Collaborator

@ViliusS

Thank you for your response and error log!

Your error log is:

20:47:22  + npx cypress run -- run --headless --e2e -b chrome -s cypress/e2e/tests/**/*.cy.ts
20:47:22  npm error code EACCES
20:47:22  npm error syscall mkdir
20:47:22  npm error path /.npm
20:47:22  npm error errno EACCES
20:47:22  npm error
20:47:22  npm error Your cache folder contains root-owned files, due to a bug in
20:47:22  npm error previous versions of npm which has since been addressed.
20:47:22  npm error
20:47:22  npm error To permanently fix this problem, please run:
20:47:22  npm error   sudo chown -R 1002:1002 "/.npm"

The log suggests that the custom Cypress Docker image is being run under user:group 1002:1002 and that npm is attempting to create an npm cache under /.npm and failing. Normally an npm cache would be located under /home/<username>/.npm, not under /.npm.

Following the cypress/factory > Usage instructions generates a custom Cypress Docker image with the only non-root user being node (1000). The only user home directory set up is /home/node. There is no user home directory prepared for the user 1002, and there is no entry for user 1002 in /etc/passwd.

There should be ways to set this up so it works correctly. Before proceeding, I would like to understand your environment.

Could you please say which environment you are running Jenkins under?

  • Host operating system (name and version)?
  • Docker (Desktop?) version?
  • Jenkins version?

There may be some changes which should be added to the cypress/factory process and / or there may be a need for additional documentation about how to use Cypress Docker images in Jenkins successfully.

There are already some special instructions for GitHub Actions and GitLab, so it would not be surprising if there is some need to add instructions for Jenkins.

I understand if you say that you are no longer using Cypress anymore that you may not want to work on this. Please just let us know either way.

@ViliusS
Copy link
Author

ViliusS commented Jan 6, 2025

@ViliusS

Thank you for your response and error log!

Your error log is:

20:47:22  + npx cypress run -- run --headless --e2e -b chrome -s cypress/e2e/tests/**/*.cy.ts
20:47:22  npm error code EACCES
20:47:22  npm error syscall mkdir
20:47:22  npm error path /.npm
20:47:22  npm error errno EACCES
20:47:22  npm error
20:47:22  npm error Your cache folder contains root-owned files, due to a bug in
20:47:22  npm error previous versions of npm which has since been addressed.
20:47:22  npm error
20:47:22  npm error To permanently fix this problem, please run:
20:47:22  npm error   sudo chown -R 1002:1002 "/.npm"

The log suggests that the custom Cypress Docker image is being run under user:group 1002:1002 and that npm is attempting to create an npm cache under /.npm and failing. Normally an npm cache would be located under /home/<username>/.npm, not under /.npm.

Following the cypress/factory > Usage instructions generates a custom Cypress Docker image with the only non-root user being node (1000). The only user home directory set up is /home/node. There is no user home directory prepared for the user 1002, and there is no entry for user 1002 in /etc/passwd.

In theory, under Linux, you don't need home directory or entry in /etc/passwd if you are not logging in the user. You can run Docker image under any ID. This is why such images as eclipse-temurin, or nginx works under Jenkins/GitHub Actions without modifications.

NPM cache folder can be preset to /tmp/.cache or any other global folder in advance via NPM_CONFIG_CACHE. I think we did exactly that in our custom image. However, that could probably could go into base image where node is installed.

There should be ways to set this up so it works correctly. Before proceeding, I would like to understand your environment.

Could you please say which environment you are running Jenkins under?

  • Host operating system (name and version)?
  • Docker (Desktop?) version?
  • Jenkins version?

Rocky Linux 9.5
Docker 27.4.0 (installed from official docker-ce RPM)
Jenkins 2.491 (installed from official Jenkins RPM)

There may be some changes which should be added to the cypress/factory process and / or there may be a need for additional documentation about how to use Cypress Docker images in Jenkins successfully.

There are already some special instructions for GitHub Actions and GitLab, so it would not be surprising if there is some need to add instructions for Jenkins.

I understand that all these issues have workarounds, but then again, they are workarounds :). That's not the point why I have created this issue. IMHO, ideally cypress image should be runnable without modifications. I saw instructions for GitHub Actions, but to tell you the truth cypress image is the only image I have encountered which requires these instruction.

I also glanced a bit at the current Dockerfile for images. If cypress is not installed into /root I think you could loose a lot of chmod hacks which are currently lingering in some places. Not to name a much cleaner documentation.

I understand if you say that you are no longer using Cypress anymore that you may not want to work on this. Please just let us know either way.

That's fine, I can spare some time :)

I have also remembered that we tried to make custom image without installing cypress into it. This way we tried to achieve one custom image usable by multiple projects, which used different cypress versions (via package.json). We then encountered another set of issues regarding permissions and the same /root folder.

@MikeMcC399
Copy link
Collaborator

@ViliusS

Thank you for your details, your suggestions and your insights!

I will link any PRs that I propose back to this issue.

@MikeMcC399
Copy link
Collaborator

The following documentation updates have been added to cover workarounds arising from non-root node usage:

README Known problems section

examples/included-as-non-root

I was not able to test these in a Jenkins Docker agent environment so far.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants