首页 > 解决方案 > 将 NodeJS 脚本存储在 Docker 容器之外,以便对其进行修改

问题描述

我对在 Docker 容器中运行 NodeJS 脚本很感兴趣,因为这似乎是在 unRAID 中运行东西的最简单方法(至少是小脚本)。

我当前的 Dockerfile 如下所示:

FROM node:12.9.1

COPY app.js /home/node/
COPY package*.json /home/node/
RUN mkdir /home/node/saves

WORKDIR /home/node
RUN npm install

CMD ["node", "app.js"]

不完美,但效果很好。我的脚本所做的是,它会抓取某些网站的数据,然后将其放在一个名为saves.

但是因为我这样做COPY app.js /home/node/了,每次我想对我的app.js文件进行微小的更改时,我都需要重建整个图像,删除容器,然后开始一个新的。有点烦人,但它对我有用..现在。

当我启动我的容器时,我希望该卷保持不变,所以我这样做:

docker run --net=bridge -h scraper --name scraper -d -v /mnt/user/scripts/scraper/saves:/home/node/saves scraper

这行得通,但正如我所说,如果我想改变我的app.js(比如添加一个新站点来抓取),我必须重建图像并再次运行上述命令。每一次。

还有什么比这更好的方法?我可以通过不复制文件来解决这个问题,而是每次运行一次npm installnode app.js但是这个脚本每 3 分钟运行一次,所以这将是一种巨大的资源浪费。

我还可以将适当的数据存储在我的 /saves/ 文件夹中,然后每次都在 NodeJS 脚本中读取这些数据,但我觉得这有点像 hack。

标签: node.jsdocker

解决方案


使用环境变量。

如果 app.js 文件的更改类型已知,您可以使用环境变量将此类更改提供给 docker run,并使用入口点脚本文件使用环境变量进行此类修改。

入口点脚本的内容将取决于您想要做什么。

# Add to your Dockerfile
ENV SITE_TO_SCRAP=example.com
COPY docker-entrypoint.sh /
RUN chmod +x /docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]

# Run docker with 
-e SITE_TO_SCRAP=abc.com

入口点脚本可能看起来像

#!/bin/bash
# Modify app.js
# Assuming changing the line SCRAP_URL="someurl"
sed -i -e "s@SCRAP_URL=\"someurl\"@SCRAP_URL=\"${SITE_TO_SCRAP}\"@" /home/node/app.js

# This will execute the CMD
exec "$@"

使节点缓存文件夹持久化

npm install在入口点脚本中运行,而不是在 docker 文件中。通过挂载使 node.js 缓存文件夹持久化-v host/path/to/cache:/root/.npm。这种方式节点安装尽可能使用缓存文件。用于docker run --rm node:{version} npm config get cache获取容器缓存目录。

手动挂载修改过的文件。

# To your docker run command add required file/directory mount(s)
-v /path/to/modified/app.js:/home/node/app.js

推荐阅读