Skip to content

使用容器进行 Node.js 开发

原文:https://docs.docker.com/language/nodejs/containerize/

前提条件

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

概述

在本节中,您将学习如何为您的容器化应用程序设置开发环境。这包括:

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

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

您可以使用容器来设置本地服务,比如数据库。在本节中,您将更新 compose.yaml 文件以定义数据库服务和用于持久化数据的卷。

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

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

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

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

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

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 目录中应该包含以下内容。

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

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

console
docker compose up --build

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

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

添加一些待办事项后,按 ctrl+c 停止您的应用程序。

在终端中,运行 docker compose rm 删除您的容器,然

后再运行 docker compose up 重新运行您的应用程序。

console
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 文件。打开您的 compose.yaml 文件在 IDE 或文本编辑器中,然后添加 target: dev 指令以从您的多阶段 Dockerfile 中目标 dev 阶段。

此外,为服务器服务添加一个新的卷以进行绑定挂载。对于此应用程序,您将从本地机器挂载 ./src 到容器中的 /usr/src/app/src

最后,公开端口 9229 以进行调试。

以下是更新后的 Compose 文件。

yaml
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 文件的新更改。

console
docker compose up --build

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

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

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

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

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

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

总结

在本节中,您查看了如何设置您的 Compose 文件以添加模拟数据库并持久化数据。您还学习了如何创建多阶段 Dockerfile 并设置绑定挂载进行开发。

相关信息:

下一步

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