Unable to install pi-pins package for GPIO on RPi3 on balenalib/raspberrypi3-node:10 image

I’m trying to use a relay with my RPi3, but for some reason I can’t seem to install the pi-pins package. I’m using the Balenalib/raspberrypi3-node:10-run image. Here’s my docker-compose.yml:

FROM balenalib/raspberrypi3-node:10-run

RUN apt-get update && apt-get install -yq \
  python build-essential libusb-1.0-0-dev \
  libudev-dev && \
  apt-get clean && rm -rf /var/lib/apt/lists/

# Arguments - docker-compose can override them on build and run

# NPM token for private packages
ARG NPM_TOKEN

# npm token
ENV NPM_TOKEN $NPM_TOKEN

# Enable udevd so that plugged dynamic hardware devices show up in our container.
ENV UDEV=1

# We only want warnings from NPM
ENV NPM_CONFIG_LOGLEVEL warn

RUN echo "npm token should be: $NPM_TOKEN"

RUN npm install -g yarn

# Set a working directory
WORKDIR /app

# Copies the package.json first for better cache on later pushes
COPY package.json package.json

# Copy the app
COPY . /app

RUN echo and now

# Install the packages
RUN yarn

# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /app/stdout.log \
  && ln -sf /dev/stderr /stderr.log

# ─────────────────────────────────  Command  ──────────────────────────────────

CMD ["yarn","start"]

The error seems to come from installing the epoll package and is related to node-gyp.

> epoll@0.1.22 install /app/node_modules/pi-pins/node_modules/epoll
> node-gyp rebuild

make: Entering directory '/app/node_modules/pi-pins/node_modules/epoll/build'
  CXX(target) Release/obj.target/epoll/src/epoll.o
In file included from ../../nan/nan.h:192,
                 from ../src/epoll.cc:15:
../../nan/nan_maybe_43_inl.h: In function ‘Nan::Maybe<bool> Nan::ForceSet(v8::Local<v8::Object>, v8::Local<v8::Value>, v8::Local<v8::Value>, v8::PropertyAttribute)’:
../../nan/nan_maybe_43_inl.h:112:15: error: ‘class v8::Object’ has no member named ‘ForceSet’
   return obj->ForceSet(isolate->GetCurrentContext(), key, value, attribs);
               ^~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h: In function ‘v8::Local<v8::Value> Nan::MakeCallback(v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*)’:
../../nan/nan.h:835:60: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), target, func, argc, argv);
                                                            ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:177:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h:835:60: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), target, func, argc, argv);
                                                            ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:177:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h: In function ‘v8::Local<v8::Value> Nan::MakeCallback(v8::Local<v8::Object>, v8::Local<v8::String>, int, v8::Local<v8::Value>*)’:
../../nan/nan.h:850:62: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::String>, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), target, symbol, argc, argv);
                                                              ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:170:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h:850:62: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::String>, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), target, symbol, argc, argv);
                                                              ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:170:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h: In function ‘v8::Local<v8::Value> Nan::MakeCallback(v8::Local<v8::Object>, const char*, int, v8::Local<v8::Value>*)’:
../../nan/nan.h:865:62: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, const char*, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), target, method, argc, argv);
                                                              ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:163:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h:865:62: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, const char*, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
         v8::Isolate::GetCurrent(), target, method, argc, argv);
                                                              ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:163:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h: In member function ‘v8::Local<v8::Value> Nan::Callback::Call_(v8::Isolate*, v8::Local<v8::Object>, int, v8::Local<v8::Value>*) const’:
../../nan/nan.h:1479:5: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
     ));
     ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:177:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h:1479:5: warning: ‘v8::Local<v8::Value> node::MakeCallback(v8::Isolate*, v8::Local<v8::Object>, v8::Local<v8::Function>, int, v8::Local<v8::Value>*)’ is deprecated: Use MakeCallback(..., async_context) [-Wdeprecated-declarations]
     ));
     ^
In file included from ../src/epoll.cc:12:
/root/.node-gyp/10.16.0/include/node/node.h:177:50: note: declared here
                 NODE_EXTERN v8::Local<v8::Value> MakeCallback(
                                                  ^~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/node.h:91:42: note: in definition of macro ‘NODE_DEPRECATED’
     __attribute__((deprecated(message))) declarator
                                          ^~~~~~~~~~
In file included from ../src/epoll.cc:15:
../../nan/nan.h: In function ‘void Nan::AsyncQueueWorker(Nan::AsyncWorker*)’:
../../nan/nan.h:1732:62: warning: cast between incompatible function types from ‘void (*)(uv_work_t*)’ {aka ‘void (*)(uv_work_s*)’} to ‘uv_after_work_cb’ {aka ‘void (*)(uv_work_s*, int)’} [-Wcast-function-type]
     , reinterpret_cast<uv_after_work_cb>(AsyncExecuteComplete)
                                                              ^
../src/epoll.cc: In static member function ‘static Nan::NAN_METHOD_RETURN_TYPE Epoll::Add(Nan::NAN_METHOD_ARGS_TYPE)’:
../src/epoll.cc:210:44: warning: ‘int32_t v8::Value::Int32Value() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
   int err = epoll->Add(info[0]->Int32Value(), info[1]->Int32Value());
                                            ^
In file included from /root/.node-gyp/10.16.0/include/node/v8.h:26,
                 from ../src/epoll.cc:11:
/root/.node-gyp/10.16.0/include/node/v8.h:2478:46: note: declared here
   V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
                                              ^~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/v8config.h:324:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
../src/epoll.cc:210:67: warning: ‘int32_t v8::Value::Int32Value() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
   int err = epoll->Add(info[0]->Int32Value(), info[1]->Int32Value());
                                                                   ^
In file included from /root/.node-gyp/10.16.0/include/node/v8.h:26,
                 from ../src/epoll.cc:11:
/root/.node-gyp/10.16.0/include/node/v8.h:2478:46: note: declared here
   V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
                                              ^~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/v8config.h:324:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
../src/epoll.cc: In static member function ‘static Nan::NAN_METHOD_RETURN_TYPE Epoll::Modify(Nan::NAN_METHOD_ARGS_TYPE)’:
../src/epoll.cc:230:47: warning: ‘int32_t v8::Value::Int32Value() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
   int err = epoll->Modify(info[0]->Int32Value(), info[1]->Int32Value());
                                               ^
In file included from /root/.node-gyp/10.16.0/include/node/v8.h:26,
                 from ../src/epoll.cc:11:
/root/.node-gyp/10.16.0/include/node/v8.h:2478:46: note: declared here
   V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
                                              ^~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/v8config.h:324:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
../src/epoll.cc:230:70: warning: ‘int32_t v8::Value::Int32Value() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
   int err = epoll->Modify(info[0]->Int32Value(), info[1]->Int32Value());
                                                                      ^
In file included from /root/.node-gyp/10.16.0/include/node/v8.h:26,
                 from ../src/epoll.cc:11:
/root/.node-gyp/10.16.0/include/node/v8.h:2478:46: note: declared here
   V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
                                              ^~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/v8config.h:324:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
../src/epoll.cc: In static member function ‘static Nan::NAN_METHOD_RETURN_TYPE Epoll::Remove(Nan::NAN_METHOD_ARGS_TYPE)’:
../src/epoll.cc:247:47: warning: ‘int32_t v8::Value::Int32Value() const’ is deprecated: Use maybe version [-Wdeprecated-declarations]
   int err = epoll->Remove(info[0]->Int32Value());
                                               ^
In file included from /root/.node-gyp/10.16.0/include/node/v8.h:26,
                 from ../src/epoll.cc:11:
/root/.node-gyp/10.16.0/include/node/v8.h:2478:46: note: declared here
   V8_DEPRECATED("Use maybe version", int32_t Int32Value() const);
                                              ^~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/v8config.h:324:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
In file included from ../src/epoll.cc:12:
../src/epoll.cc: At global scope:
/root/.node-gyp/10.16.0/include/node/node.h:573:43: warning: cast between incompatible function types from ‘void (*)(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE)’ {aka ‘void (*)(v8::Local<v8::Object>)’} to ‘node::addon_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, void*)’} [-Wcast-function-type]
       (node::addon_register_func) (regfunc),                          \
                                           ^
/root/.node-gyp/10.16.0/include/node/node.h:607:3: note: in expansion of macro ‘NODE_MODULE_X’
   NODE_MODULE_X(modname, regfunc, NULL, 0)  // NOLINT (readability/null_usage)
   ^~~~~~~~~~~~~
../src/epoll.cc:381:1: note: in expansion of macro ‘NODE_MODULE’
 NODE_MODULE(epoll, Epoll::Init)
 ^~~~~~~~~~~
In file included from ../src/epoll.cc:11:
/root/.node-gyp/10.16.0/include/node/v8.h: In instantiation of ‘void v8::PersistentBase<T>::SetWeak(P*, typename v8::WeakCallbackInfo<P>::Callback, v8::WeakCallbackType) [with P = node::ObjectWrap; T = v8::Object; typename v8::WeakCallbackInfo<P>::Callback = void (*)(const v8::WeakCallbackInfo<node::ObjectWrap>&)]’:
/root/.node-gyp/10.16.0/include/node/node_object_wrap.h:84:78:   required from here
/root/.node-gyp/10.16.0/include/node/v8.h:9502:16: warning: cast between incompatible function types from ‘v8::WeakCallbackInfo<node::ObjectWrap>::Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<node::ObjectWrap>&)’} to ‘Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<void>&)’} [-Wcast-function-type]
                reinterpret_cast<Callback>(callback), type);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/root/.node-gyp/10.16.0/include/node/v8.h: In instantiation of ‘void v8::PersistentBase<T>::SetWeak(P*, typename v8::WeakCallbackInfo<P>::Callback, v8::WeakCallbackType) [with P = Nan::ObjectWrap; T = v8::Object; typename v8::WeakCallbackInfo<P>::Callback = void (*)(const v8::WeakCallbackInfo<Nan::ObjectWrap>&)]’:
../../nan/nan_object_wrap.h:66:61:   required from here
/root/.node-gyp/10.16.0/include/node/v8.h:9502:16: warning: cast between incompatible function types from ‘v8::WeakCallbackInfo<Nan::ObjectWrap>::Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<Nan::ObjectWrap>&)’} to ‘Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<void>&)’} [-Wcast-function-type]
make: *** [epoll.target.mk:101: Release/obj.target/epoll/src/epoll.o] Error 1
make: Leaving directory '/app/node_modules/pi-pins/node_modules/epoll/build'
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:198:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:248:12)
gyp ERR! System Linux 4.14.98
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /app/node_modules/pi-pins/node_modules/epoll
gyp ERR! node -v v10.16.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 
npm WARN iot-node@1.0.0 No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! epoll@0.1.22 install: `node-gyp rebuild`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the epoll@0.1.22 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2019-08-16T00_48_04_399Z-debug.log

I’ve tried manually installing node-gyp but to no avail.

I’ve tried running the example from https://github.com/balena-io-playground/balena-rpi-nodejs-basic-gpio and can get my relay to work, my assumption is that there’s some issue with the balenalib/raspberrypi3-node:10 base image, but I can’t work out what.

Hi,
To use native modules it is usually best to use the -build variant of our base images. For example balenalib/raspberrypi3-node:10-build.
I checked out the pi-pins package and it depends on an epoll version 0.1.22, which only supports Node up to version 8. So I was able to build the pi-pins packages with a simple example for the base images balenalib/raspberrypi3-node:8-build (with some compiler warnings) and balenalib/raspberrypi3-node:6-build. Here is my minimal example:

FROM balenalib/raspberrypi3-node:8-build

WORKDIR /app

COPY package.json package.json

RUN npm install

CMD ["/bin/bash"]

Thanks @afitzek, turns out the issue was that the version of epoll in the package.json of the lib I was trying to use was very out of date and was not compatible with Node 10x, so updating the epoll version did the trick!