将 Docker 与具有 node-gyp 依赖项的 nodejs 一起使用

Using Docker with nodejs with node-gyp dependencies

我打算使用 Docker 来部署 node.js 应用程序。该应用程序有几个需要 node-gyp 的依赖项。 Node-gyp 在交付平台上针对已编译的库构建这些模块(例如 canvas、lwip、qrcode),根据我的经验,这些构建可能高度依赖于 o/s 版本和安装的库,并且它们经常破解一个简单的 npm install.

那么从 node:version 构建我的 Docker 文件 是正确的方法吗?这似乎是我迄今为止发现的每个 Docker/Node 教程中显示的方法。但是如果我从节点镜像构建,部署容器时会发生什么?如何确保目标主机具有编译 node-gyp 模块所需的库?

我正在寻找的另一种方法是构建 Docker 文件 FROM ubuntu:version。但我认为这意味着将 nodeJS 安装到 Ubuntu 图像中,整个东西会大得多。

还有其他处理方法吗?

How can I ensure the target host will have the libraries needed to compile the node-gyp modules?

目标主机也是运行宁docker。只要依赖项在您的映像中,那么您的服务器也会有它们。如果你问我,这就是 docker 的全部意义。如果它 运行 在本地,那么它也会在服务器上 运行。

对于更小的文件,我会选择 node-alpine (FROM node:8-alpine)。在我全神贯注于 node-gyp 之前,我一直在与它作斗争,但现在我什至不明白我曾认为这是一个问题。只要添加构建工具 RUN apk add python make gcc g++ 就可以了(但是这会增加 100-200mb 的大小)。

此外,如果它变得非常耗时(比如您发现自己不时使用 --no-cache 重建图像),那么最好将其拆分为您自己的基础图像和另一张图片 FROM my-base-image:latest,其中包含您经常更改的内容。

肯定有一些学习曲线,但我没有发现它那么陡峭。至少如果你之前接触过 docker 就不会。

The other way I'm looking at is to build the Dockerfile FROM ubuntu:version.

我在跳上 docker 之前只使用了 CentOS,而我在我的服务器上使用了 运行 CentOS。所以我认为 运行 CentOS-images 也是个好主意,但我发现这很愚蠢。除非您需要非常 OS 的东西,否则增益绝对为零。现在我只使用 alpine 大概半年了,到目前为止,我唯一需要学习的 alpine 特定命令是 apk add/del.

您可能已经知道了,但不要在一开始就花太多时间优化 docker 文件大小。 (你可以通过在一行中组合命令来减少图层大小很多,(添加包,运行ning 命令,删除包)。但是如果你做任何大层中的小变化。最好在重要之前将其保留。

回头看(2 年后),在容器中管理节点依赖项仍然是一个挑战。我现在做的是:

  1. 构建 docker 图像 FROM node:10.16.0-alpine(或其他节点 版本)。这些是 hub.docker.com 上的官方 node 图片。 Docker 推荐alpine,Nodejs建立在它之上,包括 node-gyp,所以这是一个很好的起点;

  2. 包含一个 运行 apk 添加 --no-cache 以包含所有库 需要构建依赖模块,例如canvas(见下面的例子);

  3. 在 docker 构建文件中包含一个 运行 npm install canvas;这个 将节点模块(例如 canvas)构建到 docker 图像 中,因此它会从该图像加载到任何容器 运行 中。

但这可能会变得丑陋。 Alpine 使用与更重量级 OS 不同的库:值得注意的是,alpine 使用 musl 代替 glibc。依赖模块可能需要 link 到 glibc,所以你必须将它添加到映像中。 Sasha Gerrand 提供了一种方法 alpine-pkg-glibc

示例安装 node-canvas v2.5,links 到 glibc:

#  geo_core layer
#  build on a node image, in turn built on alpine linux, Docker's official linux pulled from hub.docker.com

FROM node:10.16.0-alpine

#  add libraries needed to build canvas
RUN apk add --no-cache \
    build-base \
    g++ \
    libpng \
    libpng-dev \
    jpeg-dev \
    pango-dev \
    cairo-dev \
    giflib-dev \
    python \
    ; \

#  add glibc and install canvas
RUN apk --no-cache add ca-certificates wget  && \
    wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
    wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-2.29-r0.apk && \
    apk add glibc-2.29-r0.apk && \
    npm install canvas@2.5.0
    ;

如果你需要使用 node-gyp 构建东西,你可以添加下面的行,替换你的 npm installyarn install:

RUN apk add --no-cache --virtual .build-deps make gcc g++ python \
RUN npm install --production --silent \
RUN apk del .build-deps

或者更简单的,你可以安装类似于Debian的build-essentials

alpine-sdk
RUN apk add --no-cache --virtual .build-deps alpine-sdk python \
RUN npm install --production --silent \
RUN apk del .build-deps

来源https://github.com/mhart/alpine-node/issues/27#issuecomment-390187978