cli icon indicating copy to clipboard operation
cli copied to clipboard

[BUG] npm run on a read-only filesystem does not work

Open dynk opened this issue 3 years ago • 9 comments

Is there an existing issue for this?

  • [X] I have searched the existing issues

This issue exists in the latest npm version

  • [X] I am using the latest npm

Current Behavior

After upgrading the node version to my service (node: v18.5.0 to v18.6.0, npm: from 8.12.1 to 8.13.2), my service is not able to start up anymore:

`npm WARN logfile could not be created: Error: EROFS: read-only file system, open '/usr/src/app/.npm/_logs/2022-07-15T13_35_32_477Z-debug-0.log'

[email protected] start:prod npm run db:migrate && node dist/src/main

npm ERR! code EROFS npm ERR! syscall open npm ERR! path /tmp/startprod65789232523.sh npm ERR! errno -30 npm ERR! rofs EROFS: read-only file system, open '/tmp/startprod65789232523.sh' npm ERR! rofs Often virtualized file systems, or other file systems npm ERR! rofs that don't support symlinks, give this error.

npm ERR! Log files were not written due to an error writing to the directory: /usr/src/app/.npm/_logs npm ERR! You can rerun the command with --loglevel=verbose to see the logs in your terminal`

This is due to recent changes in @npmcli/run-script which now writes scripts into the tmpdir(). (PR). This is causing our service to break since it is running in a read-only filesystem.

Is this an expected behavior? If so what would be the recommendation to run our service now?

Expected Behavior

Able to run the service with newest npm and nove version in a read-only file system.

Steps To Reproduce

Sample of docker image with working node/npm version:

`FROM node:18.5.0-alpine as node_18_5_0 RUN apk add dumb-init

Creating non-root user to run the application

RUN addgroup -g 1001 -S app && mkdir -p /usr/src/app && adduser -u 1001 -S -G app -h /usr/src/app app USER app WORKDIR /usr/src/app RUN echo $'{\n
"name": "npm-read-only-fs",\n
"version": "1.0.0",\n
"description": "",\n
"main": "index.js",\n
"scripts": {\n
"start": "echo 'some message'"\n
},\n
"author": "",\n
"license": "ISC",\n
"dependencies": {\n
},\n
"devDependencies": {\n
}\n
}\n
' >> package.json && npm install

Start the app

CMD ["dumb-init", "npm", "run", "start"] `

Sample of docker image with broken node/npm version:

` FROM node:18.6.0-alpine as node_18_6_0 RUN apk add dumb-init

Creating non-root user to run the application

RUN addgroup -g 1001 -S app && mkdir -p /usr/src/app && adduser -u 1001 -S -G app -h /usr/src/app app USER app WORKDIR /usr/src/app RUN echo $'{\n
"name": "npm-read-only-fs",\n
"version": "1.0.0",\n
"description": "",\n
"main": "index.js",\n
"scripts": {\n
"start": "echo 'some message'"\n
},\n
"author": "",\n
"license": "ISC",\n
"dependencies": {\n
},\n
"devDependencies": {\n
}\n
}\n
' >> package.json && npm install

Start the app

CMD ["dumb-init", "npm", "run", "start"] `

Running the last one will produce the same error as provided before

Environment

  • npm: 8.13.2
  • Node.js: v18.5.0
  • OS Name: macOS Big Sur version 11.6.2

dynk avatar Jul 18 '22 07:07 dynk

I can't even start my app without read-only, reported this a few days ago on image issue tracker: https://github.com/nodejs/docker-node/issues/1749

KMatuszak avatar Jul 18 '22 13:07 KMatuszak

This is being tracked in https://github.com/npm/cli/issues/4838

wraithgar avatar Jul 19 '22 17:07 wraithgar

I don't think #4838 solves this problem. I've just upgraded npm to 8.16.0 and getting this:

npm ERR! code EROFS
npm ERR! syscall open
npm ERR! path /tmp/start-09cff96e.sh
npm ERR! errno -30
npm ERR! rofs EROFS: read-only file system, open '/tmp/start-09cff96e.sh'
npm ERR! rofs Often virtualized file systems, or other file systems
npm ERR! rofs that don't support symlinks, give this error.

npm ERR! Log files were not written due to an error writing to the directory: /home/node/.npm/_logs
npm ERR! You can rerun the command with `--loglevel=verbose` to see the logs in your terminal

for any npm run <xy> command

vojty avatar Aug 08 '22 18:08 vojty

@wraithgar shouldn't we reopen this issue?

vojty avatar Aug 08 '22 18:08 vojty

Having the same problem as @vojty with 8.16.0 ...

2022-08-09 10:00:38 npm ERR! code EROFS
2022-08-09 10:00:38 npm ERR! syscall open
2022-08-09 10:00:38 npm ERR! path /tmp/production-506ef698.sh
2022-08-09 10:00:38 npm ERR! errno -30
2022-08-09 10:00:38 npm ERR! rofs EROFS: read-only file system, open '/tmp/production-506ef698.sh'

jjezek avatar Aug 09 '22 08:08 jjezek

I've found the workaround - basically don't use npm at all Given package.json:

{
  ...
  "scripts": {
    "start": "NODE_ENV=production node ./dist/index.js
  }
  ...
}

So instead of CMD [ "npm", "run", "start" ] you can run the script directly:

CMD [ "sh", "-c", "NODE_ENV=production node ./dist/index.js" ]

vojty avatar Aug 09 '22 09:08 vojty

@wraithgar This is a seperate issue. Even after using [email protected] this can be reproducible.

npm ERR! code EROFS
npm ERR! syscall open
npm ERR! path /tmp/prod-7da54d34.sh
npm ERR! errno -30
npm ERR! rofs EROFS: read-only file system, open '/tmp/prod-7da54d34.sh'
npm ERR! rofs Often virtualized file systems, or other file systems
npm ERR! rofs that don't support symlinks, give this error.

npm ERR! Log files were not written due to an error writing to the directory: /home/node/.npm/_logs
npm ERR! You can rerun the command with `--loglevel=verbose` to see the logs in your terminal

yashodgayashan avatar Aug 31 '22 03:08 yashodgayashan

@wraithgar please re-open, this is not about the LOGS issue, but about the EROFS error.

balonik avatar Sep 14 '22 17:09 balonik

@wraithgar this is not fixed. Mercifully, we actually get logs from npm telling us what the problem is, but it still exits immediately, which means you can't run this in a production container environment. It's a major regression from the previous behavior, which was perfectly happy in a read-only filesystem.

#4838 seemed to fix the logging portion, but we still need a fix for the crash.

mhamann avatar Sep 15 '22 13:09 mhamann

Why does npm run need to save anything in a tmp file? how can I disable this functionality? it used to work with npm 4 and 6 it's only a problem after we upgraded to npm 8. -_- for security reasons we need to use a readonly root filesystem in our docker images.

Ironically we even downgraded from 8.15 for an identical problem down to 8.5 and now we're seeing it again :D

I was able to make it work slighlty better by adding --offline --logs-max=0 to the npm run command -_- so now the startup cmd is npm run prod --offline --logs-max=0

marek5050 avatar Sep 30 '22 16:09 marek5050

Probably related to this topic: "npm run xxx" fills /tmp path with files /tmp/xxx-??????.sh and never cleans them up. node 16.17.1, npm 8.15.0, Ubuntu.

PRR24 avatar Oct 03 '22 11:10 PRR24

This was fixed in 8.17.0 by d0f5995e0399a093c8037057150a922e56b1d7ca.

I was able to create a dockerfile with:

FROM node:lts
COPY project /project
COPY npm-8.17.0.tgz /npm-8.17.0.tgz
RUN npm install /npm-8.17.0.tgz -g
RUN useradd -u 1234 npm
USER npm

and then run:

#/bin/bash

docker build -t npm-readonly .
ID=$(docker run -dit --rm --read-only npm-readonly)
docker exec -it "$ID" /bin/sh

In the shell the example script I created ran successfully:

$ npm --version
8.17.0
$ cd project
$ npm run console-log

> [email protected] console-log
> node script.js

1

If I change the version to 8.16.0 it fails with:

> [email protected] console-log
> node script.js

npm ERR! code EROFS
npm ERR! syscall open
npm ERR! path /tmp/console-log-16a0f356.sh
npm ERR! errno -30
npm ERR! rofs EROFS: read-only file system, open '/tmp/console-log-16a0f356.sh'
npm ERR! rofs Often virtualized file systems, or other file systems
npm ERR! rofs that don't support symlinks, give this error.

npm ERR! Log files were not written due to an error writing to the directory: /home/npm/.npm/_logs
npm ERR! You can rerun the command with `--loglevel=verbose` to see the logs in your terminal

lukekarrys avatar Oct 27 '22 03:10 lukekarrys

Hi @lukekarrys, npm with default config can't run on read-only env is an expected behavior? I still facing this in npm 10.x when running it in AWS lambda which only allows writing to /tmp folder.

ARG FUNCTION_DIR="/function"

FROM node:20-buster as build-image
ARG FUNCTION_DIR
RUN apt-get update && \
    apt-get install -y \
    g++ \
    make \
    cmake \
    unzip \
    libcurl4-openssl-dev \
    git

# npm can't run in read-only env (lambda)
# https://github.com/npm/cli/issues/5183
ENV NPM_CONFIG_CACHE=/tmp/.npm # <----------- need move cache to /tmp

# install lib
RUN mkdir -p ${FUNCTION_DIR}
COPY package.json package-lock.json ${FUNCTION_DIR}
WORKDIR ${FUNCTION_DIR}
RUN npm install
RUN npm install aws-lambda-ric

# copy code
COPY . ${FUNCTION_DIR}

ENTRYPOINT ["/usr/local/bin/npx", "aws-lambda-ric"]
CMD ["index.handler"]

The error will be like this

npm ERR! code EROFS
npm ERR! syscall mkdir
npm ERR! path /home/sbx_user1051
npm ERR! errno -30
npm ERR! rofs EROFS: read-only file system, mkdir '/home/sbx_user1051'
npm ERR! rofs Often virtualized file systems, or other file systems
npm ERR! rofs that don't support symlinks, give this error.
npm ERR! Log files were not written due to an error writing to the directory: /home/sbx_user1051/.npm/_logs 

ck-delivery-admin-vn avatar Dec 19 '23 14:12 ck-delivery-admin-vn

what is logic behind npm requiring access to tmp file ? I have docker image of a simple nestJS application facing same issue. However, The image was created in Jan. It was working fine till 15 Feb. On 16th Feb, When I ran image again, it started fail. Same image. It has multiple times on our ECS service. After deploy the image. It will work fine, then suddenly if we restart our ECS service, it may or may not show the issue. It is not even 100% guaranteed to show My guess is npm may have some logic to write logfile during "npm start"

ShadabFaiz avatar Feb 19 '24 09:02 ShadabFaiz

@ck-delivery-admin-vn I am also facing same issue can anyone help me to fix and explain why this happening

programmerraja avatar Jul 02 '24 06:07 programmerraja