Closed haggen closed 9 years ago
hm I don't know why npm install
would be trying to chown this file, but I can give you some background on why it's failing: dinghy configures the NFS volume to "squash" all files to be owned by your user on the host OSX machine. It didn't originally, it ran NFS operations as root on the host machine, this change was discussed in https://github.com/codekitchen/dinghy/issues/15
The consequence of this is that you aren't writing to the NFS share as root, and you typically won't have permission to chown files. Ideally, I'd love to be able to configure the NFS share to just ignore chown commands, like virtualbox built-in file shares do, but that isn't possible without modifications to the NFS server code.
As far as your specific problem, is the npm install
running as root? If so, modifying your container to run as a non-root user would potentially fix the issue.
I wouldn't be totally opposed to a configuration setting to let you choose whether dinghy enables root squashing or not, since both have their advantages.
Hey @codekitchen thanks a lot for the heads up! I'm going to try changing the container user later and report back to you.
Had the exact same problem running wercker, as I don't know how to configure it to not run as root inside the box, I have added a new step right before npm install
is run, that would solve my problem (effectively running npm install
as my host's user):
# NOTE: you might want to adjust the uid and gid values for your user
- script:
name: downgrade to mac user
code: |
useradd -u 501 -g 20 wercker
mkdir /home/wercker
/usr/bin/sudo -u wercker -s
export HOME=/home/wercker
@haggen I'm going to close this, let me know of you're still hitting issues.
@haggen I actually just hit a similar issue and wanted to share my solution.
I have a nodejs app. I run it in a nginx container as it is just static site code built with nodjs. Because of this, developers can't just attach to the container and run npm
because it's not actually installed. What happens when you need to update a module?
Well, I run a separate container that is the official node
image. I mount my local git repo into it and then I can run npm
command inside the container. Great! but then I run into your issue:
Error: EPERM, chown '/app/node_modules/watchify/package.json'
I don't want to have to mess around with starting a container, mounting the repo, adding users/changing permissions, I want it automated! So this is what I came up with:
docker run --rm -u $UID -it -w /app -v $PWD /client/container/npm:/.npm -v $PWD:/app node:0.10-slim npm install watchify@3.3.1 --save
-u
sets the uid of the user running the container to my local uid which means that I don't run into Error: EPERM, chown
the first -v
is specific to my case because npm wants to create a /.npm
folder. You may not need it depending on if you keep a .npm
folder in your repo, but if you do, just have a empty npm directory in your local repo that you can mount to /.npm
(-v
can't mount dotfiles as it doesn't have permission to view them)
the second -v
mounts everything in my local repo to /app
so that my changes show up in my local repo even after the container is gone
-w
just sets the WORKDIR
This essentially is a containerized way of running commands so you don't need to install something like nodejs and npm on your local. You could take it one step further and use the docker run
command as an alias or make task.
Hope this can help someone
This still does appear to be an issue. I worked around it by doing something like the following:
echo "Installing node modules..."
cp /src/package.json /root/
cd /root && npm install -q
echo "Node modules installed. Syncing back to /src/node_modules..."
rsync -rlzuIO --ignore-errors /root/node_modules/ /src/node_modules > /dev/null 2>&1
rm -rf /root/node_modules /root/package.json
Switching user in the Dockerfile to a non-root user fixed it for me.
@ryanmt How were you able to switch the user to a non-root user in the Dockerfile?
@Skilgarriff https://docs.docker.com/engine/reference/builder/#user?
@MrMMorriss I attempted that, but I'm now getting an even uglier exit than before. Still getting 'chown permission denied, Please try running as root' on npm install
@Skilgarriff USER is the command. I've often seen prerequisite useradd steps, and it might be necessary to run a chown before the npm install.
@ryanmt Turns out it was an issue with maproot. Dinghy does not map the root to 0 which causes some issues when trying to run any privileged command when trying to use that command on Volumes mounted with NFS.
More background on this issue: https://github.com/docker/machine/issues/1817 I'm specifically hitting this issue ATM with npm and it's looking like I'm going to have to use virtual box ... ;-(
There's a comment here: https://github.com/npm/npm/issues/3565#issuecomment-202473011 showing a nice way to overcome that - you can make chmod do nothing by using LD_PRELOAD.
You can do it for the entire container in Dockerfile. First make sure you've gcc installed, and then add:
RUN echo "int chown() { return 0; }" > preload.c && gcc -shared -o /libpreload.so preload.c && rm preload.c
ENV LD_PRELOAD=/libpreload.so
This simply makes chmod think it actually did something and succeed, so npm is all happy and confident it did a good job.
You can also do it just for one command - just call npm install this way (again, you need gcc):
echo "int chown() { return 0; }" > preload.c && gcc -shared -o preload.so preload.c && LD_PRELOAD=$PWD/preload.so npm install && rm preload.c preload.so
This is driving me nuts. In our dev environments, my team mounts their home folder to /root due to needing access to the NPM login token, AWS credentials, shared NPM cache, etc stored there. This worked well with docker implementations where root took ownership of new files (we've used dlite with success in the past, but lack of maintenance is making that one tough to use now). Under dinghy's model of setting root to use the executing user/group's access levels, I get this every time I NPM install, even if I delete ~/.npm first:
npm ERR! Error: EPERM: operation not permitted, chown '/root/.npm/_locks'
npm ERR! at Error (native)
npm ERR! { Error: EPERM: operation not permitted, chown '/root/.npm/_locks'
npm ERR! at Error (native)
npm ERR! errno: -1,
npm ERR! code: 'EPERM',
npm ERR! syscall: 'chown',
npm ERR! path: '/root/.npm/_locks' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
npm ERR! Linux 4.4.17-boot2docker
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "node-gyp"
npm ERR! node v6.3.1
npm ERR! npm v3.10.5
npm ERR! path npm-debug.log.737059936
npm ERR! code EACCES
npm ERR! errno -13
npm ERR! syscall open
So I did a code-dive and discovered the :custom_nfs_export_options
preference. "Eureka!" I thought. So I popped open my system's /etc/exports and grabbed this line that dlite injected: /Users -network 192.168.64.0 -mask 255.255.255.0 -alldirs -maproot=root:wheel
and converted that to what it looked like dinghy's bundled NFS needed. I ended up with these prefs:
---
:preferences:
:proxy_disabled: false
:fsevents_disabled: false
:create:
provider: xhyve
:custom_nfs_export_options: rw,alldirs,maproot=root:wheel
After a dinghy restart
, I confirmed that my machine-nfs-exports-dinghy
file had the appropriate settings. Hurrah!
...but my in-container npm install
still failed. I got the same error as before, and this one:
npm ERR! Error: EACCES: permission denied, open 'npm-debug.log.737059936'
npm ERR! at Error (native)
npm ERR! { Error: EACCES: permission denied, open 'npm-debug.log.737059936'
npm ERR! at Error (native)
npm ERR! errno: -13,
npm ERR! code: 'EACCES',
npm ERR! syscall: 'open',
npm ERR! path: 'npm-debug.log.737059936' }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.
I really, really do not want to do the chown hack mentioned above if there's an nfs configuration that can restore the old functionality. Any idea why my solution didn't take care of this?
EDIT: Neeeevermind. Rather than maproot=root:wheel
, I did anonuid=0,anongid=0
. Worked like a charm. I don't get the dinghy fanciness of keeping everything under my local user's ownership, but at least my native npm modules build now.
I'm using the passenger-ruby22
base image and I had this line in my Dockerfile:
RUN bower install --allow-root --config.interactive=false --verbose --force
which was giving me that error. I fixed it setting the user to someone different than root, as follows:
RUN setuser app bower install --allow-root --config.interactive=false --verbose --force
(The app
user is the user that comes with my base image)
This is driving me nuts. In our dev environments, my team mounts their home folder to /root due to needing access to the NPM login token, AWS credentials, shared NPM cache, etc stored there. This worked well with docker implementations where root took ownership of new files (we've used dlite with success in the past, but lack of maintenance is making that one tough to use now). Under dinghy's model of setting root to use the executing user/group's access levels, I get this every time I NPM install, even if I delete ~/.npm first:
npm ERR! Error: EPERM: operation not permitted, chown '/root/.npm/_locks' npm ERR! at Error (native) npm ERR! { Error: EPERM: operation not permitted, chown '/root/.npm/_locks' npm ERR! at Error (native) npm ERR! errno: -1, npm ERR! code: 'EPERM', npm ERR! syscall: 'chown', npm ERR! path: '/root/.npm/_locks' } npm ERR! npm ERR! Please try running this command again as root/Administrator. npm ERR! Linux 4.4.17-boot2docker npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install" "-g" "node-gyp" npm ERR! node v6.3.1 npm ERR! npm v3.10.5 npm ERR! path npm-debug.log.737059936 npm ERR! code EACCES npm ERR! errno -13 npm ERR! syscall open
So I did a code-dive and discovered the
:custom_nfs_export_options
preference. "Eureka!" I thought. So I popped open my system's /etc/exports and grabbed this line that dlite injected:/Users -network 192.168.64.0 -mask 255.255.255.0 -alldirs -maproot=root:wheel
and converted that to what it looked like dinghy's bundled NFS needed. I ended up with these prefs:--- :preferences: :proxy_disabled: false :fsevents_disabled: false :create: provider: xhyve :custom_nfs_export_options: rw,alldirs,maproot=root:wheel
After a
dinghy restart
, I confirmed that mymachine-nfs-exports-dinghy
file had the appropriate settings. Hurrah!...but my in-container
npm install
still failed. I got the same error as before, and this one:npm ERR! Error: EACCES: permission denied, open 'npm-debug.log.737059936' npm ERR! at Error (native) npm ERR! { Error: EACCES: permission denied, open 'npm-debug.log.737059936' npm ERR! at Error (native) npm ERR! errno: -13, npm ERR! code: 'EACCES', npm ERR! syscall: 'open', npm ERR! path: 'npm-debug.log.737059936' } npm ERR! npm ERR! Please try running this command again as root/Administrator.
I really, really do not want to do the chown hack mentioned above if there's an nfs configuration that can restore the old functionality. Any idea why my solution didn't take care of this?
EDIT: Neeeevermind. Rather than
maproot=root:wheel
, I didanonuid=0,anongid=0
. Worked like a charm. I don't get the dinghy fanciness of keeping everything under my local user's ownership, but at least my native npm modules build now.
Thank you so much! This helped me solve this problem as well!
Using dinghy, when I try to
npm install
something, it complains:It used to work well on boot2docker, even when using nfs.