80

I am user of AWS elastic beanstalk, and I have a little problem. I want to build my CSS files with less+node. But I don`t know how to install node in my dockerfile, when building with jenkins.

Here is installation packages what I am using in my docker. I will be glad for any suggestions.

FROM php:5.6-apache


# Install PHP5 and modules along with composer binary
RUN apt-get update
RUN apt-get -y install \
    curl \
    default-jdk \
    git \
    libcurl4-openssl-dev \
    libpq-dev \
    libmcrypt-dev \
    libpq5 \
    npm \
    node \
    zlib1g-dev \
    libfreetype6-dev \
    libjpeg62-turbo-dev \
    libpng12-dev

RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/

RUN docker-php-ext-install curl json mbstring opcache pdo_mysql zip gd exif sockets mcrypt

# Install pecl
RUN pecl install -o -f memcache-beta \
    && rm -rf /tmp/pear \
    && echo 'extension=memcache.so' > /usr/local/etc/php/conf.d/memcache.ini

After this I am runing my entrypoint.sh with code

#!/usr/bin/env sh

composer run-script post-install-cmd --no-interaction

chmod 0777 -R /var/app/app/cache
chmod 0777 -R /var/app/app/logs

exec apache2-foreground

But then I`ve got this error

 Error Output: [2016-04-04 11:23:44] assetic.ERROR: The template ":tmp:module.html.twig" contains an error: A template that extends another one cannot have a body in ":tmp:module.ht  
  ml.twig" at line 7.     

But when I install inside the Docker container node this way

apt-get install git-core curl build-essential openssl libssl-dev
 git clone https://github.com/nodejs/node.git
 cd node
 ./configure
 make
 sudo make install
 node -v

I can build my CSS. So question is..how this installation above make install inside my Dockerfile when I am building it with Jenkins?

Delirium
  • 1,277
  • 3
  • 16
  • 27
  • Whatever you are hoping to accomplish, **`chmod 777` is *wrong* and *dangerous.*** You absolutely do not want to grant write access to executable or system files to all users under any circumstances. You will want to revert to sane permissions ASAP (for your use case, probably simply make sure the files have the correct owner, and stick to `0755`) and learn about the Unix permissions model before you try to use it again. If this happened on a system with Internet access, check whether an intruder could have exploited this to escalate their privileges. – tripleee Sep 04 '22 at 10:09

11 Answers11

149

I think this works slightly better.

ENV NODE_VERSION=16.13.0
RUN apt install -y curl
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN node --version
RUN npm --version

Note that nvm is a version manager for node.js, designed to be installed per-user, and invoked per-shell. nvm works on any POSIX-compliant shell (sh, dash, ksh, zsh, bash), in particular on these platforms: unix, macOS, and windows WSL.

castis
  • 8,154
  • 4
  • 41
  • 63
Nathan
  • 1,491
  • 2
  • 6
  • 2
  • 6
    Why do you think so? – Dawid Laszuk Sep 01 '19 at 18:26
  • 3
    This seems like a better answer, as it lets you easily specify the Node version, and the docker build is much faster with nvm, versus building from source within docker – Sam Jun 20 '20 at 17:41
  • 2
    To add how fast: Answer from Nathaniel took 5 minutes before I quit the build to try this one. This one took around 15 secs. – Marek Židek Aug 28 '20 at 09:40
  • 9
    FYI, for anyone else wanting to put the NVM_DIR in some non-standard location, the `ENV NVM_DIR=/somewhere-else/.nvm` line must go before the "curl | bash" line in order to be respected by the install script. – jdmcnair Oct 16 '20 at 02:29
  • FYI, the ```NVM_DIR``` was giving an error that the path does not exists. So I had ```mkdir``` the path before ```curl``` line – Sagar Kamble Sep 23 '21 at 17:54
  • line 3 should be `RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash` *the path has an extra `/install.sh` at the end – dgrijuela Nov 21 '21 at 12:01
  • Thank you for this answer this works like charm. Many other answers I found on other questions did not work. – Snake_py Jul 04 '22 at 08:01
  • 2
    This was awesome. Just a small add. It would probably be better if the ENV line said: `ENV PATH="$NVM_DIR/versions/node/v${NODE_VERSION}/bin/:${PATH}"`. That way it dynamically changes the path if you use a different *$NVM_DIR*. – Magnus Apr 23 '23 at 16:59
37

Running apt-get install node does not install Node.js, because that's not the package you're asking for.

If you run apt-cache info node you can see that what you are installing is a "Amateur Packet Radio Node program (transitional package)"

You should follow the Node.js install instructions to install via package manager.

Or if you like building from git, you can just do that inside Docker:

RUN apt-get install -y git-core curl build-essential openssl libssl-dev \
 && git clone https://github.com/nodejs/node.git \
 && cd node \
 && ./configure \
 && make \
 && sudo make install
NiRR
  • 4,782
  • 5
  • 32
  • 60
Nathaniel Waisbrot
  • 23,261
  • 7
  • 71
  • 99
  • 4
    If you are looking for a more recent answer have a look at this one below https://stackoverflow.com/a/67491580/411428 His/her/their idea work just fine as well and does not require `sudo` which you may not want or have in your docker image. – Manfred May 22 '21 at 23:39
36

According to the following answer, I would suggest using npm via the n package, that lets you choose the nodejs version, or use the latest tag or the lts tag. For example for latest:

RUN apt-get update && apt-get install -y \
    software-properties-common \
    npm
RUN npm install npm@latest -g && \
    npm install n -g && \
    n latest
Manfred
  • 5,320
  • 3
  • 35
  • 29
loretoparisi
  • 15,724
  • 11
  • 102
  • 146
  • 4
    Great answer! Short, to the point and it just works. Nice! To use LTS just replace `latest` with `lts` in the code snippet of the answer. – Manfred May 22 '21 at 23:43
  • Another small suggestion -- depending on the base image you have, you may have to install `curl` or `wget` for `n` to fetch a node binary. ```apt-get install -y curl``` – Achintya Ashok May 14 '23 at 16:21
  • i get error : ```0.379 node: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.27' not found (required by node) 0.379 node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by node) 0.379 node: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by node)``` actualy i get this error for all solutions :) – mahdi Aug 01 '23 at 01:30
35

Just 2 lines

RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - 
RUN apt-get install -y nodejs
giapnh
  • 2,950
  • 24
  • 20
  • This line gives me following error message: `debconf: unable to initialize frontend: Dialog debconf: (TERM is not set, so the dialog frontend is not usable.) debconf: falling back to frontend: Readline debconf: unable to initialize frontend: Readline debconf: (This frontend requires a controlling tty.) debconf: falling back to frontend: Teletype dpkg-preconfigure: unable to re-open stdin:` – alper Apr 15 '22 at 22:06
  • @alper set `ARG DEBIAN_FRONTEND=noninteractive` in your Dockerfile, that should solve the issue – Ani Oct 21 '22 at 05:46
  • Is it better than accepted answer from @Nathan, which installs nvm first? – AlexFreik Jul 09 '23 at 10:40
20

Get the node image and put it at the top of your dockerfile:

FROM node:[tag_name] AS [alias_name]

Verify the version by adding following code:

RUN echo "NODE Version:" && node --version
RUN echo "NPM Version:" && npm --version

Then add the following code every time you need to use nodejs in a container:

COPY --from=[alias_name] . .


From the codes above, replace the following with:

[tag_name] - the tag value of the node image you want to use. Visit https://hub.docker.com/_/node?tab=tags for the list of available tags.

[alias_name] - your preferred image name to use in your dockerfile.


Example:

FROM node:latest AS node_base

RUN echo "NODE Version:" && node --version
RUN echo "NPM Version:" && npm --version


FROM php:5.6-apache

COPY --from=node_base . .

### OTHER CODE GOES HERE
jysummers
  • 649
  • 4
  • 16
  • 1
    For me it did not work with `COPY --from=node_base . .`, but rather with `COPY --from=node_base / /` – Hrvoje Golcic Aug 03 '21 at 00:51
  • 2
    Error: `cannot copy to non-directory: /var/lib/docker/overlay2/oscikzv9ow4kfi4x1dmvw8dmn/merged/usr/include/mysql` – Binh Ho Aug 25 '21 at 04:37
  • I find this solution more elegant, and it also took less time than installing nodejs for me – ccoutinho Dec 02 '22 at 18:30
  • This also works: `COPY --from=node:18.16.0-slim /usr/local/bin /usr/local/bin` if you just want the node binary – veuncent May 09 '23 at 13:26
  • I had to also add `COPY --from=node:18.16.0-slim /usr/local/lib/node_modules/npm /usr/local/lib/node_modules/npm` because `npm` is symlinked to that folder – Yonic Surny May 25 '23 at 16:17
17

Binary download without any compilation

FROM ubuntu

RUN apt-get update && apt-get install -y \
  ca-certificates \
  curl

ARG NODE_VERSION=14.16.0
ARG NODE_PACKAGE=node-v$NODE_VERSION-linux-x64
ARG NODE_HOME=/opt/$NODE_PACKAGE

ENV NODE_PATH $NODE_HOME/lib/node_modules
ENV PATH $NODE_HOME/bin:$PATH

RUN curl https://nodejs.org/dist/v$NODE_VERSION/$NODE_PACKAGE.tar.gz | tar -xzC /opt/

# comes with npm
# RUN npm install -g typescript
Maryan
  • 1,484
  • 1
  • 12
  • 16
8

I am using following Dockerfile to setup node version 8.10.0.

Here I have used NVM (Node Version Manager ), so we can choose which node version should be installed on that container. Please use absolute path of npm when installing node modules (eg: /root/.nvm/versions/node/v${NODE_VERSION}/bin/npm install leasot@latest -g)

   FROM ubuntu:18.04
   ENV NODE_VERSION=8.10.0
   RUN apt-get update && \
       apt-get install wget curl ca-certificates rsync -y
   RUN wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
   ENV NVM_DIR=/root/.nvm
   RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
   RUN . "$NVM_DIR/nvm.sh" &&  nvm use v${NODE_VERSION}
   RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
   RUN cp /root/.nvm/versions/node/v${NODE_VERSION}/bin/node /usr/bin/
   RUN cp /root/.nvm/versions/node/v${NODE_VERSION}/bin/npm /usr/bin/
   RUN /root/.nvm/versions/node/v${NODE_VERSION}/bin/npm install  leasot@latest -g

Note: This is a cropped Dockerfile.

Sijo M Cyril
  • 660
  • 1
  • 8
  • 14
3

The short answer, for example, install v14.17.1

ENV PATH="/opt/node-v14.17.1-linux-x64/bin:${PATH}"
RUN curl https://nodejs.org/dist/v14.17.1/node-v14.17.1-linux-x64.tar.gz |tar xzf - -C /opt/ 

list of all available versions can be found here -> https://nodejs.org/dist/

Maoz Zadok
  • 4,871
  • 3
  • 33
  • 43
3

Directly into /usr/local so it's already in your $PATH

ARG NODE_VERSION=8.10.0
RUN curl https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz | tar -xz -C /usr/local --strip-components 1
jla
  • 9,684
  • 2
  • 21
  • 18
2

The accepted answer gives the link to the installation instructions for all systems, but it won't run out of the box since you often (e.g. for ubuntu) don't have all required dependencies installed (namely curl and sudo).

So here's for example how you'd do it for ubuntu:

FROM ubuntu

# Core dependencies
RUN apt-get update && apt-get install -y curl sudo

# Node
# Uncomment your target version
# RUN curl -fsSL https://deb.nodesource.com/setup_10.x | sudo -E bash -
# RUN curl -fsSL https://deb.nodesource.com/setup_12.x | sudo -E bash -
# RUN curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -
# RUN curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
RUN sudo apt-get install -y nodejs
RUN echo "NODE Version:" && node --version
RUN echo "NPM Version:" && npm --version

then build with

docker build . --progress=plain

to see the output of the echo statements. Of course you could also leave away the echo statements and run it regularly with docker build ., after you've made sure everything is working as intended.

You can also leave away the installation of sudo, but then you'll have to get rid of the sudo occurrences in the script.

bersling
  • 17,851
  • 9
  • 60
  • 74
1
FROM ubuntu:20.04

# all necessaries for next RUN
RUN set -e; \
    apt-get update && \
    apt-get install -qqy --no-install-recommends \
    curl wget nano gnupg2 software-properties-common && \
    rm -rf /var/lib/apt/lists;

RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -

# uncomment for checking versions
  # Step 4/10 : RUN apt-cache show nodejs | grep Version;return 1;
  #  ---> Running in xxxxxxxxx
  # Version: 14.18.2-deb-1nodesource1
  # Version: 10.19.0~dfsg-3ubuntu1
#RUN apt-cache show nodejs | grep Version;return 1;

RUN set -e; \
    apt-get update && \
    apt-get install -qqy \
    nodejs && \
    rm -rf /var/lib/apt/lists;

# uncomment for check
# RUN node  -v
Benoit
  • 31
  • 3