Docker会在package.json文件改变时自动重新运行npm install。

6
我正在尝试为node.js项目设置开发容器,以便将本地源文件与客户端共享(这样我就可以在端口80上通过 dnsmasq 通配符请求到本地域,但我想这与问题无关)。当我在本地进行更改时,容器中的node进程将被重新启动: < p > < code > Dockerfile :

FROM node:8

# Install app dependencies
RUN npm install -g nodemon
COPY package.json /tmp/package.json
RUN cd /tmp && npm install --production

NODE_PATH=/tmp/node_modules
WORKDIR /app

EXPOSE 8080
EXPOSE 9229

CMD nodemon --inspect index.js

docker-compose.json(已缩短):

version: '3.3'
services:
    app:
        build: .
        container_name: 'my-app'
        restart: unless-stopped
        ports:
            - 8080:8080
            - 9229:9229
        volumes:
            - .:/app

由于node_modules已经在Dockerfile中安装,每当我向packages.json添加一个包时,就必须手动重新构建容器:

docker-compose stop
docker-compose build
docker-compose up -d

我可以使用inotify来设置此项监视,但我不想停止整个堆栈(包括在其中定义的其他服务)。

是否可能将此逻辑放置在容器内,并在每次更改package.json时重新运行npm install

2个回答

2

是否可以在容器内部实现此逻辑,并在每次更改package.json时重新运行npm install?

我不完全清楚,您是在主机上还是在/tmp/目录中的docker容器中更改了package.json。 我猜您在主机上修改文件,因为您在那里有其他项目文件。

如果您将package.json修改为/tmp之外的其他位置,则需要手动将新版本的package.json复制到容器中的/tmp中。

docker cp "location/of/package.json" "containername":/tmp/

然后您只需进入容器并安装依赖项。

docker exec -it containername bash
cd /tmp/
npm install

可以将这个逻辑放在容器内,在每次更改package.json时重新运行npm install吗?
您可以将上面描述的逻辑传递给一个简单的bash脚本。然后,您可以运行一些监视器(例如nodemon)来观察package.json,并在文件更改后运行该脚本。也许最好传递大延迟,以便在您输入完整名称之前不尝试安装模块。但在大多数情况下,我猜您只是使用npm命令而不是手动输入模块名称。

1

解决方案

我编写了一个入口文件,在node.js中启动了两个线程,因此Dockerfile可以非常简单。现在我们只需要docker-compose

Dockerfile

FROM node:8
RUN npm install -g nodemon

docker-compose.yml

version: '3.5'
services:
    app:
        build: .
        user: '1000'
        working_dir: /opt/app
        ports:
            - 8080:8080
            - 9229:9229
        volumes:
            - ./:/opt/app
        command: 'node docker-entry.js'

docker-entry.js

/**
 * @file docker-entry for development container
 * @author Redsandro (https://www.windowsremix.com/)
 */
'use strict'
const { spawn } = require('child_process')

/*
 * Install dependencies every time package.json changes
 */
spawn('nodemon -w package.json --exec "npm install"', {
    stdio: 'inherit',
    shell: true
})

/*
 * Restart node when a source file changes, plus:
 * Restart when `npm install` ran based on `package-lock.json` changing.
 */
spawn('nodemon --inspect -e js,json -i node_modules -i package.json index.js', {
    stdio: 'inherit',
    shell: true
})

.dockerignore

# Just ignore everything
**

这是因为当添加或更新依赖项时,package-lock.json会发生变化。因此需要npm 5。未在其他节点映像上进行测试。
在第一次运行时,请确保工作目录中没有node_modulespackage-lock.json。内部节点应用程序将在第一次运行时崩溃(显然,它找不到依赖项),但一旦安装了依赖项,它将重新启动。
输入docker-compose up -d && docker-compose logs -f以查看结果。对文件进行一些更改,并向package.json添加一个包。
每次启动容器时,都会运行npm install,这在10次中有9次是不必要的,除非您在停止容器时更改了package.json。这没问题,因为节点应用程序是并行启动的,您不必等待其完成。 您可以立即使用容器。(当然,如果这是您第一次运行,则除外。) 待办事项:我原本希望将node_modules移动到一些客户目录(例如/tmp),以便所有这些数据都存储在Docker服务器上,而不是在我的笔记本SSD上。更重要的是,您的主机和客户端现在共享相同的node_modules。如果您使用非Linux操作系统并编译软件包,则会遇到麻烦。因为它只能在主机中或者在客户端中运行,而不能同时在两者中都运行。我似乎无法像之前一样指定不同的安装目录npm,没有npm也会将其写入package-lock.json,而该文件对于此设置的本地目录是必需的。我相信通过一些巧妙的链接可以解决这个问题,但是我已经没有时间来实现这个解决方案。欢迎提供提示。请随意添加附加说明和其他答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接