在docker容器的shell脚本中使用NPM run start命令时没有找到NPM



我不确定我可能做错了什么,但我有以下script.sh文件坐在我的项目的根:

script.sh

#!/bin/sh
npm run start
envsubst '$PORT' < /etc/nginx/conf.d/configfile.template > /etc/nginx/conf.d/default.conf
nginx -g 'daemon off;'

然后我在我的Dockerfile中引用了上面的脚本,如下所示:

Dockerfile

# Build environment
FROM node:16.14.2
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
# server environment
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/configfile.template
ENV HOST 0.0.0.0
ENV NODE_ENV production
EXPOSE 8080
COPY script.sh /
RUN chmod +x /script.sh
ENTRYPOINT ["/script.sh"]

成功构建Docker映像后,我试图将其作为容器运行,但我一直返回的是以下错误:

/script.sh: line 2: npm: not found

我希望这个脚本能够从环境中获取已经安装的npm。

我能做些什么不同的工作?

你试图运行两个独立的程序,所以在两个不同的容器中运行它们。

# Dockerfile.app
FROM node:16.14.2
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . ./
ENV HOST 0.0.0.0
ENV NODE_ENV production
EXPOSE 8080
CMD npm run start
# Dockerfile.nginx
FROM nginx:alpine
COPY nginx.conf /etc/nginx/conf.d/configfile.template

你可以使用像Docker Compose这样的系统来同时运行这两个部分:

# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.app
nginx:
build:
context: .
dockerfile: nginx
ports:
- 8080:80

运行docker-compose up -d将同时启动两个容器。在您的Nginx配置中,确保使用proxy_pass http://app:8080,使用Compose服务名称和服务正在侦听的端口号,将请求转发到另一个容器。

Nginx Dockerfile看起来很短,但它是正确的。Docker Hubnginx镜像已经知道如何在它自己的入口点脚本中运行脚本中的envsubst行,并且它已经有一个正确的默认命令。

在你的问题中显示的设置中有两个基本问题,都与试图在同一个容器中运行两个程序有关。首先是你不能合并图像,有第二个FROM行使Docker从新的基本图像开始。(所以你的最终图像只包含Nginx,而不是Node或你的构建应用程序,因此npm not found错误。)第二个问题是,脚本将启动应用程序,但直到应用程序退出后才启动Nginx代理。有一些常见的解决方法(比如使用后台进程),但它本质上导致一个进程或另一个进程不受Docker监控,所以你的应用程序可能会失败,而Docker不会注意到它能够重新启动它。

最新更新