nodejs / docker-node

Official Docker Image for Node.js :whale: :turtle: :rocket:
https://hub.docker.com/_/node/
MIT License
8.26k stars 1.97k forks source link

Can't install global packages as root user in arm32v6/node images #873

Open andyault opened 6 years ago

andyault commented 6 years ago

Hey all, I have a pretty standard Dockerfile for running my code on top of the node:8-alpine image that works fine normally, but hangs indefinitely after switching to the arm32v6/node:8-alpine variant. The only fix I was able to get working was to switch to the node user before calling npm install -g, and then switch back to the root user to run (I know it's against best practices, but my main concern for now is getting the image to run without errors). This does not happen for non-global packages.

Note that this isn't the same as #603 because I can't even get debug messages. I've tried this on OS X and Windows, both show the same behavior.

Dockerfile:

# FROM node:8-alpine
FROM arm32v6/node:8-alpine

# install deps
RUN apk add --no-cache \
    bluez \
    bluez-firmware \
    bluez-deprecated \
    wireless-tools \
    curl \
    ca-certificates \
    openrc \
    && rc-update add bluetooth

# https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#global-npm-dependencies
ENV NPM_CONFIG_PREFIX=/home/node/.npm-global \
    PATH=$PATH:/home/node/.npm-global/bin

# install pm2
# if I install as root, npm hangs so bad it never even gets to debug messages
# USER node
RUN NPM_CONFIG_LOGLEVEL=silly npm i --production pm2 -g
# USER root

Build log:

$ docker build -t my-image /var/empty
Sending build context to Docker daemon   2.08kB
Step 1/4 : FROM arm32v6/node:8-alpine
 ---> 39a1d7610bbd
Step 2/4 : RUN apk add --no-cache   bluez   bluez-firmware  bluez-deprecated    wireless-tools  curl    ca-certificates     openrc  && rc-update add bluetooth
 ---> Running in 3650668ae604
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/main/armhf/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.8/community/armhf/APKINDEX.tar.gz
(1/38) Installing expat (2.2.5-r0)
...
(38/38) Installing wireless-tools (30_pre9-r0)
Executing busybox-1.28.4-r1.trigger
Executing glib-2.56.1-r0.trigger
Executing dbus-1.10.24-r1.trigger
Executing ca-certificates-20171114-r3.trigger
OK: 30 MiB in 53 packages
 * service bluetooth added to runlevel sysinit
Removing intermediate container 3650668ae604
 ---> 6a835c834fc2
Step 3/4 : ENV NPM_CONFIG_PREFIX=/home/node/.npm-global     PATH=$PATH:/home/node/.npm-global/bin
 ---> Running in 49b4db275c51
Removing intermediate container 49b4db275c51
 ---> fa0fef9c8158
Step 4/4 : RUN NPM_CONFIG_LOGLEVEL=silly npm i --production pm2 -g
 ---> Running in 5a556613d879
Unknown host QEMU_IFLA type: 40
Unknown host QEMU_IFLA type: 41
Unknown host QEMU_IFLA type: 40
Unknown host QEMU_IFLA type: 41
Unknown QEMU_IFLA_INFO_KIND ipip
Unknown host QEMU_IFLA type: 40
Unknown host QEMU_IFLA type: 41
Unknown QEMU_IFLA_INFO_KIND ip6tnl
Unknown host QEMU_IFLA type: 40
Unknown host QEMU_IFLA type: 41

# hangs forever
PeterDaveHello commented 5 years ago

I tested your Dockerfile on my Raspberry Pi 3 B+ using Raspbian GNU/Linux 9.4, with USER node, root, or without USER config, and they all worked fine, would you please provide more info?

andyault commented 5 years ago

I can confirm that I'm able to do the same on my Raspberry Pi, so it seems like this issue is exclusive to platforms that need QEMU

PeterDaveHello commented 5 years ago

So, I'm not sure if this is an issue that we @nodejs/docker can solve, the QEMU configuration may also affect this problem.

ndruwizz commented 5 years ago

Any update?

intersides commented 5 years ago

I had the same problem . To me the solution was to use yarn just for pm2

...

RUN apk add yarn
#NOTE npm install pm2 -g will freeze in Raspberry PI 4.
RUN yarn global add pm2
...
Charl13 commented 4 years ago

Same issue here building multi-arch images using Docker Buildx.

Build command

docker buildx build --no-cache --platform linux/amd64,linux/arm64,linux/arm/v7 -t charl13/flood:latest .

Dockerfile (from Flood-UI/food)

ARG NODE_IMAGE=node:12.2-alpine
ARG WORKDIR=/usr/src/app/

FROM ${NODE_IMAGE} as nodebuild
ARG WORKDIR

WORKDIR $WORKDIR

# Generate node_modules
COPY package.json \
     package-lock.json \
     .babelrc \
     .eslintrc.js \
     .eslintignore \
     .prettierrc \
     ABOUT.md \
     $WORKDIR
RUN apk add --no-cache --virtual=build-dependencies \
    python build-base && \
    npm install && \
    apk del --purge build-dependencies

# Build static assets and remove devDependencies.
COPY client ./client
COPY server ./server
COPY shared ./shared
COPY scripts ./scripts
COPY config.docker.js ./config.js
RUN npm run build && \
    npm prune --production

# Now get the clean image without any dependencies and copy compiled app
FROM ${NODE_IMAGE} as flood
ARG WORKDIR

WORKDIR $WORKDIR

# Install runtime dependencies.
RUN apk --no-cache add \
    mediainfo

COPY --from=nodebuild $WORKDIR $WORKDIR

# Hints for consumers of the container.
EXPOSE 3000
VOLUME ["/data"]

# Start application.
CMD [ "npm", "start" ]

It hangs forever on this line.

RUN apk add --no-cache --virtual=build-dependencies \
    python build-base && \
    npm install && \
    apk del --purge build-dependencies

As work around I've changed it to this line.

RUN apk add --no-cache --virtual=build-dependencies \
    yarn python build-base && \
    yarn install && \
    apk del --purge build-dependencies

Note that I've tried to build this image on a Raspberry Pi 3 Model B+ which has an ARMv7 architecture. It hangs on the same line there as well. This is the reason why I've moved to Docker Buildx on my Mac. But as described above, building for ARMv7 (and maybe other ARM variants) makes the npm install command hang.

Debug info

docker system info
Client:
 Debug Mode: false
 Plugins:
  app: Docker Application (Docker Inc., v0.8.0)
  buildx: Build with BuildKit (Docker Inc., v0.3.1-tp-docker)

Server:
 Containers: 51
  Running: 5
  Paused: 0
  Stopped: 46
 Images: 195
 Server Version: 19.03.5
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: true
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
 Swarm: inactive
 Runtimes: runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339
 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
 init version: fec3683
 Security Options:
  seccomp
   Profile: default
 Kernel Version: 4.9.184-linuxkit
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 2
 Total Memory: 3.855GiB
 Name: docker-desktop
 ID: HNQQ:KMLE:OR6F:Y3KU:LJIL:BZPA:NPKV:VSGA:44VA:46WG:QGDH:LWIL
 Docker Root Dir: /var/lib/docker
 Debug Mode: true
  File Descriptors: 66
  Goroutines: 73
  System Time: 2019-12-10T08:26:29.6066411Z
  EventsListeners: 2
 HTTP Proxy: gateway.docker.internal:3128
 HTTPS Proxy: gateway.docker.internal:3129
 Registry: https://index.docker.io/v1/
 Labels:
 Experimental: true
 Insecure Registries:
  127.0.0.0/8
 Live Restore Enabled: false
 Product License: Community Engine
kegi commented 4 years ago

@Charl13 I have a very similar setup as you. Did you find a solution ?

kegi commented 4 years ago

After few days of trying, I successfully built arm 32/64 bits using QEMU. Here is few things I did :

I hope that can help ;)