我是码头工人并且很喜欢玩它.我想在docker容器中运行nodejs app.我把ubuntu:14.04作为基本图像并构建我自己的nodeJS烘焙图像.我的Dockerfile内容如下所示
FROM ubuntu:14.04
MAINTAINER nmrony
#install packages, nodejs and npm
RUN apt-get -y update && \
apt-get -y install build-essential && \
curl -sL https://deb.nodesource.com/setup | bash - && \
apt-get install -y nodejs
#Copy the sources to Container
COPY ./src /src
CMD ["cd /src"]
CMD ["npm install"]
CMD ["nodejs", "/src/server.js"]
Run Code Online (Sandbox Code Playgroud)
我使用以下命令运行容器
docker run -p 8080:8080 -d --name nodejs_expreriments nmrony/exp-nodejs
Run Code Online (Sandbox Code Playgroud)
它运行正常.但是当我尝试浏览时http:localhost:8080它不会运行.当我跑docker logs nodejs_expreriments,我得到以下错误
Error: Cannot find module 'express'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/src/server.js:1:77)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
Run Code Online (Sandbox Code Playgroud)
我用交互式shell运行另一个容器,发现没有安装npm.有人可以帮助我为什么NPM没有安装在容器上?难道我做错了什么?
Mic*_*lot 11
您的根本问题是您只能在Docker文件中拥有一个 CMD.每个RUN/ COPY命令在此期间构建一个图层docker build,因此您可以根据需要添加任意数量的图层.但是,在一个期间,只有一个 CMD被执行docker run.由于你有三个CMD语句,实际上只有一个语句被执行(大概是最后一个).
(IMO,如果Dockerfile队会选择这个词BUILD来代替RUN和RUN代替的CMD,所以docker build就BUILD陈述和docker run不运行的语句,这可能是对新用户减少混乱.哦,好.)
您要么将前两个CMDs 转换为RUNs(如果您希望它们docker build在图像中发生并被烘焙到图像中),要么将所有三个CMDs转换为您运行的脚本.这里有一些解决方案:
(1)最简单的变化可能是使用WORKDIR,而不是cd使您的npm install一个RUN命令.如果您希望能够npm install在构建期间使服务器在运行时快速启动,则您需要执行以下操作:
#Copy the sources to Container
COPY ./src /src
WORKDIR /src
RUN npm install
CMD nodejs server.js
Run Code Online (Sandbox Code Playgroud)
(2)如果你正在积极开发,你可能想要考虑如下:
#Copy the sources to Container
WORKDIR /src
COPY ./src/package.json /src/package.json
RUN npm install
COPY /src /src
CMD nodejs server.js
Run Code Online (Sandbox Code Playgroud)
因此,如果package.json发生更改,您只需要执行npm安装.否则,每当图像中的任何内容发生变化时,您都会重建所有内容.
(3)如果你经常更改包文件并且不想一直打扰构建和运行,那么另一个选项是有用的,那就是将源保留在卷上的图像之外,这样你就可以运行了没有重建:
...
WORKDIR /src
VOLUME /src
CMD build_and_serve.sh
Run Code Online (Sandbox Code Playgroud)
其中的内容build_and_serve.sh是:
#!/bin/bash
npm install && nodejs server.js
Run Code Online (Sandbox Code Playgroud)
你运行它像:
docker run -v /path/to/your/src:/src -p 8080:8080 -d --name nodejs_expreriments nmrony/exp-nodejs
Run Code Online (Sandbox Code Playgroud)
当然,最后一个选项不会为您提供便携式docker镜像,您可以将某人与您的服务器一起提供给您,因为您的代码位于图像之外的卷上.
很多选择!
对我来说,这工作:
RUN apt-get update \
&& apt-get upgrade -y \
&& curl -sL https://deb.nodesource.com/setup_8.x | bash - \
&& apt-get install -y nodejs \
&& npm install -g react-tools
Run Code Online (Sandbox Code Playgroud)
我的debian映像apt-get的npm版本破旧,因此通过下载路径进行了修复。