发布于 2026-01-06 0 阅读
0

如何将 NestJS 容器化

如何将 NestJS 容器化

今天,我将带你了解如何将 NestJS 应用容器化。这将帮助你将应用打包到一个容器中,使其能够在不同的环境中稳定运行。让我们开始吧!

我们走吧

步骤 1:设置 Dockerfile

首先,我们需要Dockerfile在 NestJS 项目的根目录下创建一个文件。该文件将包含构建 Docker 镜像的指令。

基本Dockerfile结构大概是这样的:

# Use Node.js version 20 as the base image
FROM node:20

# Set the working directory in the container
WORKDIR /usr/src/app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Build the application
RUN npm run build

# Run the application
CMD ["node", "dist/main.js"]
Enter fullscreen mode Exit fullscreen mode

此 Dockerfile 执行以下操作:

  • 使用 Node.js 版本 20 作为基础镜像。
  • 将工作目录设置为/usr/src/app.
  • 复制package.jsonpackage-lock.json工作目录。
  • 使用以下命令安装依赖项npm install
  • 将应用程序的其余代码复制到容器中。
  • 使用以下方式构建应用程序npm run build
  • 指定运行应用程序的命令node dist/main.js

创建一个.dockerignore文件,将不必要的文件从 Docker 镜像中排除。

node_modules
npm-debug.log
dist
.git
.env
*.md
.gitignore
Enter fullscreen mode Exit fullscreen mode

步骤 2:在本地测试 Docker 容器

现在,让我们在本地测试一下 Docker 镜像,确保一切运行正常。

构建 Docker 镜像:

在项目根目录下打开终端并运行:

   docker build -t nest-app .
Enter fullscreen mode Exit fullscreen mode

此命令构建 Docker 镜像并为其添加标签nest-app

运行 Docker 容器:

镜像构建完成后,您可以使用以下命令运行它:

   docker run -p 3000:3000 nest-app
Enter fullscreen mode Exit fullscreen mode

此命令从镜像启动一个新容器nest-app,并将容器的 3000 端口映射到本地计算机的 3000 端口。

核实申请:

打开您的网络浏览器并访问http://localhost:3000。如果一切设置正确,您应该会看到您的 NestJS 应用程序正在运行。

步骤 3:优化生产

为了优化 Dockerfile 以适应生产环境,我们将进行一些更改以减小镜像大小并提高安全性。

使用 Alpine 节点镜像:

Alpine 镜像体积更小、效率更高。请将基础镜像更新为:

   FROM node:20-alpine
Enter fullscreen mode Exit fullscreen mode

设置 NODE_ENV 环境变量:

设置NODE_ENVproduction优化应用程序以适应生产环境:

   ENV NODE_ENV production
Enter fullscreen mode Exit fullscreen mode

请使用npm ci以下方式代替npm install

npm ci对于 Docker 构建等自动化环境来说,这种方式更可靠。替换RUN npm install为:

   RUN npm ci
Enter fullscreen mode Exit fullscreen mode

添加用户说明:

为了提高安全性,请以非 root 用户身份运行应用程序。在安装依赖项后添加以下命令:

   USER node
Enter fullscreen mode Exit fullscreen mode

使用多阶段构建:

多阶段构建允许你将构建环境和运行时环境分离,从而创建更小的最终镜像。以下是一个多阶段 Dockerfile 示例:

   # Development stage
   FROM node:20-alpine AS development
   WORKDIR /usr/src/app
   COPY package*.json ./
   RUN npm ci
   COPY . .
   USER node

   # Build stage
   FROM node:20-alpine AS build
   WORKDIR /usr/src/app
   COPY package*.json ./
   COPY --from=development /usr/src/app/node_modules ./node_modules
   COPY . .
   RUN npm run build
   ENV NODE_ENV production
   RUN npm ci --only=production && npm cache clean --force
   USER node

   # Production stage
   FROM node:20-alpine AS production
   WORKDIR /usr/src/app
   COPY --from=build /usr/src/app/node_modules ./node_modules
   COPY --from=build /usr/src/app/dist ./dist
   CMD ["node", "dist/main.js"]
Enter fullscreen mode Exit fullscreen mode

该装置分为三个阶段:

  • development用于本地开发,包含所有依赖项。
  • build构建用于生产环境的应用程序。
  • production:运行生产构建的最后阶段。

步骤 4:重建并运行优化后的镜像

更新完成后Dockerfile,重新构建镜像:

docker build -t nest-app .
Enter fullscreen mode Exit fullscreen mode

然后,运行新的优化容器:

docker run -p 3000:3000 nest-app
Enter fullscreen mode Exit fullscreen mode

使用以下命令检查新图像的大小:

docker images
Enter fullscreen mode Exit fullscreen mode

您应该会看到图像大小显著减小,从而提高生产效率。

常见问题排查

  • 错误:找不到模块“webpack”:请确保您的基础镜像中使用的是正确的 Node.js 版本。例如,请使用FROM node:20-alpine而不是FROM node:14-alpine
  • 错误:找不到 nest 命令:这通常是由于未安装 Nest CLI 导致的。在多阶段构建中,请确保从开发阶段复制node_modules已安装 CLI 的目录。

使用不同的软件包管理器

如果你使用的是 pnpm 而不是 npm,你的Dockerfile配置会略有不同。以下是一个示例:

# Development stage
FROM node:20 AS development
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY pnpm-lock.yaml ./
RUN pnpm fetch --prod
COPY . .
RUN pnpm install
USER node

# Build stage
FROM node:20 AS build
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /usr/src/app
COPY pnpm-lock.yaml ./
COPY --from=development /usr/src/app/node_modules ./node_modules
COPY . .
RUN pnpm build
ENV NODE_ENV production
RUN pnpm install --prod
USER node

# Production stage
FROM node:20-alpine AS production
WORKDIR /usr/src/app
COPY --from=build /usr/src/app/node_modules ./node_modules
COPY --from=build /usr/src/app/dist ./dist
CMD ["node", "dist/main.js"]
Enter fullscreen mode Exit fullscreen mode

将 Fastify 与 NestJS 结合使用

如果您使用的是 Fastify 而不是 Express,则需要修改您的main.ts配置以监听0.0.0.0

import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );
  await app.listen(process.env.PORT || 3000, '0.0.0.0');
}
bootstrap();
Enter fullscreen mode Exit fullscreen mode

搞定!你现在拥有了一个针对生产环境优化的 Docker 化 NestJS 应用。如果你想部署你的 NestJS 应用,请访问sliplane.io。

谢谢,
乔纳斯

文章来源:https://dev.to/code42cate/how-to-dockerize-nestjs-327j