typicode / husky

Git hooks made easy 🐶 woof!
https://typicode.github.io/husky
MIT License
32.63k stars 1.03k forks source link

[Docker] Husky fail to install on docker image with Node 16 #991

Closed Th3S4mur41 closed 2 years ago

Th3S4mur41 commented 3 years ago

Husky as devDependency with a prepare script to install the hooks according to documentation.

The prepare step fails on the node:latest container due to missing permissions.

Github Actions job is configured as follow:

  test:
    runs-on: [self-hosted, linux]
    container: mcr.microsoft.com/playwright:focal
    steps:
      - uses: actions/checkout@v2
      - run: npm ci --no-optional --no-audit --prefer-offline --progress=false
      - run: HOME=/root npm run test:playwright

This is the error ouptut from the CI:

prepare
> husky install

husky - Git hooks failed to install
/__w/project_a/project_a/node_modules/husky/lib/index.js:33
        throw e;
        ^

Error: EACCES: permission denied, mkdir '.husky/_'
    at Object.mkdirSync (node:fs:1324:3)
    at Object.install (/__w/project_a/project_a/node_modules/husky/lib/index.js:23:12)
    at Object.install (/__w/project_a/project_a/node_modules/husky/lib/bin.js:27:41)
    at Object.<anonymous> (/__w/project_a/project_a/node_modules/husky/lib/bin.js:39:22)
    at Module._compile (node:internal/modules/cjs/loader:1109:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)
    at Module.load (node:internal/modules/cjs/loader:989:32)
    at Function.Module._load (node:internal/modules/cjs/loader:829:14)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12)
    at node:internal/main/run_main_module:17:47 {
  errno: -13,
  syscall: 'mkdir',
  code: 'EACCES',
  path: '.husky/_'
}
npm ERR! code 1
npm ERR! path /__w/project_a/project_a
npm ERR! command failed
npm ERR! command sh -c husky install

The same script runs fine on e.g. node:lts-buster container

Check out https://github.com/Th3S4mur41/bug-playwright-husky/pull/1 for an example

typicode commented 3 years ago

Have you tried https://typicode.github.io/husky/#/?id=disable-husky-in-cidocker ? Or would you have a way to fix the permission issue ?

Th3S4mur41 commented 3 years ago

Both options: --ignore-scripts and is-ci are indeed possible workarounds have however their downside...

--ignore-script also prevents other scripts from running, which makes it unusable in some projects.

is-ci is working to, but I'd rather not add a dependency just for this purpose

A better workaround would be to skip the husky install when HUSKY is set to 0 instead of only skipping the hooks. That would address both concerns mentioned above,

In the end this is still a bug though, but unfortunately I don't have a fix for it yet

drptbl commented 3 years ago

Same issue on docker image with node 14.

typicode commented 3 years ago

I see, what about npm set-script prepare '' before?

Th3S4mur41 commented 3 years ago

Need to test, but that would only be an option if husky is the only script in prepare. I wouldn't want to replicate half of my prepare script in my CI script just to disable husky. This would be error prone, considering that somebody that would edit the script in package.json would most probably forget about the CI script.

As mentioned above, wouldn't the easiest solution be to check the HUSKY variable before install, just like it is done before the hooks?

gopricy commented 3 years ago

had exact same issue, any update on this?

Th3S4mur41 commented 3 years ago

My current workaround is to run the CI in node:lts-buster instead of node But that won't hold forever

vanduc1102 commented 3 years ago

same issue, i have to use RUN yarn install --ignore-scripts

Th3S4mur41 commented 3 years ago

Workaround just broke as Node 16 has been promoted to LTS 😞

heatherKoo07 commented 2 years ago

Hi, I have the same issue with node:lts-alpine.

Here's a part of my docker build logs

Building web
Step 1/8 : FROM node:lts-alpine
 ---> 44e24535dfbf
Step 2/8 : WORKDIR '/app'
 ---> Using cache
 ---> a325b039be4f
Step 3/8 : COPY package.json .
 ---> Using cache
 ---> 12ecf0f20f50
Step 4/8 : RUN npm install
 ---> Running in 7bdc6515e6c7
npm WARN deprecated querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
npm WARN deprecated uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.

> kif_new_frontend@1.0.0 prepare
> husky install

added 1199 packages, and audited 1200 packages in 2m

As you can see, there's no message husky - Git hooks installed right after > husky install. When I run npm install on local machine, I can see the installed message tho.

How do you run the husky in the docker container? Because of the above issue, .husky/_ directory is not created in the container which failed the pre-commit script.

AnshuPrince commented 2 years ago

Added husky globally before installing packages, sorry thats all i got at the moment RUN npm install husky -g RUN npm install --production

vanduc1102 commented 2 years ago

I moved to simple-git-hooks because of this issue. 😢

typicode commented 2 years ago

Thank you for the repo! I tried to run the GitHub actions and it seems to have been fixed: https://github.com/typicode/bug-playwright-husky/runs/5267015618?check_suite_focus=true

Maybe supporting HUSKY=0 would be good. However I'm not aware of any other tool or command working this way (i.e. can be called but due to an env variable would do nothing). Since there are other ways, I'm not sure if it would be good to add yet another way.

I'll revisit this idea for husky 8 though (which is planned to release when Node 12 reaches end of support).

Thanks for the feedback :+1:

samir-satpute commented 2 years ago

had exact same issue, any update on that?

Ren22 commented 2 years ago

any update would be much appreciated

typicode commented 2 years ago

Husky 8 now supports HUSKY=0 to disable Git hooks installation.

dekelev commented 2 years ago

Thanks @typicode, but I think it still doesn't work. I'm getting #15 34.82 npm ERR! command sh -c husky install error when building the Dockerfile locally.

I've upgraded husky to v8.0.0 in package.json (dev dependency), ran npm i, set ARG HUSKY=0 in the Dockerfile and removed RUN npm install husky -g before running RUN npm ci --only=production.

Th3S4mur41 commented 2 years ago

@typicode update the demo repo to run scripts again and set the HUSKY env variable to 0. Unfortunately it seems like the install still tried to run https://github.com/Th3S4mur41/bug-playwright-husky/runs/6348285917?check_suite_focus=true

typicode commented 2 years ago

@Th3S4mur41 I've forked it and it works here https://github.com/typicode/bug-playwright-husky/runs/6361294637?check_suite_focus=true. I didn't investigate though why it works in the fork and not in your repo :thinking: I've also updated husky to 8.0.1 to trigger another action.

Th3S4mur41 commented 2 years ago

@typicode thanks, found the error... Somehow the package-lock was not properly committed. Working now 👍

dekelev commented 2 years ago

@typicode It seems that this solution requires moving husky from the dev dependencies to the production dependencies. Am I missing something here?

I see now that my scripts has "prepare": "husky install", so I guess that's why.

ShinJustinHolly3317 commented 2 years ago

npm will execute prepare right after install packages. When you npm ci --production then npm execute prepare

you can checkout here


prepare (since npm@4.0.0)


so solution is that you move your husky to optionalDependencies this will ignore when building code on production server.

MikeMcC399 commented 1 year ago

@ShinJustinHolly3317

Thanks for your tip! There is a typo though in your post. The package.json section is called optionalDependencies.

Should this go into the README to say:

npm install husky -O

instead of

npm install husky -D ?

ShinJustinHolly3317 commented 1 year ago

@MikeMcC399 Ahh.. I'll correct the typo then. And yes, npm install -o solve this problem for me. Also I think that's a logical solution, not a work around one.

rajahn1 commented 10 months ago

npm will execute prepare right after install packages. When you npm ci --production then npm execute prepare

you can checkout here

prepare (since npm@4.0.0)

  • Runs any time before the package is packed, i.e. during npm publish and npm pack
  • Runs BEFORE the package is packed
  • Runs BEFORE the package is published
  • Runs on local npm install without any arguments
  • Run AFTER prepublish, but BEFORE prepublishOnly
  • NOTE: If a package being installed through git contains a prepare script, its dependencies and devDependencies will be installed, and the prepare script will be run, before the package is packaged and installed.
  • As of npm@7 these scripts run in the background. To see the output, run with: --foreground-scripts.

so solution is that you move your husky to optionalDependencies this will ignore when building code on production server.

Thanks bro <3

PedroS11 commented 8 months ago

I'm using husky v9 with node20 and this is no longer an issue. The prepare command runs but husky leaves a "warning" message and the execution continues.

My Dockerfile

# First Stage: Install Dependencies & Build
FROM node:20-alpine AS builder
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn install
COPY . .
RUN yarn build

# Second Stage: Run Application
FROM node:20-alpine AS final
WORKDIR /usr/src/app
COPY --from=builder ./usr/src/app/dist ./dist
COPY package.json yarn.lock ./
RUN yarn install --production
CMD [ "yarn", "start" ]

image