更新
我改变了这个问题的方向,最终利用 Docker 图像层来缓存 npm 安装,除非 package.config 发生变化,see here .
请注意,关于这个问题,我仍然在从属 Jenkins Docker 镜像中构建我的 AngularJs Docker 镜像,但我不再在 Docker 从属镜像中运行 npm 安装,我将我的应用程序文件复制到我的 AngularJs Docker 镜像并运行npm install 在 AngularJs Docker 镜像中,从而获得 npm install 的 Docker 缓存层,灵感来自这个伟大的 idea/answer here .
--------------------------------更新结束---------------- ------------------
好吧,我应该补充一点,我在一个 Docker 容器中,但这真的应该无关紧要,我没有停止容器,我有用于 npm 缓存文件夹和/home 的卷运行 npm 命令的用户的文件夹。
安装了 npm 的 Docker 容器的目的是它是一个构建从站,由 Jenkins 启动以构建 AngularJs 应用程序。问题是它非常慢,每次都要下载所有需要的 npm 包。
jenkins
是用户,构建服务器上的 jenkins 帐户是“谁”正在运行 npm install
对于运行 npm install
命令的用户的 npm 文件夹,我有卷:/home/jenkins/.npm
以及命令 的文件夹>npm config get cache
说的是我的缓存目录:/root/.npm
。容器容量并不重要,因为我在运行 npm install
后没有停止容器。
确定我开始调试所采取的步骤,首先,我使用以下命令“进入容器”:
docker exec -it <container_id> bash
我从此时开始运行的所有命令都已连接到安装了 npm 的正在运行的容器。
echo "$HOME"
结果在 /root
npm config get cache
结果在 root/.npm
任何时候 jenkins
在此容器中运行 npm install
,在该命令成功完成后,我运行 npm cache ls
,它总是产生空,没有缓存:~/.npm
但是我们可以通过 ls -a/home/jenkins/.npm/
看到许多包被下载:
所以我尝试将 cache-min 设置为很长的过期时间:npm config set cache-min 9999999
没有帮助。
我不确定还能做什么,似乎我的 npm 包都没有被缓存,我如何让 npm 缓存包?
这里是截断的 npm 安装输出:
Downloading binary from https://github.com/sass/node-sass/releases/download/v4.5.3/linux-x64-48_binding.node
Download complete
Binary saved to /home/jenkins/workspace/tsl.frontend.development/node_modules/node-sass/vendor/linux-x64-48/binding.node
Caching binary to /home/jenkins/.npm/node-sass/4.5.3/linux-x64-48_binding.node
Binary found at /home/jenkins/workspace/tsl.frontend.development/node_modules/node-sass/vendor/linux-x64-48/binding.node
Testing binary
Binary is fine
typings WARN deprecated 3/24/2017: "registry:dt/core-js#0.9.7+20161130133742" is deprecated (updated, replaced or removed)
[?25h
+-- app (global)
`-- core-js (global)
这是我的 Dockerfile:
FROM centos:7
MAINTAINER Brian Ogden
RUN yum update -y && \
yum clean all
#############################################
# Jenkins Slave setup
#############################################
RUN yum install -y \
git \
openssh-server \
java-1.8.0-openjdk \
sudo \
make && \
yum clean all
# gen dummy keys, centos doesn't autogen them like ubuntu does
RUN /usr/bin/ssh-keygen -A
# Set SSH Configuration to allow remote logins without /proc write access
RUN sed -ri 's/^session\s+required\s+pam_loginuid.so$/session optional pam_loginuid.so/' /etc/pam.d/sshd
# Create Jenkins User
RUN useradd jenkins -m -s /bin/bash
# Add public key for Jenkins login
RUN mkdir /home/jenkins/.ssh
COPY /files/id_rsa.pub /home/jenkins/.ssh/authorized_keys
#setup permissions for the new folders and files
RUN chown -R jenkins /home/jenkins
RUN chgrp -R jenkins /home/jenkins
RUN chmod 600 /home/jenkins/.ssh/authorized_keys
RUN chmod 700 /home/jenkins/.ssh
# Add the jenkins user to sudoers
RUN echo "jenkins ALL=(ALL) ALL" >> etc/sudoers
#############################################
# Expose SSH port and run SSHD
EXPOSE 22
#Technically, the Docker Plugin enforces this call when it starts containers by overriding the entry command.
#I place this here because I want this build slave to run locally as it would if it was started in the build farm.
CMD ["/usr/sbin/sshd","-D"]
#############################################
# Docker and Docker Compose Install
#############################################
#install required packages
RUN yum install -y \
yum-utils \
device-mapper-persistent-data \
lvm2 \
curl && \
yum clean all
#add Docker CE stable repository
RUN yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
#Update the yum package index.
RUN yum makecache fast
#install Docker CE
RUN yum install -y docker-ce-17.06.0.ce-1.el7.centos
#install Docker Compose 1.14.0
#download Docker Compose binary from github repo
RUN curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#Apply executable permissions to the binary
RUN chmod +x /usr/local/bin/docker-compose
#############################################
ENV NODE_VERSION 6.11.1
#############################################
# NodeJs Install
#############################################
RUN yum install -y \
wget
#Download NodeJs package
RUN wget https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz
#extract the binary package into our system's local package hierarchy with the tar command.
#The archive is packaged within a versioned directory, which we can get rid of by passing the --strip-components 1 option.
#We will specify the target directory of our command with the -C command:
#This will install all of the components within the /usr/local branch
RUN tar --strip-components 1 -xzvf node-v* -C /usr/local
#############################################
#############################################
# npm -setup volume for package cache
# this will speed up builds
#############################################
RUN mkdir /home/jenkins/.npm
RUN chown jenkins /home/jenkins/.npm .
RUN mkdir /root/.npm
RUN chown jenkins /root/.npm .
#for npm cache, this cannot be expressed in docker-compose.yml
#the reason for this is that Jenkins spins up slave containers using
#the docker plugin, this means that there
VOLUME /home/jenkins/.npm
VOLUME /root/.npm
#############################################
最佳答案
当你运行 docker exec -it <container> bash
您以 root
访问 Docker 容器用户。 npm install
因此将缓存保存到 /root/.npm
,这不是容器保存的卷。另一方面, Jenkins 使用 jenkins
用户,保存到 /home/jenkins/.npm
, 正在缓存中。因此,为了模拟实际 Jenkins 工作流程的功能,您需要 su jenkins
在你可以之前npm install
.
话虽这么说,npm 缓存并不是一个完美的解决方案(特别是如果您有大量的自动化 Jenkins 构建)。需要研究的一些事情将是更好的长期解决方案:
安装本地 NPM 缓存,如
sinopia
.我找到了 this guide特别有帮助。使用 Docker 构建您的应用程序(在 Docker 中使用 Docker 可以很好地工作)。 Docker 会在每个构建步骤后进行缓存,从而避免重复获取依赖项。
关于node.js - 如何让 npm 使用缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46922252/