【问题标题】:How can I run an npm command in a docker container?如何在 docker 容器中运行 npm 命令?
【发布时间】:2020-05-21 06:31:35
【问题描述】:

我正在尝试在 docker 容器内以开发模式运行 Angular 应用程序,但是当我使用 docker-compose build 运行它时,它可以正常工作,但是当我尝试放置容器时,出现以下错误:



ERROR: for sypgod  Cannot start service sypgod: OCI runtime create failed: container_linux.go:346: starting container process caused "exec: \"npm\": executable file not found in $PATH

真正的问题是它无法识别命令 npm serve,但是为什么呢??

设置如下:

Docker 容器(Nginx 反向代理 -> Angular 运行在 4000 端口)

我知道有更好的方法来部署它,但由于某些个人原因,我现在需要这个设置

Dockerfile:


FROM node:10.9 


COPY package.json package-lock.json ./

RUN npm ci && mkdir /angular && mv ./node_modules ./angular

WORKDIR /angular

RUN npm install -g @angular/cli 

COPY . . 


FROM nginx:alpine
COPY toborFront.conf /etc/nginx/conf.d/
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
CMD ["npm", "serve", "--port 4000"]

Nginx 服务器站点

server{
    listen 80;
    server_name sypgod;


    location / {
            proxy_read_timeout 5m;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://localhost:4000/;


    }

}


Docker Compose 文件(我遇到问题的重要部分)

 sypgod: # The name of the service
        container_name: sypgod  # Container name
        build: 
            context: ../angular
            dockerfile: Dockerfile # Location of our Dockerfile


【问题讨论】:

    标签: node.js angular docker npm docker-compose


    【解决方案1】:

    似乎无法从容器访问 npm。 尝试定义它尝试从哪里执行它:

    docker run -v "$PWD":/usr/src/app -w /usr/src/app node:10.9 npm serve --port 4000
    

    来源:https://gist.github.com/ArtemGordinsky/b79ea473e8bc6f67943b

    还要确保在运行 docker 容器的计算机上安装了 npm。

    【讨论】:

    • 感谢您的解决方案。为什么需要在主机上安装 npm?没有它它也能工作,从 docker 运行 npm 不是整个想法吗?
    【解决方案2】:

    您可以执行以下操作

    ### STAGE 1: Build ###
    
    # We label our stage as ‘builder’
    FROM node:alpine as builder
    
    RUN apk --no-cache --virtual build-dependencies add \
        git \
        python \
        make \
        g++
    
        RUN mkdir -p /ng-app/dist
    
        WORKDIR /ng-app
    
        COPY package.json package-lock.json ./
    
        ## Storing node modules on a separate layer will prevent unnecessary npm installs at each build
        RUN npm install
    
        COPY . .
    
        ## Build the angular app in production mode and store the artifacts in dist folder
    
        RUN npm run ng build -- --prod --output-path=dist
    
    
        ### STAGE 2: Setup ###
    
        FROM nginx:1.14.1-alpine
    
        ## Copy our default nginx config
        COPY toborFront.conf /etc/nginx/conf.d/
    
        ## Remove default nginx website
        RUN rm -rf "/usr/share/nginx/html/*"
    
        ## From ‘builder’ stage copy over the artifacts in dist folder to default nginx public folder
        COPY --from=builder /ng-app/dist /usr/share/nginx/html
    
        CMD ["nginx", "-g", "daemon off;"]
    

    【讨论】:

    • 这行得通,因为我之前尝试过,但问题是我想稍后在角度服务器端渲染中部署,所以为此,我还必须执行 npm serve:ssr 然后在 Nginx 中放置一个反向代理。我该怎么做,我尝试了我放在 OP 中的示例,因为它很简单,后来尝试了服务器端渲染,所以你的答案是 100% 好的,但不是我需要的
    【解决方案3】:

    最终运行的图像是这样的:

    FROM nginx:alpine
    COPY toborFront.conf /etc/nginx/conf.d/
    EXPOSE 8080
    CMD ["npm", "serve", "--port 4000"]
    

    第一阶段没有任何效果(您可以将COPY --from=...文件从中取出),如果有多个CMDs,则只有最后一个有效果。由于您在普通的 nginx 图像中运行它,因此没有 npm 命令,导致您看到的错误。

    我建议将主机上的 Node 用于实时开发环境。当您构建并测试了您的应用程序并希望部署它时,如果合适,请使用 Docker。在你的 Dockerfile 中,在第一阶段运行 ng build 将应用程序编译为静态文件,在第二阶段添加一个 COPY --from=... 以将构建的应用程序放入 Nginx 映像中,并删除所有 CMD 行(@987654331 @ 具有适当的默认值 CMD)。 @VikramJakhar 的 answer 有一个更完整的 Dockerfile 展示了这一点。

    看起来您可能正在尝试在 Docker 中同时运行 Nginx 和 Angular 开发服务器。如果这是您的目标,您需要在两个单独的容器中运行它们。为此:

    • 将此 Dockerfile 一分为二。将 CMD ["npm", "serve"] 行放在第一个(仅限 Angular)Dockerfile 的末尾。
    • docker-compose.yml 文件中添加第二个块以运行第二个容器。后端npm serve容器不需要发布ports:
    • 将 Nginx 配置中后端服务器的主机名从 localhost 更改为另一个容器的 Docker Compose 名称。

    【讨论】:

    • 我分成了两个不同的 dockerFIles,一个是 nginx,另一个是 angular 项目。我已经退出了发布的端口,但是在 nginx 配置中我不确定我的容器的组合名称是什么,应该是:sypgod?所以,文件应该是这样的:
    • services: 下声明第二个容器的块的名称是什么?这是一个有效的主机名。
    • 是sypgod,但我也应该添加端口?
    • 是的,你需要端口(服务正在监听的容器内的端口;需要监听 0.0.0.0 “所有接口”;ports: 无效)。
    • 它没有,工作正常,我已经把它放在 nginx conf sypgod:4000 但它不起作用,sypgod 是容器的名称
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-08
    • 2020-06-25
    • 2020-06-24
    • 1970-01-01
    相关资源
    最近更新 更多