3

I need to extend a Dockerfile and add grunt to it. I did the following:

This docker run as-is

    FROM openjdk:8-jdk-slim
    ARG ND=v12.13.0

    RUN apt-get update && \
        apt-get install --yes --no-install-recommends curl  && \

        NODE_H=/opt/nodejs; mkdir -p ${NODE_H} && \
        curl --fail --silent --output - "http://nodejs.org/dist/${ND}/node-${ND}-linux-x64.tar.gz" \
         | tar -xzv -f - -C "${NODE_H}" && \
        ln -s "${NODE_H}/node-${ND}-linux-x64/bin/npm" /usr/local/bin/npm && \
        ln -s "${NODE_H}/node-${ND}-linux-x64/bin/node" /usr/local/bin/node && \
        ln -s "${NODE_H}/node-${ND}-linux-x64/bin/npx" /usr/local/bin/ && \



    npm install grunt-cli -g

    RUN grunt -v

I've put also the following which doesn't help...

ENV PATH="$PATH:/usr/local/bin"

When I run the command grunt-v I get the following error:

/bin/sh: 1: grunt: not found.

I try also to install grunt through npm install grunt -g without success. Any idea how to fix it?

grunt output from docker build

/opt/nodejs/node-v12.13.0-linux-x64/bin/grunt -> /opt/nodejs/node-v12.13.0-linux-x64/lib/node_modules/grunt-cli/bin/grunt
+ grunt-cli@1.3.2

I need the grunt command to be available in this docker image

I cannot change the docker image, i.e. form jdk...this is given

update

I've also tried with what VonC suggested but still have issue,

FROM openjdk:8-jdk-slim


ARG ND=v12.13.0

RUN apt-get update && \
    apt-get install --yes --no-install-recommends curl  && \

    # install node
    NODE_HOME=/opt/nodejs; mkdir -p ${NODE_HOME} && \
    curl --fail --silent --output - "http://nodejs.org/dist/${ND}/node-${ND}-linux-x64.tar.gz" \
     | tar -xzv -f - -C "${NODE_HOME}" && \
    ln -s "${NODE_HOME}/node-${ND}-linux-x64/bin/node" /usr/local/bin/node && \
    ln -s "${NODE_HOME}/node-${ND}-linux-x64/bin/npm" /usr/local/bin/npm && \
    ln -s "${NODE_HOME}/node-${ND}-linux-x64/bin/npx" /usr/local/bin/ && \



    npm install -g grunt-cli

ENV PATH="${PATH}:/usr/local/bin"
RUN ls /usr/local/bin/
RUN grunt -v

the ls command returns


docker-java-home
node
npm
npx

Any idea what is missing?

JME
  • 881
  • 2
  • 11
  • 23
  • Can you start from a `node` base image that will have all of the standard paths set up correctly? – David Maze Nov 15 '19 at 10:43
  • @DavidMaze - Thanks but this is given and I cannot change it, there is no way to use it with the existing java image? – JME Nov 15 '19 at 11:04
  • @Jhon D - Of course, there is a way to work with your given image, but the node base image would most likely be a better fit. A working example based on your base image (openjdk:8-jdk-slim) is in my answer below – ckaserer Nov 18 '19 at 13:23
  • @John D: did you get it working based on the answers provided or are there open issues left? – ckaserer Nov 21 '19 at 08:55

3 Answers3

6

this will work:

FROM openjdk:8-jdk-slim


ARG ND=v12.13.0

RUN apt-get update && \
    apt-get install --yes --no-install-recommends curl \
    && NODE_HOME=/opt/nodejs; mkdir -p ${NODE_HOME} \
    && curl --fail --silent --output - "http://nodejs.org/dist/${ND}/node-${ND}-linux-x64.tar.gz" \
     | tar -xzv -f - -C "${NODE_HOME}" \
    &&  ln -s "${NODE_HOME}/node-${ND}-linux-x64/bin/node" /usr/local/bin/node \
    && ln -s "${NODE_HOME}/node-${ND}-linux-x64/bin/npm" /usr/local/bin/npm \
    && ln -s "${NODE_HOME}/node-${ND}-linux-x64/bin/npx" /usr/local/bin/ \
    && npm install --prefix /usr/local/ -g grunt-cli

ENV PATH="${PATH}:/usr/local/bin"
RUN ls /usr/local/bin
RUN grunt -v

using --prefix will tell npm to install grunt in /usr/local/bin

ls output:

Step 5/6 : RUN ls /usr/local/bin
 ---> Running in 96493743512d
docker-java-home
grunt
node
npm
npx

grunt -v output:

Step 6/6 : RUN grunt -v
 ---> Running in c6248c4fce6c
grunt-cli: The grunt command line interface (v1.3.2)
LinPy
  • 16,987
  • 4
  • 43
  • 57
  • It works but `/usr/local/bin` is already in PATH for `openjdk:8-jdk-slim`, there is no need for `ENV PATH="${PATH}:/usr/local/bin"` – Pierre B. Nov 22 '19 at 11:15
  • yes, I only copy the file as it is from the question :) – LinPy Nov 22 '19 at 11:17
  • Thanks, when I run it I got error, cannot find local grunt , the error is: `grunt-cli: The grunt command line interface (v1.3.2) Fatal error: Unable to find local grunt. If you're seeing this message, grunt hasn't been installed locally to your project. For more information about installing and configuring grunt, ` any idea? – JME Nov 25 '19 at 07:54
  • https://github.com/gruntjs/grunt-docs/issues/38#issuecomment-33422556 – LinPy Nov 25 '19 at 08:01
2

I've put also the following which doesn't help...

ENV PATH="$PATH:/usr/local/bin"

As illustrated here, that should be enough, also the exact syntax would be (to be sure)

ENV PATH="${PATH}:/usr/local/bin"

But:

  • make sure to add it just before your last RUN grunt
  • add a RUN ls /usr/local/bin/ to see if your install command worked
  • try and use the syntax npm instal -g grunt, instead of npm instal grunt -g

Another approach:

The Docker image openjdk:8-jdk-slim is based on debian:buster-slim

So try and install node through its installation script, as seen here:

# install node.js environment
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      gnupg && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*
RUN curl -sL https://deb.nodesource.com/setup_${NODEJS_VERSION}.x | bash -
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
      nodejs && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/* && \
    npm install -g grunt

You can still use the same base image openjdk:8-jdk-slim, but you just extend it with a regular node installation, rather than fiddling with symbolic links.

In your case, add ENV NODEJS_VERSION 12 first.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1

This works

FROM openjdk:8-jdk-slim

ARG NODE_HOME=/opt/nodejs
ARG ND=v12.13.0
ENV PATH=${PATH}:${NODE_HOME}/node-${ND}-linux-x64/bin/

RUN apt-get update && \
    apt-get install --yes --no-install-recommends curl  && \
    # install node
    mkdir -p ${NODE_HOME} && \
    curl --fail --silent --output - "http://nodejs.org/dist/${ND}/node-${ND}-linux-x64.tar.gz" \
     | tar -xzv -f - -C "${NODE_HOME}" && \
    npm install -g grunt-cli

RUN grunt -v

First, move NODE_HOME up in your dockerfile and set it as a build arg.

That way we can already set the PATH early on.

By setting the path to the node bin folder we can use all binaries in that location without manually linking each. That translates to grunt being available after installation without additional black magic.

ckaserer
  • 4,827
  • 3
  • 18
  • 33