【问题标题】:Change node version using nvm and docker-compose使用 nvm 和 docker-compose 更改节点版本
【发布时间】:2020-03-09 12:41:19
【问题描述】:

我有一个运行 centos/systemd 的 Dockerfile,它还安装了 nvm,并且有一个运行 /usr/sbin/init 的 entrypoint.sh(根据文档的要求)它还接受来自 docker-compose 命令的参数来控制节点版本正在使用 - 但似乎节点版本由于某种原因没有持久/保留。

如何通过 docker-compose 文件控制节点版本?

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

码头工人撰写:

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

docker-compose up(输出):

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

谢谢!

【问题讨论】:

  • 一个 Docker 镜像通常会做一个的事情。例如,您实际上没有任何理由在 Dockerfile 中安装三个版本的 Node,因为容器运行的单个应用程序只会使用其中一个。不要使用nvm之类的版本管理器,直接安装你需要的单一版本的Node作为镜像内的“系统”Node即可。
  • 这是开发设置,我有不同的项目需要不同的版本
  • 每个项目都可以有自己的Dockerfile 来适应这种情况。
  • 由于我有多个项目有多种需求,每个项目运行几个容器,想法是创建几个容器,然后将每个项目与 docker-compose 混合匹配。为每个节点版本创建不同的 docker 文件将使其难以维护,因为该容器还运行 apache 和收费的其他服务,因此每次与节点无关的更改都会让我修改所有 docker 文件。我真的希望该命令能够正常工作...除了我所描述的其他所有内容都可以正常工作。

标签: docker docker-compose nvm


【解决方案1】:

如果您为每个项目创建一个 dockerfile,那么对于每个部署,将它们与 docker-compose 文件结合起来,这是您的最佳选择。如果您想促进代码重用,您可以考虑创建一个通用基础镜像,供您的所有 dockerfile 使用。

【讨论】:

    【解决方案2】:

    在网上无休止的搜索后回答我自己的问题。 需要注意/更改的 2 件事:

    1. 我们还需要设置默认节点版本(在 shell 脚本中)。不幸的是,我不知道为什么有必要将其设置为默认值以保持其持久性,但它确实有效(如果有人能解释,请这样做)。所以 entrypoint.sh 看起来像这样:
    #!/bin/bash
    source root/.nvm/nvm.sh && nvm use "$@" && nvm alias default "$@"
    node --version
    exec /usr/sbin/init
    
    1. 当使用docker exec -it <container_id> /bin/sh -c "node --version" 运行 bash 并且未在交互模式或登录到 shell 时,它不会读取启动脚本,因此使用 source /root/.nvm/nvm.shnvm use XXX 设置的节点版本不是红色的,这就是它没有“更改”的原因这个特定的 bash 会话。解决方案是在运行 node --version 例如之前登录容器并从或源 nvm.sh 中运行node --versiondocker exec -it <container_id> sh -c "source /root/.nvm/nvm.sh && node --version"

    希望对遇到同样问题的人有所帮助。

    【讨论】:

      猜你喜欢
      • 2021-02-28
      • 1970-01-01
      • 2019-05-16
      • 2018-04-01
      • 2017-01-04
      • 2018-11-08
      • 1970-01-01
      • 2018-04-11
      • 2020-07-05
      相关资源
      最近更新 更多