skip to Main Content

I have a Dockerfile running centos/systemd that also installs nvm and have an entrypoint.sh that runs /usr/sbin/init (as required by docs) it also accept an argument from docker-compose command to control the node version being used – BUT it seems the node version is not persistent/kept for some reason.

How can I control node version from docker-compose file?

Dockerfile:

FROM centos/systemd

# Install & enable httpd
RUN yum -y update
RUN yum -y install 
    httpd 
    autofs 
    gcc-c++ 
    make 
    git 
    fontconfig 
    bzip2 
    libpng-devel 
    ruby 
    ruby-devel 
    zip 
    unzip
RUN yum clean all
RUN systemctl enable httpd.service

# Setting up virtual hosts
RUN echo "IncludeOptional apps/*.conf" >> /etc/httpd/conf/httpd.conf

# Install nvm to later use in compose
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION 13.10.0
RUN curl --silent -o- https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash

# install node and npm
RUN source $NVM_DIR/nvm.sh 
    && nvm install $NODE_VERSION 
    && nvm install 12.16.1 
    && nvm install 11.9.0 
    && nvm install 10.9.0 
    && nvm alias default $NODE_VERSION 
    && nvm use default

# add node and npm to path so the commands are available
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH

# Expose ports
EXPOSE 80
EXPOSE 443

COPY entrypoint.sh ./entrypoint.sh
RUN chmod +x ./entrypoint.sh

ENTRYPOINT ["./entrypoint.sh"]

entrypoint.sh:

#!/bin/bash
source root/.nvm/nvm.sh && nvm use "$@"
node --version
exec /usr/sbin/init

docker-compose:

version: '3'
services:
  httpd:
    build: '..Web-ServerApache'
    privileged: true
    ports:
      - 80:80
      - 443:443
    command: 11.9.0

docker-compose up (output):

httpd_1  | Now using node v11.9.0 (npm v6.5.0)
httpd_1  | v11.9.0

docker exec -it /bin/sh -lc “node –version”:

v13.10.0

Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    Answering my own question after endless searches across the web. 2 things to note/change:

    1. We need to set the default node version as well (inside the shell script). Unfortunately, I don't no why it's necessary to set it as default to keep it persistent but it just works (if anyone can explain that, please do). So entrypoint.sh looks like this:
    #!/bin/bash
    source root/.nvm/nvm.sh && nvm use "$@" && nvm alias default "$@"
    node --version
    exec /usr/sbin/init
    
    1. when running bash with docker exec -it <container_id> /bin/sh -c "node --version" and not in interactive mode or login to shell it will not read startup scripts so node version set by using source /root/.nvm/nvm.sh and nvm use XXX is not red and thats why it's not "changed" for this specific bash session. Solution is to login to container and run node --version from within OR source nvm.sh as well before running node --version e.g. docker exec -it <container_id> sh -c "source /root/.nvm/nvm.sh && node --version"

    Hope that helps to anyone that came across the same issue.


  2. If you create a dockerfile for each project then, combine them with docker-compose files, for each deployment, that is your best option. If you want to facilitate for code reuse you can look at creating a generic base image to which all your dockerfiles use.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search