如果我在 dockerfile 中写 运行 node index.js 而不是 CMD node index.js 会发生什么?
What happens if I write RUN node index.js instead of CMD node index.js in a dockerfile?
我用 docker 文件
创建了一个简单的 hello world node.js 应用程序
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD node index.js
如果我在 docker 文件中将 CMD 更改为 运行,它仍然有效。
docker 文件中记录了使用 CMD,因为它将在容器的 运行 上启动节点服务器。
我想知道如果我使用 运行 cmd 而不是 CMD 会发生什么。
如果我制作一个本身处于 运行 状态的 docker 图像,基本上会发生什么。
RUN
将在构建过程中执行命令。 CMD
在 执行 容器时用作默认命令,而不是构建。如果您在 RUN
指令中 运行 node index.js
,您的构建将永远无法完成,并且您没有容器可与他人共享。
有关详细信息,请参阅 docker 文件文档:RUN
and CMD
。
该文档中的相关位:
The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
The main purpose of a CMD is to provide defaults for an executing container.
编辑:使用 OP 的 index.json
、package.json
和 Dockerfile
文件,docker 映像构建未完成使用 RUN node index.js
时并在使用 CMD node index.js
.
时完成(如预期)
index.js
的内容:
//Load express module with `require` directive
var express = require('express')
var app = express()
//Define request response in root URL (/)
app.get('/', function (req, res) {
res.send('Hello World!')
})
//Launch listening server on port 8081
app.listen(8080, function () {
console.log('app listening on port 8080!')
})
package.json
的内容:
{
"name": "dummy_nodejs_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "Debojit",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
使用Dockerfile
时如下:
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
RUN node index.js
然后构建挂起。这是输出:
jakub@dash:/tmp/test-node$ docker build -t test .
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM node:10
---> d5680e53a228
Step 2/7 : WORKDIR /usr/src/app
---> Using cache
---> a4b4547833e5
Step 3/7 : COPY package*.json ./
---> Using cache
---> 2b19cc3e48a3
Step 4/7 : RUN npm install
---> Using cache
---> fe1f1e72d17d
Step 5/7 : COPY . .
---> eb6fe0e3d1a7
Step 6/7 : EXPOSE 8080
---> Running in e573b923fcb2
Removing intermediate container e573b923fcb2
---> b3590153eed7
Step 7/7 : RUN node index.js
---> Running in 08b408e6e6f3
app listening on port 8080!
这将无限期挂起。
使用 Dockerfile 时
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD node index.js
构建输出是:
jakub@dash:/tmp/test-node$ docker build -t test .
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM node:10
---> d5680e53a228
Step 2/7 : WORKDIR /usr/src/app
---> Using cache
---> a4b4547833e5
Step 3/7 : COPY package*.json ./
---> Using cache
---> 2b19cc3e48a3
Step 4/7 : RUN npm install
---> Using cache
---> fe1f1e72d17d
Step 5/7 : COPY . .
---> Using cache
---> fc036f428e34
Step 6/7 : EXPOSE 8080
---> Using cache
---> d1ede7276d34
Step 7/7 : CMD node index.js
---> Using cache
---> cf051929395b
Successfully built cf051929395b
Successfully tagged test:latest
首先,如果您在构建阶段使用 RUN
命令启动任何长 运行 进程,您的构建过程将被卡住。
RUN
命令在构建时执行,这是为构建时配置和安装包和工具而设计的,使用 RUN
命令准备你的 Docker 图像,例如安装 npm 模块和一些其他应用程序依赖项,当进程在容器中启动时这些依赖项将可用。
CMD
在你启动容器时执行,它不会在构建时执行,CMD
应该是一个很长的-运行进程来保持你的容器。
RUN
步骤使用提供的命令执行一个临时容器,等待该命令退出,然后捕获对容器文件系统的更改作为生成图像的另一层。它不存储 运行ning 进程、对环境变量的更改或对 shell 状态的任何更改,因为这些不会写入文件系统。它也不捕获对卷的更改,因为临时容器是使用映像中定义的卷启动的,并且对卷的更改不会应用到容器文件系统。这是构建时间步长。
当图像运行作为容器时,CMD
步骤替换了现有的默认命令docker 运行s。只要此命令为 运行ning,容器就会存在,并且该命令只能有一个值。如果您第二次定义 CMD
,则先前的值将被替换。如果您使用覆盖的命令启动容器,CMD
的图像值将被忽略。
因此,您希望将在镜像构建时修改文件系统的步骤与容器为 运行 时执行的步骤分开,分别为 RUN
和 CMD
。
我用 docker 文件
创建了一个简单的 hello world node.js 应用程序FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD node index.js
如果我在 docker 文件中将 CMD 更改为 运行,它仍然有效。 docker 文件中记录了使用 CMD,因为它将在容器的 运行 上启动节点服务器。
我想知道如果我使用 运行 cmd 而不是 CMD 会发生什么。 如果我制作一个本身处于 运行 状态的 docker 图像,基本上会发生什么。
RUN
将在构建过程中执行命令。 CMD
在 执行 容器时用作默认命令,而不是构建。如果您在 RUN
指令中 运行 node index.js
,您的构建将永远无法完成,并且您没有容器可与他人共享。
有关详细信息,请参阅 docker 文件文档:RUN
and CMD
。
该文档中的相关位:
The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
The main purpose of a CMD is to provide defaults for an executing container.
编辑:使用 OP 的 index.json
、package.json
和 Dockerfile
文件,docker 映像构建未完成使用 RUN node index.js
时并在使用 CMD node index.js
.
index.js
的内容:
//Load express module with `require` directive
var express = require('express')
var app = express()
//Define request response in root URL (/)
app.get('/', function (req, res) {
res.send('Hello World!')
})
//Launch listening server on port 8081
app.listen(8080, function () {
console.log('app listening on port 8080!')
})
package.json
的内容:
{
"name": "dummy_nodejs_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "Debojit",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
使用Dockerfile
时如下:
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
RUN node index.js
然后构建挂起。这是输出:
jakub@dash:/tmp/test-node$ docker build -t test .
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM node:10
---> d5680e53a228
Step 2/7 : WORKDIR /usr/src/app
---> Using cache
---> a4b4547833e5
Step 3/7 : COPY package*.json ./
---> Using cache
---> 2b19cc3e48a3
Step 4/7 : RUN npm install
---> Using cache
---> fe1f1e72d17d
Step 5/7 : COPY . .
---> eb6fe0e3d1a7
Step 6/7 : EXPOSE 8080
---> Running in e573b923fcb2
Removing intermediate container e573b923fcb2
---> b3590153eed7
Step 7/7 : RUN node index.js
---> Running in 08b408e6e6f3
app listening on port 8080!
这将无限期挂起。
使用 Dockerfile 时
FROM node:10
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD node index.js
构建输出是:
jakub@dash:/tmp/test-node$ docker build -t test .
Sending build context to Docker daemon 4.096kB
Step 1/7 : FROM node:10
---> d5680e53a228
Step 2/7 : WORKDIR /usr/src/app
---> Using cache
---> a4b4547833e5
Step 3/7 : COPY package*.json ./
---> Using cache
---> 2b19cc3e48a3
Step 4/7 : RUN npm install
---> Using cache
---> fe1f1e72d17d
Step 5/7 : COPY . .
---> Using cache
---> fc036f428e34
Step 6/7 : EXPOSE 8080
---> Using cache
---> d1ede7276d34
Step 7/7 : CMD node index.js
---> Using cache
---> cf051929395b
Successfully built cf051929395b
Successfully tagged test:latest
首先,如果您在构建阶段使用 RUN
命令启动任何长 运行 进程,您的构建过程将被卡住。
RUN
命令在构建时执行,这是为构建时配置和安装包和工具而设计的,使用 RUN
命令准备你的 Docker 图像,例如安装 npm 模块和一些其他应用程序依赖项,当进程在容器中启动时这些依赖项将可用。
CMD
在你启动容器时执行,它不会在构建时执行,CMD
应该是一个很长的-运行进程来保持你的容器。
RUN
步骤使用提供的命令执行一个临时容器,等待该命令退出,然后捕获对容器文件系统的更改作为生成图像的另一层。它不存储 运行ning 进程、对环境变量的更改或对 shell 状态的任何更改,因为这些不会写入文件系统。它也不捕获对卷的更改,因为临时容器是使用映像中定义的卷启动的,并且对卷的更改不会应用到容器文件系统。这是构建时间步长。
当图像运行作为容器时,CMD
步骤替换了现有的默认命令docker 运行s。只要此命令为 运行ning,容器就会存在,并且该命令只能有一个值。如果您第二次定义 CMD
,则先前的值将被替换。如果您使用覆盖的命令启动容器,CMD
的图像值将被忽略。
因此,您希望将在镜像构建时修改文件系统的步骤与容器为 运行 时执行的步骤分开,分别为 RUN
和 CMD
。