Node.js 的 Docker 容器

Node.js 是一个开源的、异步事件驱动的 JavaScript 运行时,用于运行 JavaScript 应用程序。它广泛用于传统网站和 API 服务器。同时,Docker 容器是一个独立的、可部署的单元,它将应用程序及其依赖项打包在一起,使其具有高度的可扩展性和可维护性。在本文中,我们将为 Node.js 创建一个 Docker 容器,并在该容器上运行一个简单的 express.js 应用程序。

什么是 Docker 容器?

Docker 是一个提供 Docker 运行时的开放平台。它使应用程序的开发、运行和部署变得简单易行。Docker 容器因其轻量级且高效利用底层系统资源而广受欢迎。它与虚拟机共享主机操作系统的内核,这使得 Docker 速度更快,能够同时处理多个请求。点击此处了解更多关于Docker的信息。

什么是 Node.js?

Node.js 是一个开源且免费的服务器环境。它提供 JavaScript 运行时,以便 JavaScript 应用程序可以在服务器上运行。它还允许JavaScript代码在浏览器之外运行。它还有很多其他功能,例如生成动态页面内容,在服务器上创建、保存和关闭文件,以及在后端处理数据库。

为什么要对 Node.js 使用 Docker 容器?

开发人员面临的问题之一是,应用程序的开发和部署环境可能截然不同。开发人员可能会开发自己的本地系统,而这很可能与应用程序最终部署到的云实例完全不同。

Docker 容器解决了这个问题,它使用了镜像的概念,镜像存储了 Docker 容器在特定时间的记录,就像所有库一样。运行应用程序时需要镜像及其版本。然后,开发人员可以与其他人共享此镜像,以获得与开发人员相同的环境并运行应用程序。

Docker 容器是微服务学习Docker 架构适配的最佳工具。许多公司正在转向 Docker,因为在 Docker 上运行的应用程序更易于维护、易于修改且高度可扩展。

分步 Docker 化 NodeJS 应用程序

步骤 1:Docker 化 Node.js Web 应用

让我们从一个轻松的快速应用程序开始,它在访问根端点时 打印“ Hello World!这是来自 docker 容器的 Nodejs ”。

  • 创建一个名为express_app的文件夹并使用以下命令移动到该文件夹内。
mkdir express_app   
cd express_app  

现在,创建一个名为app.js的文件,如下所示。

第 2 步:创建 Node.js 应用

创建一个包含描述您的应用程序所需的所有文件和依赖项的文件,并将其命名为package.Jason。

{
  "name": "docker-example",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "start": "nodemon app.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "nodemon": "^2.0.12"
  }
}
  • 现在,使用以下命令初始化node项目。
npm init  

这将添加 package.json 文件,其中包含有关我们项目的信息,例如脚本、依赖项和版本。它会询问包的名称、版本以及许多其他信息(您可以按 ENTER 选择默认值)。

  • npm:Node 包管理器 (Node Package Manager) 的缩写。它是 Node.js 捆绑的工具,用于管理 Node.js 的包(可在您自己的项目中使用的代码片段)。npm 可以帮助您安装、卸载、更新和管理这些包。

  • init:这是“initialize”的缩写。运行npm init,就是请求 npm 帮你设置项目的初始配置。本质上,你是在说:“我想启动一个新项目。请指导我完成设置过程。”

安装 Express 库并将其作为依赖项添加到 package.json 文件中。

npm install --save express
  • npm:Node 包管理器的缩写。它是一个帮助开发人员管理和安装 Node.js 应用程序包(类似于插件或库)的工具。

  • install:这是你给 npm 的命令。你告诉它你想安装一些东西。

  • –save:这部分表示您要将要安装的包作为依赖项保存在项目package.json文件中。该package.json文件会跟踪项目运行时所需的所有依赖项。将包保存为依赖项意味着,如果其他人想要运行您的项目,他们只需查看该package.json文件,了解所需的包,然后轻松安装它们。

  • express:这是您要安装的软件包的名称。在本例中,它是一个用于使用 Node.js 创建 Web 服务器和 Web 应用程序的常用软件包。安装时,npm 会获取所有必需的文件,并将它们放在node_modules项目目录中名为 express 的文件夹中。此文件夹包含您已安装软件包的所有代码。

安装一个名为 nodemon 的工具,当它检测到任何更改时会自动重新启动node应用程序。

npm install --save nodemon  

我们明确地将这些依赖项添加到我们的 package.json 文件中,以便在 docker 容器内运行此应用程序时下载它们。

  • 在package.json文件的 scripts 部分添加一个脚本,以便使用 nodemon 运行应用程序。文件内容如下:

步骤3:Express.js

Express 是一个 Node.js 框架,可帮助开发人员在服务器端将其 Web 应用程序组织成MVC 架构。与仅使用 Node.js 开发应用程序相比,它使 Web 应用程序的开发更加快速和简单。

例如,node.js 应用程序可能需要后端的MongoDB,而 Express 是帮助管理路由、请求和视图等一切的框架。

然后,创建一个 server.js 文件,使用 Express.js 框架定义一个 Web 应用程序:

// import and create an express app
const express = require('express');
const app = express()

// message as response
msg = "Hello world! this is nodejs in a docker container.."
// create an end point of the api
app.get('/', (req, res) => res.send(msg));

// now run the application and start listening
// on port 3000
app.listen(3000, () => {
    console.log("app running on port 3000...");
})

在此阶段,我们可以使用以下命令在本地系统上运行我们的应用程序:

npm run start

但实际上,我们想要将这个应用程序docker化。为此,我们需要创建一个镜像,并提供一些信息,例如我们需要的运行时、应用程序将使用的端口以及本地系统上可用的所需文件。

  • npm:npm 是 Node.js 捆绑的命令行工具。它用于管理 Node.js 包和依赖项,以及运行文件中定义的脚本package.json

  • run:这告诉 npm 您想要执行一个脚本。

  • start:这是要运行的脚本的名称。它是 npm 识别的特殊名称。您可以自定义它,但它"start"是运行应用程序主入口点的约定。

  • 创建一个 Dockerfile,其中包含将运行应用程序的镜像的所有信息。docker 软件可以识别这个特殊文件,并使用它构建镜像。

步骤 4: 在 Node.js 应用项目中创建 Dockerfile

首先,创建一个名为Dockerfile的文件。

FROM node:latest
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app
CMD ["npm", "start"]

Dockerfile 的解释

  1. FROM 采用基础镜像的名称,并可选择与其版本一起使用。

  2. WORKDIR 表示容器中保存应用程序文件的目录。

  3. COPY 命令将 package.json 文件复制到应用程序目录。

  4. RUN 命令运行提供的命令来安装 package.json 文件中提到的所有依赖项。

  5. 然后使用COPY将其余文件复制到容器中的app目录。

  6. 最后,我们提供运行应用程序的脚本。

  • 创建所有需要的文件后的文件夹结构如下:

最终的文件夹结构

  • 最后,使用此命令构建我们将在 docker 容器中运行的映像。

步骤5:构建您的镜像

创建 Dockerfile 后,使用以下命令通过帮助 Dockerfile 构建映像。

docker build -t docker-container-nodejs .
  • docker build:这是用于构建 Docker 镜像的命令。它告诉 Docker 根据 Dockerfile 中提供的指令构建镜像。

  • -t docker-container-nodejs:-t标志是“tag”的缩写,用于为正在构建的镜像指定名称以及可选的标签。在本例中,我们将镜像命名为“docker-container-nodejs”。名称通常采用以下格式<repository>/<image_name>: ,其中docker-container-nodejs是镜像名称。

  • .:命令末尾的点表示构建上下文。它指示 Docker 在当前目录中查找 Dockerfile 以及其他必要的文件。Docker 会在构建上下文中查找 Dockerfile 中引用的文件,例如源代码、依赖项和配置文件。.

该命令使用 -t 参数指定镜像名称,然后我们需要指定镜像的地址。接下来,我们需要将 Dockerfile 放置到该目录中;由于我们在运行命令时处于该目录中,因此可以使用句点,它代表当前目录。

  • 确认镜像已创建。
docker images

输出将是系统中的镜像列表。它应该包含我们最近创建的镜像,其名称是我们通过 -t 标志指定的。

  • 要使用此映像运行 docker 容器,请使用以下命令。

步骤 6:运行镜像

将镜像作为容器运行,并以容器的形式部署应用程序。

docker run -d -p 8000:3000 -v address_to_app_locally:/app docker-container-nodejs

上述命令运行一个 docker 容器。-p 参数用于将本地端口 8000 映射到容器的 3000 端口(应用程序正在该端口上运行)。-v 参数用于将应用程序文件挂载到容器的 app 目录中。此外,还需要指定要在容器中运行的镜像名称,在本例中为 docker-container-nodejs。

  • `docker run`:此命令用于从镜像创建并启动新的 Docker 容器。

  • `-d`:此标志代表“分离模式”。它在后台运行容器,因此您的终端可以自由地执行其他命令。

  • `-p 8000:3000`:此选项将主机上的端口映射到 Docker 容器内的端口。

    • `8000`:主机(即您的计算机)上的端口。

    • `3000`:Node.js 应用程序运行的 Docker 容器内的端口。

    • 这意味着当您http://localhost:8000在主机上访问时,它将被转发到http://localhost:3000容器内部。

  • `-v address_to_app_locally:/app`:此标志安装一个卷,将主机上的目录链接到容器内的目录。

    • `address_to_app_locally`:主机上应用程序目录的路径。

    • `/app`:Docker 容器内应用程序可用的目录。

    • 这使您可以在本地开发应用程序并查看容器内部的变化,而无需重建它。

  • `docker-container-nodejs`:这是创建容器的 Docker 镜像的名称。请确保在运行该命令之前已构建或拉取此镜像。

步骤 7:测试应用程序

访问此地址localhost :8000,我们的 express 应用程序将返回以下响应。

在 Docker 容器上快速运行应用程序

使用 Docker Compose 运行 node

version: '3.8'

services:
  app:
    build: .
    ports:
      - "8000:3000"
    volumes:
      - .:/app
    command: npm start
  • `version: ‘3.8’`:指定 Docker Compose 文件格式的版本。3.8 版本是常用的版本,支持最新功能。

  • `services`:定义组成应用程序的服务。这里我们有一个名为 的服务app

  • `app`:服务名称。此服务代表您的 Node.js 应用程序。

  • `build: .`:指示Docker Compose从位于当前目录 ( ) 中的 Dockerfile 构建映像.

  • `ports`:映射主机和 Docker 容器之间的端口。

    • `“8000:3000”`:将主机上的 8000 端口映射到 Docker 容器内的 3000 端口。当您http://localhost:8000在主机上访问时,它会将请求转发到运行 Node.js 应用的容器中的 3000 端口。
  • `volumes`:将主机中的目录挂载到 Docker 容器中。

    • `. : /app`:将主机上的当前目录 ( .) 挂载到/app容器内的目录。这样您就可以在主机上编辑代码,并且更改将反映在容器内。
  • `command`:指定在容器内运行的命令。

    • `npm start`:运行npm start,通常会启动您的 Node.js 应用程序。

Docker node最佳实践

  • 使用官方node镜像:从轻量级基础镜像开始,例如较小的镜像尺寸。node:alpine

  • 利用多阶段构建:使用多阶段构建,通过仅包含必要的文件来减少最终镜像大小。

  • 缓存依赖项:在复制其他文件之前首先复制package.jsonpackage-lock.json运行,npm install以利用Docker 的层缓存。

  • 设置工作目录:用于WORKDIR设置容器内的工作目录。

  • 用途:创建一个文件以从构建上下文中排除不必要的文件和目录。`.dockerignore` .dockerignore

  • 以非 root 用户身份运行:在 Dockerfile 中添加非 root 用户并切换到该用户以获得更好的安全性。

  • 优化CMD:用于CMD ["node", "your-app.js"]定义容器的默认命令。

结论

在本文中,我们了解了 Docker 容器、镜像及其优势。然后,我们学习了如何创建可在 Docker 容器上运行的镜像。最后,我们创建了一个小型 Express 应用程序,演示了如何使用在 Docker 容器中运行的 Node.js 应用程序。

Leave a Comment