Docker Node Alpine Image Build Fails on node-gyp
Tags: docker, beginners, typescript, node
Published: 2020-09-23 09:23:28

##Docker node:7.9-alpine unable to build package due python is not installed :Resolved##

I'm attempting to Dockerize a node.js application(Typescript). I'm using the node:12.18.4-alpine Docker image as a base.

I go this

##gyp ERR! configure error
gyp ERR! stack Error: Can't find Python executable "python", you can set the PYTHON env variable.
gyp ERR! stack at PythonFinder.failNoPython (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:484:19)
gyp ERR! stack at PythonFinder. (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/configure.js:406:16)
gyp ERR! stack at F (/usr/local/lib/node_modules/npm/node_modules/which/which.js:68:16)
gyp ERR! stack at E (/usr/local/lib/node_modules/npm/node_modules/which/which.js:80:29)
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/which/which.js:89:16
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/isexe/index.js:42:5
gyp ERR! stack at /usr/local/lib/node_modules/npm/node_modules/isexe/mode.js:8:5
gyp ERR! stack at FSReqCallback.oncomplete (fs.js:159:21)
gyp ERR! System Linux 3.10.0-957.el7.x86_64
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "configure" "--fallback-to-build" "--module=/code/server/node_modules/bcrypt/lib/binding/bcrypt_lib.node" "--module_name=bcrypt_lib" "--module_path=/code/server/node_modules/bcrypt/lib/binding" "--napi_version=4" "--node_abi_napi=napi" "--napi_build_version=0" "--node_napi_label=node-v67"
gyp ERR! cwd /code/server/node_modules/bcrypt
gyp ERR! node -v v11.9.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
node-pre-gyp ERR! build error
node-pre-gyp ERR! stack Error: Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/code/server/node_modules/bcrypt/lib/binding/bcrypt_lib.node --module_name=bcrypt_lib --module_path=/code/server/node_modules/bcrypt/lib/binding --napi_version=4 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v67' (1)
node-pre-gyp ERR! stack at ChildProcess. (/code/server/node_modules/bcrypt/node_modules/node-pre-gyp/lib/util/compile.js:83:29)
node-pre-gyp ERR! stack at ChildProcess.emit (events.js:197:13)
node-pre-gyp ERR! stack at maybeClose (internal/child_process.js:978:16)
node-pre-gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)
node-pre-gyp ERR! System Linux 3.10.0-957.el7.x86_64
node-pre-gyp ERR! command "/usr/local/bin/node" "/code/server/node_modules/bcrypt/node_modules/.bin/node-pre-gyp" "install" "--fallback-to-build"
node-pre-gyp ERR! cwd /code/server/node_modules/bcrypt
node-pre-gyp ERR! node -v v11.9.0
node-pre-gyp ERR! node-pre-gyp -v v0.12.0
node-pre-gyp ERR! not ok
Failed to execute '/usr/local/bin/node /usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js configure --fallback-to-build --module=/code/server/node_modules/bcrypt/lib/binding/bcrypt_lib.node --module_name=bcrypt_lib --module_path=/code/server/node_modules/bcrypt/lib/binding --napi_version=4 --node_abi_napi=napi --napi_build_version=0 --node_napi_label=node-v67' (1)
npm WARN backend-botmanagementservice@1.0.0 No description
npm WARN backend-botmanagementservice@1.0.0 No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
........


my docker file was

```Docker
 #MY first stage, that is the Builder
FROM node:12.18.4 AS ts-sample-builder
WORKDIR /app
COPY . .
RUN npm install
RUN npm run clean
RUN npm run build
# My Second stage, that creates an image for production
FROM node:12.18.4 AS ts-sample-prod
WORKDIR /app
COPY --from=ts-sample-builder ./app/dist ./dist
COPY package* ./
RUN npm install --production
CMD npm run start-prod
EXPOSE 3001
```

To reduce image size I change node version node:12.18.4-alpine then it caches issues as I mentioned above.

When using alpine, you need to install build dependencies for some node modules to be able to be built natively. It should probably be documented
Note:
if just use the base as node:12 or any other version your image size will be more than 1GB some cases.

[How to speed up Node re-builds by leveraging Docker multi-stage builds](
https://www.freecodecamp.org/news/speed-up-node-re-builds-leveraging-docker-multi-stage-builds-and-save-money-65189a4ab115/)
if you are using alpine, you need to install build dependencies for some node module to be able to be built natively.

Example

```Docker
FROM node:8.12-alpine
EXPOSE 8080
WORKDIR /app
COPY . .
#python
RUN apk add --no-cache --virtual .gyp \
        python \
        make \
        g++ \
    && npm install \
    && apk del .gyp
CMD ["npm", "start"]
```

Docker and Node.js Best Practices

[Docker and Node.js Best Practices](
https://github.com/nodejs/docker-node/blob/master/docs/BestPractices.md#node-gyp-alpine)

I will suggest you for checking bcrypt $ bcryptjs npm docs.
[node-gyp only works with stable/released versions of node. Since the bcrypt module uses node-gyp to build and install, you'll need a stable version of node to use bcrypt. If you do not, you'll likely see an error that starts with:](https://www.npmjs.com/package/bcrypt#dependencies)

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/krq1f7c8by3mnicz7r53.png)



In the end, It resolves all issues like slow build  &Python is not installed &, etc.

```Dockerfinal
#My first stage, that is the Builder
FROM  node:12.18.4-buster AS build
#RUN apk add --update --no-cache \
#    python \
#    make \
#    g++
COPY . .
# If you have native dependencies, you'll need extra tools
RUN npm install
#RUN npm install
RUN npm run build
RUN npm prune --production
#CMD npm run start-prod
#EXPOSE 3001
## My Second stage, that creates an image for production
FROM node:12.18.4-alpine
WORKDIR /app
COPY --from=build ./dist ./dist
COPY --from=build ./node_modules ./node_modules
CMD npm run start-prod
EXPOSE 3001
```

It worked for me! 

learn more about multi staging.

[Using Multi-Stage Builds to Simplify And Standardize Build Processes](
https://medium.com/capital-one-tech/multi-stage-builds-and-dockerfile-b5866d9e2f84)