使用容器进行 Node.js 开发

先决条件

完成 Node.js 应用程序的容器化

概述

在本部分中,您将了解如何为容器化应用程序设置开发环境。这包括:

  • 添加本地数据库并持久化数据
  • 配置容器以运行开发环境
  • 调试您的容器化应用程序

添加本地数据库并持久化数据

您可以使用容器来设置本地服务,例如数据库。在本部分中,您将更新compose.yaml文件以定义数据库服务和用于保存数据的卷。

compose.yaml在 IDE 或文本编辑器中打开文件。您会注意到它已经包含 Postgres 数据库和卷的注释掉指令。

src/persistence/postgres.js在 IDE 或文本编辑器中打开。您会注意到,此应用程序使用 Postgres 数据库,并且需要一些环境变量才能连接到数据库。该compose.yaml文件没有定义这些变量。

您需要更新compose.yaml文件中的以下项目:

  • 取消注释所有数据库指令。
  • 在server服务下添加环境变量。
  • 添加secrets到服务器服务中获取数据库密码。

以下是更新后的compose.yaml文件。

services:
  server:
    build:
      context: .
    ports:
      - 3000:3000
    environment:
      NODE_ENV: production
      POSTGRES_HOST: db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD_FILE: /run/secrets/db-password
      POSTGRES_DB: example
    depends_on:
      db:
        condition: service_healthy
    secrets:
      - db-password
  db:
    image: postgres
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt

笔记

要了解有关 Compose 文件中的说明的更多信息,请参阅 Compose 文件参考

在使用 Compose 运行应用程序之前,请注意此 Compose 文件使用 secrets并指定一个password.txt文件来保存数据库的密码。您必须创建此文件,因为它不包含在源存储库中。

在克隆存储库的目录中,创建一个名为 的新目录db。在该db目录中,创建一个名为password.txt.在 IDE 或文本编辑器中打开password.txt并添加您选择的密码。密码必须位于单行中,文件中不得有任何其他行。

您的目录中现在应该有以下内容docker-nodejs-sample

├── docker-nodejs-sample/
│ ├── db/
│ │ └── password.txt
│ ├── spec/
│ ├── src/
│ ├── .dockerignore
│ ├── .gitignore
│ ├── compose.yaml
│ ├── Dockerfile
│ ├── package-lock.json
│ ├── package.json
│ ├── README.Docker.md
│ └── README.md

运行以下命令来启动您的应用程序。

$ docker compose up --build

打开浏览器并验证应用程序是否正在 http://localhost:3000运行。

将一些项目添加到待办事项列表中以测试数据持久性。

将一些项目添加到待办事项列表后,按ctrl+c终端中的 停止应用程序。

在终端中,运行docker compose rm以删除容器,然后运行docker compose up以再次运行应用程序。

$ docker compose rm
$ docker compose up --build

在浏览器中刷新 http://localhost:3000并验证待办事项是否仍然存在,即使在容器被删除并再次运行之后也是如此。

配置并运行开发容器

您可以使用绑定挂载将源代码挂载到容器中。一旦您保存文件,容器就可以立即看到您对代码所做的更改。这意味着您可以在容器中运行进程(例如nodemon)来监视文件系统更改并对其做出响应。要了解有关绑定挂载的更多信息,请参阅存储概述

除了添加绑定挂载之外,您还可以配置 Dockerfile 和compose.yaml文件来安装开发依赖项并运行开发工具。

更新您的 Dockerfile 以进行开发

在 IDE 或文本编辑器中打开 Dockerfile。请注意,Dockerfile 不会安装开发依赖项,也不会运行 nodemon。您需要更新 Dockerfile 以安装开发依赖项并运行 nodemon。

您可以为两者使用一个多阶段 Dockerfile,而不是创建一个用于生产的 Dockerfile 和另一个用于开发的 Dockerfile。

将您的 Dockerfile 更新为以下多阶段 Dockerfile。

# syntax=docker/dockerfile:1

ARG NODE_VERSION=18.0.0

FROM node:${NODE_VERSION}-alpine as base
WORKDIR /usr/src/app
EXPOSE 3000

FROM base as dev
RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci --include=dev
USER node
COPY . .
CMD npm run dev

FROM base as prod
RUN --mount=type=bind,source=package.json,target=package.json \
    --mount=type=bind,source=package-lock.json,target=package-lock.json \
    --mount=type=cache,target=/root/.npm \
    npm ci --omit=dev
USER node
COPY . .
CMD node src/index.js

在 Dockerfile 中,首先as baseFROM node:${NODE_VERSION}-alpine语句添加标签。这使您可以在其他构建阶段引用此构建阶段。接下来,添加一个标记dev为安装开发依赖项的新构建阶段并使用 启动容器npm run dev。最后,您添加一个标记prod为省略开发依赖项的阶段并使用node src/index.js.要了解有关多阶段构建的更多信息,请参阅 多阶段构建

接下来,您需要更新 Compose 文件才能使用新阶段。

更新您的 Compose 文件以进行开发

要使用 Compose 运行dev阶段,您需要更新compose.yaml 文件。在 IDE 或文本编辑器中打开compose.yaml文件,然后添加 指令以从多阶段 Dockerfile 中target: dev定位该阶段。dev

另外,将新卷添加到服务器服务以进行绑定安装。对于此应用程序,您将从./src本地计算机安装到/usr/src/app/src容器中。

最后,发布9229调试端口。

以下是更新后的 Compose 文件。

services:
  server:
    build:
      context: .
      target: dev
    ports:
      - 3000:3000
      - 9229:9229
    environment:
      NODE_ENV: production
      POSTGRES_HOST: db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD_FILE: /run/secrets/db-password
      POSTGRES_DB: example
    depends_on:
      db:
        condition: service_healthy
    secrets:
      - db-password
    volumes:
      - ./src:/usr/src/app/src
  db:
    image: postgres
    restart: always
    user: postgres
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
    healthcheck:
      test: [ "CMD", "pg_isready" ]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  db-data:
secrets:
  db-password:
    file: db/password.txt

运行您的开发容器并调试您的应用程序

运行以下命令以运行对Dockerfilecompose.yaml文件进行新更改的应用程序。

$ docker compose up --build

打开浏览器并验证应用程序是否正在 http://localhost:3000运行。

对本地计算机上应用程序源文件的任何更改现在都将立即反映在正在运行的容器中。

docker-nodejs-sample/src/static/js/app.js在 IDE 或文本编辑器中打开,并将第 109 行的按钮文本从 更新Add ItemAdd

+                         {submitting ? 'Adding...' : 'Add'}
-                         {submitting ? 'Adding...' : 'Add Item'}

在浏览器中刷新 http://localhost:3000并验证是否显示更新的文本。

您现在可以将检查器客户端连接到您的应用程序以进行调试。有关检查器客户端的更多详细信息,请参阅 Node.js 文档

概括

在本部分中,您了解了如何设置 Compose 文件以添加模拟数据库并保留数据。您还学习了如何创建多阶段 Dockerfile 并设置用于开发的绑定安装。

相关信息:

下一步

在下一节中,您将学习如何使用 Docker 运行单元测试。