如何将Node.js与Docker结合使用

更新日期: 2023-11-28阅读: 528标签: Docker
教程介绍了在 Docker 容器中运行 Node.js 应用程序的好处以及如何创建实用的开发工作流程。

Node.js允许您在服务器和客户端上使用 JavaScript 创建快速且可扩展的 Web 应用程序。您的应用程序可能在您的开发计算机上完美运行,但您能确定它可以在您同事的设备或生产服务器上运行吗?

考虑以下场景:

  • 当其他人使用 Windows 而服务器运行 Linux 时,您可能使用 macOS。
  • 您安装了 Node.js 20,但其他人使用一系列运行时版本。
  • 您正在使用数据库等依赖项,这些依赖项存在差异,或者可能在其他平台上不可用。
  • 您确定您的新代码不会在另一个操作系统 (OS) 上执行任何危险操作吗?

Docker Delivers

Docker有助于解决上面列出的“但它可以在我的机器上运行”问题。您无需在本地安装应用程序,而是在称为容器的轻量级隔离虚拟机环境中运行

真正的虚拟机模拟 PC 硬件,因此您可以安装操作系统。Docker 模拟操作系统,以便您可以安装应用程序。通常为每个基于 Linux 的容器安装一个应用程序,并通过虚拟网络连接它们,以便它们可以在 HTTP 端口上进行通信。

优点:

  • 您的 Docker 设置可以模拟生产 Linux 服务器,也可以使用容器进行部署。
  • 您可以在几分钟内下载、安装和配置依赖项。
  • 您的容器化应用程序在所有设备上都以相同的方式运行。
  • 这样更安全。您的应用程序可能会破坏容器的操作系统,但它不会影响您的电脑,您可以在几秒钟内重新启动。

使用 Docker,无需在 PC 上安装 Node.js 或使用运行时管理选项(例如nvm )。


你的第一个脚本

在Windows、macOS或Linux上安装 Docker Desktop ,然后创建一个version.js使用以下代码命名的小脚本:

console.log(`Node.js version: ${ process.version }`);

如果您本地安装了 Node.js,请尝试运行该脚本。

$ node version.js
Node.js version: v18.18.2

您现在可以在 Docker 容器内运行相同的脚本。以下命令使用 Node.js 的最新长期支持 (LTS) 版本。cd进入脚本目录并在 macOS 或 Linux 上运行它:

$ docker run --rm --name version \
  -v $PWD:/home/node/app \
  -w /home/node/app \
  node:lts-alpine version.js

Node.js version: v20.9.0

{}Windows Powershell 用户可以使用类似的带括号的命令PWD:

> docker run --rm --name version -v ${PWD}:/home/node/app -w /home/node/app node:lts-alpine version.js

Node.js version: v20.9.0

第一次运行可能需要一两分钟才能执行,因为 Docker 下载依赖项。随后的运行是瞬时的。

让我们尝试不同版本的 Node — 例如最新版本的版本 21。在 macOS 或 Linux 上:

$ docker run --rm --name version \
  -v $PWD:/home/node/app \
  -w /home/node/app \
  node:21-alpine version.js

Node.js version: v21.1.0

在 Windows Powershell 上:

> docker run --rm --name version -v ${PWD}:/home/node/app -w /home/node/app node:21-alpine version.js

Node.js version: v21.1.0

请记住,该脚本在安装了特定版本的 Node.js 的 Linux 容器内运行。

参数解释

出于好奇,命令参数是:

  • docker run从图像启动一个新容器- 下面详细介绍。

  • --rm终止时删除容器。除非您有充分的理由再次重新启动容器,否则没有必要保留容器。

  • --name version为容器指定一个名称,以便于管理。

  • -v $PWD:/home/node/app(或-v ${PWD}:/home/node/app)bind 安装卷。在这种情况下,主机 PC 上的电流直接安装在位于 的容器内/home/node/app。

  • -w /home/node/app设置 Node.js 工作目录。

  • node:lts-alpine是图像——在本例中,是在 Alpine Linux 中运行的 Node.js 的 LTS 版本。该映像包含运行应用程序所需的操作系统和文件。将其视为磁盘快照。您可以从同一个映像启动任意数量的容器:它们都引用同一组文件,因此每个容器需要最少的资源。

  • version.js是要执行的命令(从工作目录内部)。

Docker 镜像可从Docker Hub获取,并且可用于包括Node.js在内的应用程序和运行时。图像通常有多个版本,并用诸如:lts-alpine、20-bullseye-slim或 等标签标识latest。

请注意,Alpine是一个小型 Linux 发行版,基本映像大小约为 5MB。它不包含很多库,但对于简单的项目(例如本教程中的项目)来说已经足够了。


运行复杂的应用程序

上面的脚本version.js很简单,不包含依赖项或构建步骤。大多数 Node.js 应用程序用于在目录npm中安装和管理模块node_modules。您不能使用上面的命令,因为:

  • 您无法npm在主机 PC 上运行(您可能没有安装 Node.js 或正确的版本)。
  • 某些模块需要特定于平台的二进制文件。您无法在主机 PC 上安装 Windows 二进制文件并期望它在 Linux 容器中运行。

解决方案是创建您自己的 Docker 映像,其中包含:

  • Node.js 运行时的适当版本
  • 包含所有必需模块的应用程序的已安装版本

以下演示使用Express.js框架构建一个简单的 Node.js 应用程序。创建一个名为的新目录simple并添加一个package.json包含以下内容的文件:

{
  "name": "simple",
  "version": "1.0.0",
  "description": "simple Node.js and Docker example",
  "type": "module",
  "main": "index.js",
  "scripts": {
    "debug": "node --watch --inspect=0.0.0.0:9229 index.js",
    "start": "node index.js"
  },
  "license": "MIT",
  "dependencies": {
    "express": "^4.18.2"
  }
}

添加index.js包含 JavaScript 代码的文件:

// Express application
import express from 'express';

// configuration
const cfg = {
  port: process.env.PORT || 3000
};

// initialize Express
const app = express();

// home page route
app.get('/:name?', (req, res) => {
  res.send(`Hello ${ req.params.name || 'World' }!`);
});

// start server
app.listen(cfg.port, () => {
  console.log(`server listening at http://localhost:${ cfg.port }`);
});

不要尝试在主机 PC 上安装依赖项或运行此应用程序!

创建一个名为Dockerfile以下内容的文件:

# base Node.js LTS image
FROM node:lts-alpine

# define environment variables
ENV HOME=/home/node/app
ENV NODE_ENV=production
ENV NODE_PORT=3000

# create application folder and assign rights to the node user
RUN mkdir -p $HOME && chown -R node:node $HOME

# set the working directory
WORKDIR $HOME

# set the active user
USER node

# copy package.json from the host
COPY --chown=node:node package.json $HOME/

# install application modules
RUN npm install && npm cache clean --force

# copy remaining files
COPY --chown=node:node . .

# expose port on the host
EXPOSE $NODE_PORT

# application launch command
CMD [ "node", "./index.js" ]

这定义了安装和执行应用程序所需的步骤。请注意,package.json将复制到映像,然后在复制其余文件之前npm install运行。这比一次复制所有文件更有效,因为 Docker 在每个命令中都会创建一个镜像。如果你的应用程序文件()发生变化,Docker只需要运行最后三个步骤;不需要再这样做了。index.jsnpm install

您也可以选择添加.dockerignore文件。它类似于.gitignore并阻止将不必要的文件复制到映像中COPY 。例如:

Dockerfile

.git
.gitignore

.vscode
node_modules
README.md

simple通过输入以下命令构建一个 Docker 映像(请注意.末尾的句点 - 表示您正在使用当前目录中的文件)

$ docker image build -t simple .

node:lts-alpine如果上面使用的 Docker 镜像尚未从您的系统中删除,该镜像应该会在几秒钟内构建完成。

假设构建成功,从您的映像启动一个容器:

$ docker run -it --rm --name simple -p 3000:3000 simple

server listening at http://localhost:3000

-p 3000:3000 将主机 PC 上的端口 3000 发布或公开<host-port>到<container-port>容器内的端口 3000。

打开浏览器并输入 URLhttp://localhost:3000/以查看“Hello World!”

尝试在 URL 中添加名称 - 例如http://localhost:3000/Craig- 以查看替代消息。

最后,通过单击 Docker Desktop容器选项卡中的停止图标来停止应用程序运行,或者在另一个终端窗口中输入以下命令:

docker container stop simple


更好的 Docker 开发工作流程

上述过程有一些令人沮丧的缺陷:

  • 对代码(在index.js)中的任何更改都需要您停止容器、重建映像、重新启动容器并重新测试。

  • 您无法附加 Node.js 调试器,例如VS Code中提供的调试器。

Docker 可以通过保留现有的生产级映像来改进您的开发工作流程,但运行具有覆盖的容器以执行以下操作:

  • 设置环境变量,例如NODE_ENVto development。

  • 将本地目录挂载到容器中。

  • 使用 启动应用程序npm run debug。它会运行node --watch --inspect=0.0.0.0:9229 index.js,当文件更改时重新启动应用程序(Node.js 18 中的新增功能),并使用容器外部允许的请求启动调试器。

  • 向主机公开应用程序端口 3000 和调试器端口 9229。

您可以使用一个长docker run命令来完成此操作,但我更喜欢使用Docker Compose。它与 Docker Desktop 一起安装,通常用于启动多个容器。创建一个新文件,命名docker-compse.yml为以下内容:

version: '3'

services:

  simple:
    environment:
      - NODE_ENV=development
    build:
      context: ./
      dockerfile: Dockerfile
    container_name: simple
    volumes:
      - ./:/home/node/app
    ports:
      - "3000:3000"
      - "9229:9229"
    command: /bin/sh -c 'npm install && npm run debug'

使用以下命令启动在调试模式下运行的应用程序:

$ docker compose up

[+] Building 0.0s
[+] Running 2/2
 ✔ Network simple_default  Created
 ✔ Container simple        Created
Attaching to simple
simple  |
simple  | up to date, audited 63 packages in 481ms
simple  |
simple  | > simple@1.0.0 debug
simple  | > node --watch --inspect=0.0.0.0:9229 index.js
simple  |
simple  | Debugger listening on ws://0.0.0.0:9229/de201ceb-5d00-1234-8692-8916f5969cba
simple  | For help, see: https://nodejs.org/en/docs/inspector
simple  | server listening at http://localhost:3000

请注意,旧版本的 Docker Compose 是使用docker-compose. 较新的版本已将 Compose 功能集成到主可执行文件中,因此它以docker compose.

实时应用程序重新启动

打开index.js,进行更改(例如第 14 行的字符串),然后保存文件以查看应用程序自动重新启动:

simple  | Restarting 'index.js'
simple  | Debugger listening on ws://0.0.0.0:9229/acd16665-1399-4dbc-881a-8855ddf9d34c
simple  | For help, see: https://nodejs.org/en/docs/inspector
simple  | server listening at http://localhost:3000

打开或刷新浏览器https://localhost:3000/以查看更新。

使用 VS Code 进行调试

打开 VS Code运行和调试面板,然后单击创建 launch.json 文件


在下拉列表中选择Node.js.vscode/launch.json ,将创建一个文件并在编辑器中打开。添加以下代码,将调试器附加到正在运行的容器:

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Attach to Container",
      "address": "localhost",
      "port": 9229,
      "localRoot": "${workspaceFolder}",
      "remoteRoot": "/home/node/app",
      "skipFiles": [
        "<node_internals>/**"
      ]
    }
  ]
}

保存文件,然后单击“调试”窗格顶部的“附加到容器”以开始调试。


出现调试工具栏。单击装订index.js线以显示红点,切换到第 14 行并添加断点。


在浏览器中刷新https://localhost:3000/,VS Code 将在断点处停止执行并显示所有应用程序变量的状态。单击调试工具栏上的图标可继续运行、单步执行代码或断开调试器。

停止容器

通过打开另一个终端来停止正在运行的容器。cd到应用程序目录,然后输入:

docker compose down


概括

虽然 Docker 需要一些初始设置时间,但健壮、可分发代码的长期好处远远超过了付出的努力。当您添加更多依赖项(例如数据库)时,Docker 将变得非常宝贵。

本教程介绍了在 Docker 容器中运行 Node.js 应用程序的基础知识。

翻译来自:https://www.sitepoint.com/node-js-docker

链接: https://fly63.com/article/detial/12577

npm私有仓库 配置verdaccio在docker环境

前端开发过程中,少不了自己封装一些通用的包,但又不想放在公共的平台,所以搭建一个npm私有的仓库是很有必要的。在这里简单介绍如何使用 verdoccio 在docker环境下的配置。verdoccio,轻量级私有npm代理注册表。

ASP.NET Core 如何在运行Docker容器时指定容器外部端口(docker compose)

所以我们可以通过修改docker compose的配置文件来完成我们的需求。熟悉Docker的都应该知道容器运行时其内部会有一个端口以映射到我们外部的端口,我们需要固定的就是这个外部端口。

DOCKER上运行DOTNET CORE

下载microsoft/dotnet镜像、创建.NET Core MVC项目、上面dotnet restore这一步可能会卡很久遇到超时的状况,因为Nuget在国外的原因,博客园有提供加速镜像,参照设定好之后,速度会快很多

Docker---大型项目容器化改造

虚拟化和容器化是项目云化不可避免的两个问题。虚拟化由于是纯平台操作,一个运行于linux操作系统的项目几乎不需要做任何改造就可以支持虚拟化。而项目如果要支持容器化则需要做许多细致的改造工作。

开发人员爱Docker的10个理由

Stack Overflow开发人员调查中,开发人员将Docker评为:最受欢迎的平台,最喜欢的平台,最常用的平台。来自世界各地的近90,000名开发人员对调查做出了回应。

Docker部署网站之后映射域名

Docker中部署tomcat相信大家也都知道,不知道的可以google 或者bing 一下。这里主要是为了记录在我们启动容器之后,tomcat需要直接定位到网站信息,而不是打开域名之后,还得加个blog后缀才能访问到我们的网站首页。

微服务架构之「 容器技术 」

现在一聊到容器技术,大家就默认是指 Docker 了。但事实上,在 Docker 出现之前,PaaS社区早就有容器技术了,以 Cloud Foundry、OpenShift 为代表的就是当时的主流。那为啥最终还是 Docker 火起来了呢?

Docker部署ngnix静态网站

首先获取ngnix镜像(默认的是最新版),先来编写一个最简单的Dockerfile,一个Dockerfile修改该Nginx镜像的首页.Dockerfile是一个文本文件,其中包含了若干条指令

如何从单独的容器调试运行中的Docker容器?

容器非常适合封装软件,但是有时一味地改造容器镜像以使其尽可能小时,您可能走得太远。我们需要在“简洁”的镜像和无法调试的镜像之间找到很好的平衡。看到人们调试正在运行的容器的正常方法

内部集群的 DNS server 搭建

当我们使用 traefik 反向代理和自动服务发现后,我们对集群内部的服务分为两类:公有服务。如我的博客,网站,以及为它们提供服务的 API。我们可以通过公有的域名去映射服务使得外网能够访问

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!