Issue to node-sass and Docker
Asked Answered
A

6

21

I'm attempting to dockerise my node application. My current application is a nodejs express server with postgresql. ExpressJS uses node-sass-middleware to handle the sass assets. When I run node and postgresql locally on my OSX machine everything works fine. When I try to run the app with docker-compose I get a "Missing Binding error"

Here is my Dockerfile:

FROM node:7.2.1
RUN apt-get update -qq && apt-get install -y build-essential
RUN apt-get install -y libpq-dev postgresql-client
ENV APP_HOME /my_app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
ADD package.json .
RUN npm install
RUN npm rebuild node-sass
ADD . .
CMD [ "npm", "start" ]
EXPOSE 3000

Here is my docker-compose.yml file:

version: '2'
services:
    db:
      image: postgres:9.6.1
      ports:
        - '5432:5432'
    web:
      build: . # use the Dockerfile next to this file
      volumes:
        - .:/my_app
      ports:
        - "3000:3000"
      depends_on:
        - db

When I run docker-compose up I still get the following error:

web_1  | [nodemon] 1.11.0
web_1  | [nodemon] to restart at any time, enter `rs`
web_1  | [nodemon] watching: *.*
web_1  | [nodemon] starting `node ./bin/www`
web_1  | /my_app/node_modules/node-sass/lib/binding.js:15
web_1  |       throw new Error(errors.missingBinary());
web_1  |       ^
web_1  |
web_1  | Error: Missing binding /my_app/node_modules/node-sass/vendor/linux-x64-51/binding.node
web_1  | Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 7.x
web_1  |
web_1  | Found bindings for the following environments:
web_1  |   - OS X 64-bit with Node.js 7.x
web_1  |
web_1  | This usually happens because your environment has changed since running `npm install`.
web_1  | Run `npm rebuild node-sass` to build the binding for your current environment.
web_1  |     at module.exports (/my_app/node_modules/node-sass/lib/binding.js:15:13)
web_1  |     at Object.<anonymous> (/my_app/node_modules/node-sass/lib/index.js:14:35)
web_1  |     at Module._compile (module.js:571:32)
web_1  |     at Object.Module._extensions..js (module.js:580:10)
web_1  |     at Module.load (module.js:488:32)
web_1  |     at tryModuleLoad (module.js:447:12)
web_1  |     at Function.Module._load (module.js:439:3)
web_1  |     at Module.require (module.js:498:17)
web_1  |     at require (internal/module.js:20:19)
web_1  |     at Object.<anonymous> (/my_app/node_modules/node-sass-middleware/middleware.js:3:12)
web_1  |     at Module._compile (module.js:571:32)
web_1  |     at Object.Module._extensions..js (module.js:580:10)
web_1  |     at Module.load (module.js:488:32)
web_1  |     at tryModuleLoad (module.js:447:12)
web_1  |     at Function.Module._load (module.js:439:3)
web_1  |     at Module.require (module.js:498:17)
web_1  | [nodemon] app crashed - waiting for file changes before starting...

I though by adding RUN npm rebuild node-sass to the Dockerfile, it would build the correct binding for the OS in the docker container... But it does not seem to work.

Any thoughts?

Abbie answered 30/1, 2017 at 18:17 Comment(2)
What version of node-sass-middleware/node-sass are you trying to install. Node 7 support was only added semi-recentlyUnderlayer
@Underlayer i'm using node-sass-middleware version 0.9.8Abbie
S
13

The support for Node.js 7 (for Linux and OSX) seems to have been added in node-sass v3.7.0. Make sure you use a version equal to or newer than this.

Either you can update your Dockerfile:

FROM node:7.2.1
RUN apt-get update -qq && apt-get install -y build-essential
RUN apt-get install -y libpq-dev postgresql-client
ENV APP_HOME /my_app
RUN mkdir $APP_HOME
WORKDIR $APP_HOME
ADD package.json .

# Add the two entries below
RUN mkdir -p node_modules/node-sass/vendor/linux-x64-51
RUN curl -L https://github.com/sass/node-sass/releases/download/v4.5.0/linux-x64-51_binding.node -o node_modules/node-sass/vendor/linux-x64-51/binding.node

RUN npm install
RUN npm rebuild node-sass
ADD . .
CMD [ "npm", "start" ]
EXPOSE 3000

Or you can download the binding locally and then build from the Dockerfile without any modification:

cd /path/to/node_app/node_modules
mkdir -p node-sass/vendor/linux-x64-51
curl -L https://github.com/sass/node-sass/releases/download/v4.5.0/linux-x64-51_binding.node -o node-sass/vendor/linux-x64-51/binding.node

Keep an eye out for different versions for the pre-compiled native bindings at: https://github.com/sass/node-sass/releases

Snowslide answered 30/1, 2017 at 19:7 Comment(8)
I manage to get the binding file locally and built from the Dockerfile, however the new error I'm getting now is: web_1 | Error: /my_app/node_modules/node-sass/vendor/linux-x64-51/binding.node: invalid ELF header Thoughts?Abbie
Don't pull stuff on the binaries repo, it's just a scratchpad for the maintainers that will go away. If you're going to curl the binaries, use the GH releases attachmentsUnderlayer
Using the GH releases attachement did not solve the issue. I'm still getting the error: Error: /my_app/node_modules/node-sass/vendor/linux-x64-51/binding.node: invalid ELF headerAbbie
Which version of node-sass are you using?Snowslide
If you're running Alpine, then you'll need the "Musl" variant linux_musl-x64-51_binding.nodeUnderlayer
I just realized my mistake in the answer. It should have been curl -L and not just curl. @Abbie Please try again. @Underlayer , docker image for node:7.2.1 uses debian8.Snowslide
Could you have a look at my question here please: #60153962 +1.Rabon
Any help node-sass:6.0.0 Failing to build an image tried to use your curl command to get node-sass binding but curl also fails on node:14.x base image but does work if base image is on ubuntu something wrong to build an image but works on local machine. https://mcmap.net/q/196472/-issue-to-node-sass-and-dockerPalomino
V
10

I have encountered this problem a few times when running my apps within Docker. I believe the problem arises when mounting my local app directory with Docker as this includes the node_modules folder which have been built in a different environment.

My local setup is Mac OSX while Docker is running in linux.

The solution for me was to add a .dockerignore file in the root of my app and add node_modules as per this suggestion https://mcmap.net/q/63418/-node-sass-couldn-39-t-find-a-binding-for-your-current-environment

I then needed to trigger yarn install to run again in my docker container and also ran the node-sass rebuild command with the docker container: docker-compose run web npm rebuild node-sass where web is the name of my docker container.

I suspect my Dockerfile may have a bit of bloat but I will add in case it helps someone:

FROM ruby:2.3.7
ENV BUNDLER_VERSION=1.17.3
RUN gem install bundler -v "$BUNDLER_VERSION" --no-document
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -  
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -   
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list   
RUN apt-get update -qq && apt-get install -y nodejs yarn build-essential libpq-dev postgresql-client
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
ENV RAILS_ENV docker    
ENV WEBPACKER_DEV_SERVER_PUBLIC localhost:3035  
ENV WEBPACKER_DEV_SERVER_HOST localhost 
COPY package.json *yarn* ./
RUN bundle install
RUN yarn install
COPY . /myapp

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

and my docker-compose.yml

version: '3'
services:
  db:
    image: postgres
    ports: 
      - "5433:5432"
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    environment: 
      - RAILS_ENV=development
      - NODE_ENV=development
      - WEBPACKER_DEV_SERVER_PUBLIC=localhost:3035
      - WEBPACKER_DEV_SERVER_HOST=localhost
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
      - redis
      #- elasticsearch
  redis:
    image: redis:alpine
Valerlan answered 22/5, 2019 at 14:30 Comment(4)
second this solution, worked for me. More about my situation: angular-cli uses node-sass 4.9.3, my macos has node 12; while in container I have node 10 and is debian (make sure your node-sass plays well with your node version - saw several people got caught by this). Exclude node_module in .dockerignore, do a node-sass rebuild, then TA-DA - it worked.Luff
thanks, ENV RAILS_ENV docker doesn't sound right, ENV RAILS_ENV development makes more sense, until you go to prodSoke
You are probably right. I set up a separate environment as not all our devs are using Docker at the moment and I didn't want to interfere with their setup.Valerlan
Thanks very much, the .dockerignore of node_modules did the trick. I didn't appear to need a node-sass rebuild on my end with node 10.16.3 // node-sass 4.13.0, but happily seeing nodemon restarting the docker-compose owned express procs with changes to osx dev env. You rescued me from a brain scratcher :+1:Gum
B
0

I was able to solve this problem by changing:

RUN npm rebuild node-sass

to:

RUN npm rebuild node-sass --sass-binary-name = linux-x64-83

Pointing out which distro to run. In my case I had to see which version I was requesting, which in this case is Linux x64-83.

Here is the list of versions that may exist: https://github.com/sass/node-sass/releases

Burwell answered 22/2, 2021 at 15:26 Comment(0)
C
0

I did this for docker, yarn and react

# pull the base image
FROM node:lts-alpine

# set the working direction
WORKDIR /app

# add `/app/node_modules/.bin` to $PATH
ENV PATH /app/node_modules/.bin:$PATH

# install app dependencies
COPY package.json ./

COPY yarn.lock ./

# rebuild node-sass
RUN yarn add node-sass

RUN yarn

# add app
COPY . ./

# start app
CMD ["yarn", "start"]
Chalutz answered 22/7, 2021 at 23:40 Comment(0)
N
0

for a newbie like me

step 1 : open terminal from docker container

enter image description here

Step 2: then run command `npm rebuild node-sass

enter image description here

Step 3: Restart the container after this it should work

enter image description here

Nester answered 8/6, 2022 at 10:42 Comment(0)
B
0

I have a similar error, only when I run the docker container on a Linux machine, in MAC is working perfect!! I think it could be related to the paths? But I am not sure.

ERROR in ./node_modules/slick-carousel/slick/slick.css
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleError: Module Error (from ./node_modules/sass-loader/dist/cjs.js):
globalThis is not defined
    at Object.emitError (/var/www/html/webroot/node_modules/webpack/lib/NormalModule.js:614:6)
    at getSassImplementation (/var/www/html/webroot/node_modules/sass-loader/dist/utils.js:60:21)
    at Object.loader (/var/www/html/webroot/node_modules/sass-loader/dist/index.js:35:59)
 @ ./admin/js/react/templates/Events/EventsList.js 15:0-40
 @ ./admin/js/react/templates/Events/Events.js 10:0-38 119:39-49
 @ ./admin/js/index.js 232:11-58

86 ERRORS in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
Baylor answered 18/8, 2023 at 9:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.