A
A
Alex2016-07-20 17:30:39
Node.js
Alex, 2016-07-20 17:30:39

Why does npm install -g behave differently inside docker?

Actually faced with interesting behavior. There is the following dockerfile

FROM ubuntu:14.04

RUN locale-gen en_US.UTF-8
ENV LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 TERM=xterm

RUN apt-get -y update && apt-get -y install \
    software-properties-common \
    git supervisor curl wget python-pip \
    && curl -s http://nginx.org/keys/nginx_signing.key | apt-key add - \
    && add-apt-repository ppa:ondrej/php \
    && add-apt-repository ppa:nginx/stable \
    && pip install supervisor-stdout \
    && apt-get -y upgrade && apt-get -y dist-upgrade

RUN apt-get install -y \
    php5.6-mcrypt \
    php5.6-zip \
    php5.6-bcmath \
    ...
    php5.6-fpm \
    nginx \
    imagemagick \
    && rm -rf /var/lib/apt/lists/*

COPY tools/phantomjs /opt/phantomjs
COPY tools/node-v0.10.46/ /opt/node/

RUN update-alternatives --install /usr/bin/phantomjs phantomjs /opt/phantomjs 50 \
&& update-alternatives --install /usr/bin/node node /opt/node/bin/node 50 \
&& update-alternatives --install /usr/bin/npm npm /opt/node/bin/npm 50 \
&& npm -g install pm2 bower gulp \
&& update-alternatives --install /usr/bin/bower bower /opt/node/bin/bower 50 \
&& update-alternatives --install /usr/bin/pm2 pm2 /opt/node/bin/pm2 50 \
&& update-alternatives --install /usr/bin/gulp gulp /opt/node/bin/gulp 50

I start by the working machine - the image gathers without problems. I run it on a home machine, it crashes with an error
update-alternatives: error: alternative path /opt/node/bin/bower doesn't exist

And indeed, when I look at the output, I see that on the working machine the modules are placed in /opt/node/lib/node_modules and the corresponding symlink is created in the /opt/node/bin folder, and on the home machine the modules are placed in /usr/lib/ node_modules and no symlinks appear in /opt/node/bin.
Actually the question is why?
Docker is running on Ubuntu 14.04 from off repository, the image is built with the same Dockerfile. I was actually sure that docker just guarantees complete abstraction from the hardware and 100% playback. But it looks like I'm missing something.
UPD1
The only thing I noticed is that on the working machine, the base image has
ubuntu: 14.04, ID: 38c759202e30
and on the home machine
ubuntu: 14.04, ID: b2f1fdd93175, the
working machine
# docker info
Containers: 1
 Running: 1
 Paused: 0
 Stopped: 0
Images: 22
Server Version: 1.11.2
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 23
 Dirperm1 Supported: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge null host
Kernel Version: 3.13.0-92-generic
Operating System: Ubuntu 14.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.955 GiB
Name: designer-docker
ID: KRDG:UUYU:DIHL:N4FI:VSKH:7LJG:HFZ2:LWWZ:IPKZ:I2L3:442I:USXP
Docker Root Dir: /var/lib/docker
Debug mode (client): false
Debug mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support

# docker version
Client:
 Version:      1.11.2
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   b9f10c9
 Built:        Wed Jun  1 21:47:50 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.11.2
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   b9f10c9
 Built:        Wed Jun  1 21:47:50 2016
 OS/Arch:      linux/amd64

and this is homemade
# docker info
Containers: 1
 Running: 0
 Paused: 0
 Stopped: 1
Images: 24
Server Version: 1.11.2
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 25
 Dirperm1 Supported: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge null host
Kernel Version: 3.13.0-92-generic
Operating System: Ubuntu 14.04.4 LTS
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 1.948 GiB
Name: docker
ID: VAHK:OL3A:C6NB:7P7S:E64Y:RKVP:42HN:AULR:N2XB:GTN2:SGDR:Z3KF
Docker Root Dir: /var/lib/docker
Debug mode (client): false
Debug mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support



# docker version
Client:
 Version:      1.11.2
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   b9f10c9
 Built:        Wed Jun  1 21:47:50 2016
 OS/Arch:      linux/amd64

Server:
 Version:      1.11.2
 API version:  1.23
 Go version:   go1.5.4
 Git commit:   b9f10c9
 Built:        Wed Jun  1 21:47:50 2016
 OS/Arch:      linux/amd64

Answer the question

In order to leave comments, you need to log in

2 answer(s)
P
Pavel, 2016-07-20
@pvlg

Most likely, there are no tools/node-v0.10.46/ on the home machine,
perhaps there are no execution rights
or inside the container
chmod +x /opt/node/bin/bower

A
Alex, 2016-07-21
@ALexhha

Everything turned out to be easier. The point is in npm itself, or rather, how it processes paths.

# docker run -it 98605b17ed79 bash -il

[email protected]:/# npm -g root
/usr/lib/node_modules

[email protected]:/# /opt/node/bin/npm -g root
/opt/node/lib/node_modules

[email protected]:/# whereis npm
npm: /usr/bin/npm /usr/bin/X11/npm /opt/node/bin/npm

[email protected]:/# ls -lad /usr/bin/npm
lrwxrwxrwx 1 root root 21 Jul 20 18:56 /usr/bin/npm -> /etc/alternatives/npm

[email protected]:/# ls -lad /etc/alternatives/npm
lrwxrwxrwx 1 root root 17 Jul 20 18:56 /etc/alternatives/npm -> /opt/node/bin/npm

Therefore, this nuance must be taken into account. Alternatively install modules with --prefix
# npm install -g --prefix=/node/modules pm2 bower gulp

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question