node-sass 和 Docker 的问题

Posted

技术标签:

【中文标题】node-sass 和 Docker 的问题【英文标题】:Issue to node-sass and Docker 【发布时间】:2017-06-16 00:22:10 【问题描述】:

我正在尝试 dockerise 我的节点应用程序。我当前的应用程序是一个带有 postgresql 的 nodejs express 服务器。 ExpressJS 使用 node-sass-middleware 来处理 sass 资产。当我在我的 OSX 机器上本地运行 node 和 postgresql 时,一切正常。当我尝试使用 docker-compose 运行应用程序时,我收到“缺少绑定错误”

这是我的 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

这是我的docker-compose.yml 文件:

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

当我运行 docker-compose up 时,我仍然收到以下错误:

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...

虽然我通过将RUN npm rebuild node-sass 添加到 Dockerfile 中,它会为 docker 容器中的操作系统构建正确的绑定......但它似乎不起作用。

有什么想法吗?

【问题讨论】:

您要安装什么版本的 node-sass-middleware/node-sass。 Node 7 支持是最近才添加的 @nschonni 我正在使用 node-sass-middleware 版本 0.9.8 【参考方案1】:

node-sass v3.7.0 中似乎添加了对 Node.js 7(适用于 Linux 和 OSX)的支持。请确保您使用的版本等于或高于此版本。

您可以更新您的 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

或者您可以在本地下载绑定,然后在不进行任何修改的情况下从 Dockerfile 构建:

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

留意不同版本的预编译本机绑定:https://github.com/sass/node-sass/releases

【讨论】:

我设法在本地获取绑定文件并从 Dockerfile 构建,但是我现在得到的新错误是:web_1 | Error: /my_app/node_modules/node-sass/vendor/linux-x64-51/binding.node: invalid ELF header Thoughts? 不要在二进制 repo 上拉东西,它只是维护者的便签本,将会消失。如果您要卷曲二进制文件,请使用 GH 版本附件 使用 GH 版本附件并没有解决问题。我仍然收到错误:Error: /my_app/node_modules/node-sass/vendor/linux-x64-51/binding.node: invalid ELF header 你使用的是哪个版本的 node-sass? 如果您运行的是 Alpine,那么您将需要“Musl”变体 linux_musl-x64-51_binding.node【参考方案2】:

在 Docker 中运行我的应用程序时,我曾多次遇到此问题。 我相信在使用 Docker 挂载我的本地应用程序目录时会出现问题,因为这包括在不同环境中构建的 node_modules 文件夹。

我的本​​地设置是 Mac OSX,而​​ Docker 在 linux 中运行。

我的解决方案是在我的应用程序的根目录中添加一个 .dockerignore 文件,并根据此建议添加 node_modules https://***.com/a/55657576/3258059

然后我需要触发 yarn install 以在我的 docker 容器中再次运行,并使用 docker 容器运行 node-sass 重建命令:docker-compose run web npm rebuild node-sass 其中 web 是我的 docker 容器的名称。

我怀疑我的 Dockerfile 可能有点臃肿,但我会添加以防它对某人有所帮助:

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"]

还有我的 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

【讨论】:

第二个这个解决方案,对我有用。更多关于我的情况:angular-cli使用node-sass 4.9.3,我的macos有node 12;而在容器中,我有节点 10 并且是 debian(确保您的 node-sass 与您的节点版本配合良好 - 看到有几个人被这个抓住了)。在 .dockerignore 中排除 node_module,进行 node-sass 重建,然后 TA-DA - 它成功了。 谢谢,ENV RAILS_ENV docker 听起来不对,ENV RAILS_ENV development 更有意义,直到你去 prod 你可能是对的。我设置了一个单独的环境,因为目前并非所有开发人员都在使用 Docker,我不想干扰他们的设置。 非常感谢,node_modules 的 .dockerignore 成功了。我似乎不需要使用 node 10.16.3 // node-sass 4.13.0 重新构建 node-sass,但很高兴看到 nodemon 通过更改 osx dev env 重新启动 docker-compose 拥有的 express procs。你把我从脑筋急转弯中救了出来:+1:【参考方案3】:

我可以通过改变来解决这个问题:

RUN npm rebuild node-sass

到:

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

指出要运行的发行版。在我的情况下,我必须查看我请求的版本,在这种情况下是 Linux x64-83

以下是可能存在的版本列表: https://github.com/sass/node-sass/releases

【讨论】:

【参考方案4】:

我为 docker、yarn 和 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"]

【讨论】:

以上是关于node-sass 和 Docker 的问题的主要内容,如果未能解决你的问题,请参考以下文章

node-sass 和 Docker 的问题

Docker容器中的Node-sass绑定问题

Mac node-sass 安装失败“v8::String::Utf8Value”

Mac node-sass 安装失败“v8::String::Utf8Value”

node-sass和dart-sass区别(以及解决M1芯片/arm芯片无法使用node-sass的问题)

解决windows下node-sass安装失败和版本过高的问题