@ALexhha
DevOps Engineer

Почему npm install -g внутри docker ведет себя по разному?

Собственно столкнулся с интересным поведением. Есть следующий 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


Запускаю на рабочей машине - образ собирается без проблем. Запускаю на домашней машине, вываливается с ошибкой

update-alternatives: error: alternative path /opt/node/bin/bower doesn't exist


И действительно, когда смотрю вывод, то вижу, что на рабочей машине модули ставятся в /opt/node/lib/node_modules и в папке /opt/node/bin создается соответствующий симлинк, а на домашней машине модули ставятся в /usr/lib/node_modules и в /opt/node/bin никаких симлинков не появляется.

Собственно вопрос почему так?

Docker запущен на Ubuntu 14.04 с офф репозитария, образ создается с одним и тем же Dockerfile. Я собственно был уверен, что docker как раз и гарантирует, полное абстрагирование от аппаратной части и воспроизведение на 100%. Но видать я что то упускаю.

UPD1
Единственное что заметил, на рабочей машине у базового образа
ubuntu:14.04, ID: 38c759202e30

а на домашней
ubuntu:14.04, ID: b2f1fdd93175

рабочая машина
# 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


а это домашняя
# 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
  • Вопрос задан
  • 531 просмотр
Пригласить эксперта
Ответы на вопрос 2
Скорее всего на домашней машине отсутствует tools/node-v0.10.46/

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

возможно нет прав на исполнение

chmod +x tools/node-v0.10.46/bin/bower
или внутри контейнера
chmod +x /opt/node/bin/bower
Ответ написан
@ALexhha Автор вопроса
DevOps Engineer
Все оказалось проще. Дело таки в самом npm, а точнее как он обрабатывает пути.
# docker run -it 98605b17ed79 bash -il

root@27b780224672:/# npm -g root
/usr/lib/node_modules

root@27b780224672:/# /opt/node/bin/npm -g root
/opt/node/lib/node_modules

root@27b780224672:/# whereis npm
npm: /usr/bin/npm /usr/bin/X11/npm /opt/node/bin/npm

root@27b780224672:/# ls -lad /usr/bin/npm
lrwxrwxrwx 1 root root 21 Jul 20 18:56 /usr/bin/npm -> /etc/alternatives/npm

root@27b780224672:/# ls -lad /etc/alternatives/npm
lrwxrwxrwx 1 root root 17 Jul 20 18:56 /etc/alternatives/npm -> /opt/node/bin/npm


Поэтому надо учитывать этот нюанс. Как вариант устанавливать модули с --prefix
# npm install -g --prefix=/node/modules pm2 bower gulp
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы