建立您的Node映像

预计阅读时间:12分钟

先决条件

通过入门第1部分中的方向和设置来理解Docker概念。

概述

现在,我们对容器和Docker平台有了一个很好的了解,让我们看一下构建我们的第一个映像。映像包括运行应用程序所需的一切-代码或二进制文件,运行时,依赖项以及所需的任何其他文件系统对象。

要完成本教程,您需要以下内容:

  • Node.js版本12.18或更高版本。下载Node.js
  • 在本地运行的Docker:按照说明下载并安装Docker
  • IDE或文本编辑器来编辑文件。我们建议使用Visual Studio Code。

样品申请

让我们创建一个简单的Node.js应用程序,以作为示例。在本地计算机上创建一个名为的目录,node-docker然后按照以下步骤创建一个简单的REST API。

$ cd [path to your node-docker directory]
$ npm init -y
$ npm install ronin-server ronin-mocks
$ touch server.js

现在,让我们添加一些代码来处理我们的REST请求。我们将使用模拟服务器,以便我们专注于对应用程序进行Docker化。

在IDE中打开此工作目录,然后将以下代码添加到server.js文件中。

const ronin     = require( 'ronin-server' )
const mocks     = require( 'ronin-mocks' )

const server = ronin.server()

server.use( '/', mocks.server( server.Router(), false, true ) )
server.start()

模拟服务器将被调用,Ronin.js并且默认情况下将在端口8000上进行侦听。您可以向根(/)端点发出POST请求,并且发送到服务器的所有JSON结构都将保存在内存中。您还可以将GET请求发送到同一端点,并接收先前已过帐的JSON对象数组。

测试应用程序

让我们启动我们的应用程序,并确保它运行正常。打开终端,然后导航到您创建的工作目录。

$ node server.js

为了测试应用程序是否正常运行,我们首先将一些JSON发布到API,然后发出GET请求以查看数据是否已保存。打开一个新终端并运行以下curl命令:

$ curl --request POST \
  --url http://localhost:8000/test \
  --header 'content-type: application/json' \
  --data '{"msg": "testing" }'
{"code":"success","payload":[{"msg":"testing","id":"31f23305-f5d0-4b4f-a16f-6f4c8ec93cf1","createDate":"2020-08-28T21:53:07.157Z"}]}

$ curl http://localhost:8000/test
{"code":"success","meta":{"total":1,"count":1},"payload":[{"msg":"testing","id":"31f23305-f5d0-4b4f-a16f-6f4c8ec93cf1","createDate":"2020-08-28T21:53:07.157Z"}]}

切换回运行我们的服务器的终端。现在,您应该在服务器日志中看到以下请求。

2020-XX-31T16:35:08:4260  INFO: POST /test
2020-XX-31T16:35:21:3560  INFO: GET /test

为Node.js创建一个Dockerfile

Dockerfile是一个文本文档,其中包含用户可以在命令行上调用以组装映像的所有命令。当我们告诉Docker通过执行docker build命令来构建映像时,Docker读取这些指令并逐个执行它们,并创建一个Docker映像。

让我们逐步为应用程序创建一个Dockerfile的过程。在工作目录的根目录中,创建一个名为的Dockerfile文件,然后在文本编辑器中打开该文件。

笔记

Dockerfile的名称并不重要,但是许多命令的默认文件名只是Dockerfile。因此,在本系列中,我们将其用作文件名。

添加到Dockerfile的第一行是# syntax解析器指令。虽然可选的,这个指令指示泊坞建设者解析Dockerfile当什么语法使用,并允许旧的码头工人版本的BuildKit启用开始构建之前升级解析器。解析器指令 必须出现在Dockerfile中的任何其他注释,空格或Dockerfile指令之前,应该是Dockerfiles中的第一行。

# syntax=docker/dockerfile:1

我们建议您使用docker/dockerfile:1,它始终指向版本1语法的最新版本。BuildKit会在构建之前自动检查语法更新,以确保您使用的是最新版本。

接下来,我们需要在Dockerfile中添加一行,以告诉Docker我们想要为应用程序使用什么基本映像。

# syntax=docker/dockerfile:1

FROM node:12.18.1

Docker映像可以从其他映像继承。因此,我们将使用正式的Node.js映像,而不是创建自己的基本映像,该映像已经具有运行Node.js应用程序所需的所有工具和软件包。您可以以与考虑面向对象编程中的类继承相同的方式来考虑这一点。例如,如果我们能够用JavaScript创建Docker映像,则可以编写类似以下内容的代码。

class MyImage extends NodeBaseImage {}

这将创建一个名为的类MyImage,该类从基类继承功能NodeBaseImage

同样,当使用FROM命令时,我们告诉Docker将映像中的所有功能都包含在node:12.18.1映像中。

笔记

如果您想了解有关创建自己的基本图像的更多信息,请参阅创建基本图像

NODE_ENV环境变量指定在其中的应用程序运行的环境(通常,开发或生产)。要提高性能,最简单的操作之一就是将设置NODE_ENVproduction

ENV NODE_ENV=production

为了使运行其余命令更容易,让我们创建一个工作目录。这指示Docker使用此路径作为所有后续命令的默认位置。这样,我们不必键入完整的文件路径,但可以根据工作目录使用相对路径。

WORKDIR /app

通常,下载完用Node.js编写的项目后,要做的第一件事就是安装npm软件包。这样可以确保您的应用程序将其所有依赖项安装到node_modulesNode运行时可以在其中找到它们的目录中。

在运行之前npm install,我们需要将package.jsonpackage-lock.json文件放入映像中。我们使用COPY命令来执行此操作。该 COPY命令有两个参数。第一个参数告诉Docker您要将哪些文件复制到映像中。第二个参数告诉Docker您要将文件复制到哪里。我们将把package.jsonpackage-lock.json文件复制到我们的工作目录中/app

COPY ["package.json", "package-lock.json*", "./"]

一旦将package.json文件包含在映像中,就可以使用该RUN命令执行命令npm install。它的工作原理与我们在计算机上本地运行npm install时完全相同,但是这次这些Node模块将安装到node_modules映像内的目录中。

RUN npm install --production

至此,我们有了一个基于节点版本12.18.1的映像,并且已经安装了依赖项。我们需要做的下一件事是将源代码添加到图像中。就像package.json上面的文件一样,我们将使用COPY命令。

COPY . .

COPY命令获取位于当前目录中的所有文件,并将它们复制到映像中。现在,我们要做的就是告诉Docker当我们的镜像在容器内部运行时,我们想运行什么命令。我们使用CMD命令执行此操作。

CMD [ "node", "server.js" ]

这是完整的Dockerfile。

# syntax=docker/dockerfile:1

FROM node:12.18.1
ENV NODE_ENV=production

WORKDIR /app

COPY ["package.json", "package-lock.json*", "./"]

RUN npm install --production

COPY . .

CMD [ "node", "server.js" ]

创建一个.dockerignore文件

要在构建上下文中使用文件,Dockerfile引用指令(例如COPY指令)中指定的文件。为了提高构建的性能,可以通过在上下文目录中添加.dockerignore文件来排除文件和目录。为了缩短上下文加载时间,请创建一个.dockerignore文件并node_modules在其中添加目录。

node_modules

建立影像

现在我们已经创建了Dockerfile,让我们构建映像。为此,我们使用docker build命令。该docker build命令从Dockerfile和“上下文”构建Docker映像。构建的上下文是位于指定PATH或URL中的文件集。Docker构建过程可以访问上下文中的任何文件。

构建命令可以选择带有--tag标志。标签用于设置图像名称和格式的可选标签‘name:tag’。现在,我们将省略可选的“标签”以帮助简化操作。如果您不传递标签,则Docker将使用“最新”作为其默认标签。您将在构建输出的最后一行中看到这一点。

让我们构建我们的第一个Docker映像。

$ docker build --tag node-docker .
Sending build context to Docker daemon  82.94kB
Step 1/7 : FROM node:12.18.1
---> f5be1883c8e0
Step 2/7 : WORKDIR /code
...
Successfully built e03018e56163
Successfully tagged node-docker:latest

查看本地图像

要查看本地计算机上的图像列表,我们有两个选择。一种是使用CLI,另一种是使用Docker Desktop。由于我们当前正在终端中工作,因此让我们看一下使用CLI列出图像。

要列出图像,只需运行images命令。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
node-docker         latest              3809733582bc        About a minute ago   945MB
node                12.18.1             f5be1883c8e0        2 months ago         918MB

您应该至少看到列出的两个图像。一个用于基础图像node:12.18.1,另一个用于我们刚刚构建的图像node-docker:latest

标记图片

图像名称由斜杠分隔的名称组成。名称部分可能包含小写字母,数字和分隔符。分隔符定义为一个句点,一个或两个下划线或一个或多个破折号。名称组件不能以分隔符开头或结尾。

图像由清单和图层列表组成。简而言之,“标签”指向这些工件的组合。一个图像可以有多个标签。让我们为构建的图像创建第二个标签,并查看其图层。

要为我们上面构建的图像创建一个新标签,请运行以下命令。

$ docker tag node-docker:latest node-docker:v1.0.0

Docker tag命令为图像创建一个新标签。它不会创建新图像。标签指向相同的图像,并且是引用图像的另一种方法。

现在,运行docker images命令以查看我们的本地图像列表。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
node-docker         latest              3809733582bc        24 minutes ago      945MB
node-docker         v1.0.0              3809733582bc        24 minutes ago      945MB
node                12.18.1             f5be1883c8e0        2 months ago        918MB

您会看到我们有两个以开头的图像node-docker。我们知道它们是同一张图像,因为如果您查看“图像ID”列,则可以看到两个图像的值相同。

让我们删除刚刚创建的标签。为此,我们将使用rmi命令。rmi命令代表“删除图像”。

$ docker rmi node-docker:v1.0.0
Untagged: node-docker:v1.0.0

请注意,Docker的响应告诉我们,该映像尚未删除,只是“未标记”。通过运行images命令来验证这一点。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
node-docker         latest              3809733582bc        32 minutes ago      945MB
node                12.18.1             f5be1883c8e0        2 months ago        918MB

带有标记的图像:v1.0.0已被删除,但我们node-docker:latest的机器上仍具有可用的标记。

下一步

在本模块中,我们看了如何设置示例Node应用程序,并将在本教程的其余部分中使用该应用程序。我们还创建了一个Dockerfile,用于构建Docker映像。然后,我们看了一下标记图像和删除图像的过程。在下一个模块中,我们将研究如何:

将图像作为容器运行

反馈

通过提供您的反馈帮助我们改善此主题。通过在Docker Docs GitHub存储库中创建问题,让我们知道您的想法。或者,创建PR以建议更新。


容器图像node.js节点dockerfiles节点编码构建推送运行