使用 pnpm workspace 和 standalone 模式构建 Next.js 的 Docker 镜像

news2024/12/25 12:28:56

引言

本文将探讨如何利用 pnpm workspace 和 standalone 模式来构建 Next.js 应用程序的轻量级 Docker 镜像。这种方法通过仅在 node_modules 目录中包含必要的文件,显著减少了最终 Docker 镜像的大小。
在这里插入图片描述

Standalone 模式简介

通常情况下,所有在 dependencies 中列出的包都会被放置在 node_modules 目录中,这会导致镜像体积增大。而在 standalone 模式下构建时,可以从 node_modules 中仅复制必需的文件到一个特定的目录。这样一来,node_modules 将只包含应用程序运行所需的文件,从而大幅减少镜像的大小!

要启用 standalone 模式,请在 next.config.js 文件中添加如下配置:

module.exports = {
  output: 'standalone',
};

目录结构

我们采用了类似于 Turborepo 结构的目录布局:

.
├── apps
│   └── my-app
│       ├── package.json
│       └── ...
├── Dockerfile
├── packages
│   └── other-app
│       └── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── Dockerfile
└── .npmrc

apps 目录包含了作为服务器启动的应用程序,而 packages 目录则包含了 apps 中使用的共享包。

Dockerfile 概览

Dockerfile 设计用于维护每个应用程序的独立性,并将其放置在 /apps/my-app 目录下。下面是 Dockerfile 的概览:

多阶段构建

本 Dockerfile 采用了多阶段构建的方法来分离关注点并最小化最终镜像的大小。

第一阶段:基础环境(base)

FROM node:20.12.0-slim AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

# 启用 pnpm
RUN corepack enable

这一阶段设置了 pnpm 的环境。

第二阶段:依赖安装(deps)

FROM base AS deps

WORKDIR /app

# 复制 `pnpm install` 所需的文件
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY ./apps/my-app/package.json /app/apps/my-app/package.json
COPY ./packages/ /app/packages/

RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
    pnpm install --frozen-lockfile

这一阶段安装了所需的依赖项。

第三阶段:构建器(builder)

FROM base AS builder

WORKDIR /app

# 复制已安装的 `node_modules` 从 deps 阶段
COPY --from=deps /app/node_modules ./node_modules
# 复制构建目标的目录
COPY ./apps/my-app ./apps/my-app
COPY --from=deps /app/packages ./packages
COPY --from=deps /app/.npmrc ./

# 展开符号链接并复制到 pruned 目录
RUN pnpm --filter=@monorepo/my-app deploy /pruned

WORKDIR /pruned

# 构建应用程序
RUN pnpm --filter=@monorepo/my-app build

这一阶段构建了应用程序并准备部署。

第四阶段:运行器(runner)

FROM base AS runner

WORKDIR /app

ENV NODE_ENV=production
ENV NEXT_TELEMETRY_DISABLED=1

# 复制已构建的文件从 builder 阶段
COPY --from=builder /app/apps/my-app/public ./public
COPY --from=builder /pruned/.next/standalone .
COPY --from=builder /pruned/.next/static ./.next/static

CMD ["node", "server.js"]

这一阶段是启动应用程序的实际阶段。

构建 Docker 镜像

使用以下命令来构建 Docker 镜像并检查其大小:

$ docker build -f apps/my-app/Dockerfile --no-cache --target runner --tag myapp:latest --progress=plain

构建后检查镜像:

$ docker images

您将看到一个准备就绪且体积轻量的镜像。

结论

尽管在过程中遇到了一些挑战,比如理解 pnpm deploy 命令及管理多个应用程序在单一 workspace 中的过程,但最终还是成功地构建了一个高效且轻量的 Docker 镜像。

遇到的问题

  • 管理多个应用程序的复杂性:尝试在一个 Dockerfile 中处理所有应用程序目录下的应用,导致 --build-arg 参数增加,使得 Dockerfile 变得繁琐。
    • 解决方案:通过在每个 apps 目录中配置 Dockerfile 来避免这种情况。这样还可以针对每个应用程序单独进行 Node.js 的更新等操作。
  • pnpm deploy -> build 流程的理解不足:对 pnpm 通过符号链接工作的方式以及在 deploy 后将实际文件复制的行为理解不够深入,导致应用程序启动失败。
    • 解决方案:将 docker build--target 参数更改为 builder,然后通过 docker run -it my-app /bin/bash 进入容器并查看目录状态来进行调试。

参考链接

  • Next.js 文档:自动复制追踪文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2083540.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyPrint打印设计器(四)vue3 函数式调用组件

vue3 函数式调用组件 vue中,通常情况下调用一个组件需要以下步骤 导入组件在template引入组件,并且设置ref属性在js模块定义对应的ref属性通过ref对象调用对应的方法 如果这个组件在template是不必要的,那么可以通过函数式调用组件&#xff…

Windows 10/11 系统优化工具 Optimizer 16.7

Optimizer 功能特色 全语言支持(提供19种语言) 提高系统和网络性能 禁用不必要的窗口服务 禁用 Windows 遥测、小娜等 禁用 Office 遥测(仅适用于 Office 2016) 禁用 Windows 10 自动更新 一次快速下载有用的应用程序 卸载 UWP 应…

ARMxy工业控制器搭载 Mini PCIe加密安全芯片工业控制拓展之旅

在当今高度数字化和智能化的工业领域,数据采集的准确性、实时性和全面性对于优化生产流程、提高产品质量以及保障生产安全至关重要。ARM 工业控制器以其高效能、低功耗和出色的稳定性,成为了工业自动化领域的重要组成部分。而其中的 Mini PCIe 接口更是为…

JVM内存结构、内存参数、调优原理

文章目录 引言I JVM基础知识1.1 JVM内存区域1.2 JVM 堆内存布局1.3 JVM 内存参数II 调整JVM的默认堆内存配置2.1 java命令启动jar包时配置JVM 的内存参数2.2 基于Tomcat服务器部署的java应用,配置JVM 的内存参数III JVM调优基本概念: 应用程序的响应时间(RT)和吞吐量(QPS)…

基于springboot+vue+uniapp的使命召唤游戏助手小程序

开发语言:Java框架:springbootuniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包&#…

Lenze伦茨E82ZAFSC / E82ZAFSC001变频器IO模块手测

Lenze伦茨E82ZAFSC / E82ZAFSC001变频器IO模块手测

easyExcel 单元格合并

需求 现在有一张员工表,需要将员工信息导出为excel,同一个部门放在一起,同一个工资段放在一起。 case 员工表 package com.tx.test.testeasyexcel.excel;import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.anno…

人工智能开发实战TensorFlow机器学习框架解析

内容导读 TensorFlow概述 TensorFlow环境搭建 TensorFlow计算机加速 一、TensorFlow概述 1、TensorFlow简介 ‌‌TensorFlow是由‌Google开发的用于‌机器学习和人工智能的开源软件库,特别适用于‌深度神经网络的训练和推理。‌ 它是一个基于‌数据流图的符号…

08 - debugfs

---- 整理自 王利涛老师 课程 实验环境:宅学部落 www.zhaixue.cc 文章目录 0. 什么是 debugfs1. debugfs 配置编译和注册运行2. 第一个 debugfs 编程示例3. 通过 debugfs 导出整型数据4. 通过 debugfs 导出 16 进制数据5. 通过 debugfs 到处数组6. 通过 debugfs 导出…

【SQL】换座位

目录 题目 分析 代码 题目 表: Seat ---------------------- | Column Name | Type | ---------------------- | id | int | | student | varchar | ---------------------- id 是该表的主键(唯一值)列。 该表的每一行都表示学…

ComfyUI SDXL Prompt Styler 简介

SDXL Prompt Styler 来自于 comfyui-art-venture 节点 style 已经更新 旧版本的 sai-line art 变更为 line art log_prompt 已经更新 旧版本的 false 变更为 Yes 或 No style_name 已经更新 旧版本的 true (不再适用)(可以尝试对应style中…

【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch12 随机森林(Random Forest)

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-…

dht11 + Sc32440驱动

一、DHT11概述 1、简介 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器,它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性和卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件&#xff…

【专题】2024年中国AI人工智能基础数据服务研究报告合集PDF分享(附原数据表)

原文链接:https://tecdat.cn/?p37516 随着人工智能技术的迅猛发展,AI 基础数据服务行业迎来了前所未有的发展机遇。报告合集显示,2023 年中国 AI 基础数据服务市场规模达到 45 亿元,且未来五年复合增长率有望达到 30.4%。多模态大…

如何在不同设备上检查IP 地址?

IP 地址(Internet 协议地址)是网络上设备的唯一标识符。了解如何查找 IP 地址对于解决网络问题、设置网络设备和维护网络安全非常重要。本文将详细介绍如何在不同设备上检查 IP 地址,包括 Windows 计算机、Mac 计算机、智能手机(A…

【Material-UI】Rating组件:如何使用Basic Rating实现多种评分方式

文章目录 一、Rating 组件概述1. 组件介绍2. Basic rating 的核心功能 二、Basic rating 的详细使用方法1. 受控组件(Controlled)2. 只读模式(Read-only)3. 禁用状态(Disabled)4. 无评分状态(No…

嵌入式笔试准备

文件组合 将传输文件切分成多个部分&#xff0c;按照原排列顺序&#xff0c;每部分文件编号为一个正整数。 class Solution { public:vector<vector<int>> fileCombination(int target) {vector<vector<int>> res;int sum 0;for(int i1; i<targe…

VS2017+QT不能正常添加资源文件

is not in a subdirectory of the resource file.You now have the option to copy this file to a valid location. . 该错误原因是项目路径英文导致的&#xff0c;换成全中文路径就没问题了 具体步骤&#xff1a; 双击qrc文件&#xff0c;先添加前缀&#xff0c;然后添加图片…

机器学习之监督学习(一)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 机器学习之监督学习&#xff08;一&#xff09; 1.监督学习定义2.监督学习分类2.1回归 regression2.2 分类 classification 3.线性回归 linear regression3.1 单特征线性回归…

Android 突破边界:解密google Partner机制获取Resource

在 Android 应用开发中&#xff0c;除了可以查找系统中的特定 APK 并获取其信息外&#xff0c;还可以通过 Partner 机制获取 Partner APK 的资源文件&#xff0c;同时这种机制也是一种跨进程的通信方式。本文将进一步探讨这些内容。 1.Partner apk注册特定的action广播 /** M…