昆仑虚 - NextJS 项目如何进行部署?

news2024/12/24 21:34:05

引言

NextJS 是一个构建于 NodeJS 之上的一个 Web 开发框架。它基于 React 特性进行了一些列的扩展!! 在社区中也很是火热, 前段时间 「昆仑虚」 也终于完成了项目的迁移(React => NexJS)!!

那么接下来就是项目部署, NextJS 相比常规的前端部署还是有所区别的:

  • 常规的前端项目只是包含一些静态的资源文件, 只要起一个 Web 服务器, 然后把资源丢上去就行, 比如: Nginx
  • 但是对于 NextJS 项目是包含后端(Node)服务的, 当然官网 CI 工具其实也提供了相关 CI 命令, 正常只需要 Build 好后, 执行 start 命令即可, 但是我个人更希望能够使用 pm2 来运行, 基于 pm2 可以方便管理服务进程以及自带一套日志系统, 同时还希望能够通过 Docker 的方式来进行部署
  • NextJS 项目地址(欢迎 Star): KunLunXu-CC/website
  • Nginx 配置: docker/nginx/nginx.conf

一、架构

image

改造后 「昆仑虚」 整体部署希望如上图所示:

  • 所有服务(包括 Nginx) 都是一个 Docker 容器
  • Nginx 在中间只作为反向代理来使用
  • 当用户访问前端页面或后端接口时, 通过 Nginx 方向代理到对应的服务

当然本文只讲解 NextJS 服务部署的部分, 与此同时最后还会给出 Nginx 反向代理的配置, 至于后端服务的部署则不做讲解, 而且前后端服务都是独立的, 确失后端部分也是不影响 NextJS 部署流程…

二、修改 NextJS 配置文件

修改 NextJS 配置文件, 确保在 Build 时输出模式为 standalone, 关于 output 配置具体信息可查阅 next-config-js/output

// next.config.mjs
const nextConfig = {
+ output: 'standalone',
};
export default nextConfig;

三、Dockerfile 编写

这里我是参考了官方的一个 Demo, 基于官方模版做了简单的调整

项目根目录下创建 dockerfile 配置文件, 配置内容如下, 具体的介绍看注释:

# 使用 amd64 架构的 node 镜像作为基础镜像
FROM --platform=linux/amd64 node AS base

# 新增用户 & 用户组
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# 安装 pm2 和 pnpm
RUN npm install --global pm2 pnpm

# ------------------------- deps -----------------------------------
FROM base AS deps
WORKDIR /app

# 拷贝 package.json 和 pnpm-lock.yaml 文件, 并安装相关依赖
COPY package.json pnpm-lock.yaml* .npmrc ./
RUN pnpm i --frozen-lockfile

# ------------------------- builder -----------------------------------
FROM base AS builder
WORKDIR /app

# 拷贝上一步安装的依赖
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# 构建项目
RUN pnpm run build

# ------------------------- runner -----------------------------------
FROM base AS runner
WORKDIR /app

# 创建 ecosystem.config.js 文件, 用于 pm2 启动不想直接在项目里创建
COPY <<EOF /app/ecosystem.config.js
module.exports = {
  apps: [
    {
      name: 'klx-website',
      script: 'node server.js',
      watch: false,
  },
  ],
};
EOF

# 创建相关目录, 并设置权限
RUN mkdir pm2
RUN mkdir .next
ENV PM2_HOME /app/pm2
RUN chown nextjs:nodejs pm2
RUN chown nextjs:nodejs .next

# 复制运行服务所需要的产物, see: https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

# 暴露端口、设置主机名
EXPOSE 3000
ENV HOSTNAME="0.0.0.0"

# 运行容器时, 启动 pm2
CMD pm2 start ecosystem.config.js --no-daemon

下面我们尝试构建下镜像, 如下命令所示:

# 后面一个 . 别漏了
docker build -t website:4.2.4 . 

image

在构建时这里遇到一个坑, 就是我的机器是 M2 芯片(ARM), 导致 Build 出来的镜像在 Ubuntu 上无法运行, 这里解决方案有挺多的, 具体可以看 Forcing docker to use linux/amd64 platform by default on macOS

  1. Build 时通过 --platform linux/amd64 参数指定平台, 例: docker build --platform linux/amd64 -t website:4.2.4
  2. 通过环境变量来修改 export DOCKER_DEFAULT_PLATFORM=linux/amd64
  3. Dockerfile 中, 在指定 form 时进行设置(本文使用的方案), 例: FROM --platform=linux/amd64 node
  4. Docker compose 中, 通过 platform: linux/amd64 字段来设置

四、阿里云私人镜像仓库

这里还需要整个私人的镜像仓库, 构建好的镜像需要上传到上面, 然后在 docker compose 中进行引用。我这里使用的是阿里的服务, 下面将简单演示下:

  1. 在阿里云搜索「镜像容器服务」

image

  1. 我这里用的是免费版的

image
image
image

  1. 先创建一个命令空间

image

  1. 创建镜像仓库

image

  1. 这里我选择本地仓库

image

  1. 创建完成后, 进入详情页会有具体的仓库信息, 以及相关使用介绍(怎么登录、怎么推送、怎么拉取…)

image

五、上传镜像

大部分命令上面最后一张图其实已经给出了, 下面只是走个流程

  1. 重新构建镜像
docker build -t registry.cn-hangzhou.aliyuncs.com/kunlunxu/website:4.2.4 .
  1. 登录阿里云 Docker Registry
# username 换成自己的用户名
docker login --username=13*********@163.com registry.cn-hangzhou.aliyuncs.com
  1. 镜像推送
docker push registry.cn-hangzhou.aliyuncs.com/kunlunxu/website:4.2.4

image

  1. 推送完成, 在阿里云镜像版本列表中, 就能够看到推送的镜像了

image

六、Docker compose 编写

这里我希望通过 Docker compose 来管理我的容器(重启啥的比较方便)

项目根目录下创建 docker-compose.yml 配置文件, 具体内容如下, 相关描述看注释

version: '3'
services:
  website:
    image: registry.cn-hangzhou.aliyuncs.com/kunlunxu/website:4.2.4 # 镜像地址
    container_name: klx-website # 容器名称
    ports:
      - 3000:3000 # 端口映射
    environment:
      - TZ=Asia/Shanghai # 时区
    logging: # 日志配置
      driver: "json-file"
      options:
        max-size: "100k"
        max-file: "20"

七、部署 NexJS 项目

  1. 登录你的服务器, 拉取最新的代码! 这一步取决于你自己的部署方式, 我这里是直接在服务器把仓库代码给拉下来了, 当然你也可以直接在服务器创建一个 Docker compose 配文件)

  2. 执行 Docker compose 命令启动项目即可

docker compose up -d
  1. 运行成功

image

八、Nginx 配置

下面是 Nginx 方向代理相关的一些配置, http://172.17.8.146 是我服务器内网地址

    # HTTPS 设置
    server {
        listen 443 ssl;
        server_name www.kunlunxu.cc;#换成你的域名
        ssl_certificate /etc/nginx/ssl.pem;#证书文件
        ssl_certificate_key /etc/nginx/ssl.key;#秘钥文件
        ssl_session_timeout 5m;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers  ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
        ssl_prefer_server_ciphers   on;

        # 前端代理配置
        location / {
            proxy_pass http://172.17.8.146:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

        # API 代理配置
        location /api/ {
            proxy_pass http://172.17.8.146:4000; # 代理到 API 服务器
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }
    }
}

九、TODO

到处 NextJS 部署流程大体就是如此了, 但是这里的一切都是需要手动参与的, 包括:

  • Build 镜像前, 需要手动修改 .env.local 中的必要的环境变量
  • 需要手动在本地 Build
  • Build 完成后需要手动修改 docker-compose.yml 上镜像版本号, 并提交代码
  • 最后还需要登录到服务器, 拉取最新代码后, 拉取最新镜像后, 停止并删除相关镜像后, 重启服务

总之一切都是那么的麻烦, 后续则需要将这些流程全部简化掉…

十、参考

  • 强制 docker 在 macOS 上默认使用 linux/amd64 平台
  • building-your-application/deploying#docker-image
  • Set up a CDN
  • Serving assets and images in Next.js from a CDN without Vercel
  • Deploying a Next.js application on an EC2 instance with PM2 and Nginx

image

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

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

相关文章

便捷实用的桌面时钟 让你随时掌握时间 美观且大气

便捷实用的桌面时钟 让你随时掌握时间 美观且大气。桌面时钟顾名思义就是可以放在桌面上的时钟&#xff0c;这是一款界面优美,功能实用,易于操作的桌面时钟工具芝麻时钟&#xff08;下载地址&#xff1a;https://clock.zhimasoft.cn/?bi&#xff09; 找个好看的桌面时钟&…

【R语言】随机森林+相关性热图组合图

数据概况文末有获取方式 随机森林部分 #调用R包 library(randomForest) library(rfPermute) library(ggplot2) library(psych) library(reshape2) library(patchwork) library(reshape2) library(RColorBrewer) ​ ​ #读取数据 df<-read.csv("F:\\EXCEL-元数据\\2020…

Spring Boot与JavaWeb协同:在线考试系统的实现“

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理基于JavaWeb技术的在线考试系统设计与实现…

【02】Windows特殊权限-Trustedinstaller

知识点&#xff1a; “TrustedInstaller” 是 Windows 操作系统中的一个特殊账户&#xff0c;用于管理和保护重要的系统文件。它是 Windows 模块安装程序 (Windows Modules Installer) 的一部分&#xff0c;负责安装、修改和删除 Windows 更新和可选组件。默认情况下&#xff…

Power BI:链接数据库与动态数据展示案例

一、案例背景 在数据驱动的时代&#xff0c;如何高效、直观地展示和分析数据成为了企业决策和个人洞察的关键。Power BI作为一款强大的商业智能工具&#xff0c;凭借其强大的数据连接能力、丰富的可视化选项以及交互性和动态性&#xff0c;成为了众多企业和个人的首选。本文将…

C++/初识C++

目录 一、前言 二、正文 1C语言第一个程序&#xff1a; 1.1C的第一个程序&#xff1a; 2.命名空间 2.1 namespace的价值 2.2namespace的定义 2.3namespace的正常使用 3.C输出和输入 三、结言 一、前言 点来不及悼念C语言&#xff0c;接下来出场的是新的语言C。不同于C…

WebGL编程指南 - WebGL入门

初识绘图流程、缓冲区、着色器、attribute和uniform变量 先画一个蓝色的正方形 html代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content&…

iOS 18升级:避免常见陷阱,顺利完成升级

随着iOS 18的发布&#xff0c;许多用户都希望尽快体验到新系统带来的新功能和改进。然而&#xff0c;升级过程可能会因为准备工作不足或对步骤的不熟悉而变得复杂。本文旨在为用户提供一个清晰的升级指南&#xff0c;确保升级过程既平滑又安全。 升级前的准备工作 在开始升级之…

PCL 点云配准-ICP算法(精配准)

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 点云加载函数 2.1.2 ICP 配准函数 2.1.3 可视化函数 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接&#xff1a; PCL点云算法与项目实战案例汇总&#xf…

股票Tick数据如何获取做量化交易

【高频tick数据源】银河金融数据库 【tick高频回测策略】在利用股票Tick数据做量化交易时&#xff0c;一个关键的细节点是“实现高频交易中的市场冲击成本最小化”。细节点&#xff1a;市场冲击成本最小化策略 1. 策略原理市场冲击成本是指大额交易对市场价格造成的影响&#…

Linux驱动开发——设备树

文章目录 1 什么是设备树&#xff1f;2 DTS、DTB和DTC3 DTS语法3.1 dtsi头文件3.2 设备节点3.3 标准属性3.4 根节点compatible属性3.5 向节点追加或修改内容 4 创建小型模板设备树5 设备树在系统中的体现6 绑定信息文档7 设备树常用OF操作函数7.1 查找节点的OF函数7.2 查找父/子…

软考高级系统规划与管理师,都是精华知识点!

知识点&#xff1a;信息的定义和属性 1、 信息的基本概念 l 信息是客观事物状态和运动特征的一种普遍形式&#xff0c;客观世界中大量地存在、产生和传递着以这些方式表示出来的各种各样的信息。 l 维纳&#xff08;控制论创始人&#xff09;&#xff1a;信息就是信息&#…

基于BS21芯片方案的SLE星闪模块功能特点

1、E105-BS21系列SLE星闪模块产品简介 E105-BS21系列SLE星闪模块模块是基于星闪协议 1.0 版本的串口转 SLE&#xff08;SparkLink Low Energy&#xff09;星闪模块&#xff0c;具有体积小、功耗低、 传输距离远、传输速度快、抗干扰能力强、低延时等特点&#xff0c;工作在 2…

R语言机器学习算法实战系列(四)随机森林算法+SHAP值 (Random Forest)

文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述特征选择数据切割调节参数构建模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve特征的重要性模型解释保存模型总结系统信息介绍 随机森林是常用的非线性用于构建分类器的算法,它是由数…

2024年法拍房爆了 1-9月挂牌金额超过5200亿

据互联网数据统计2024年1-9月全国法拍房挂拍量为494737套&#xff0c;同比增长66.84%&#xff0c;挂牌金额超过5200亿&#xff01; 法拍房暴增的背后是原业主的债务困境&#xff0c;或是房地产风险释放触底&#xff0c;或与规模高达10.61万亿的经营D相关。而对于不良资产行业机…

算法-利用深度优先搜索求解二叉树路径问题

这道题可以用深度优先搜索来写&#xff0c;比如说加入节点左右节点都为空且值等于targetsum则返回true,这里可以使用一个简单的方法来写&#xff0c;就比如说我们每次遍历到一个节点时&#xff0c;用targetsum减去当前节点的值 &#xff0c;这样的话只要遍历到叶子节点值等于ta…

国际期货收费行情源CTP推送式/期货配资软件开发对接行情源的技术性说明

在现代金融市场中&#xff0c;期货交易因其高风险和高回报特性而备受关注。为了满足期货交易者的需求&#xff0c;开发高效、稳定和安全的期货交易软件变得尤为重要。本文将对国际期货收费行情源CTP推送式及期货配资软件的开发对接行情源的技术细节进行详细说明。 一、CTP&…

Windows 下 golang 多版本管理

三年前的旧文&#xff0c;最新要切版本&#xff0c;翻了出来&#xff0c;现在依然有用&#xff0c;分享出来~ 当前 golang 的各个版本还有些不兼容的问题&#xff0c;最近遇到 go-micro 框架只能运行在 go1.13~1.14 的版本情况&#xff0c;而我本地 windows 环境安装的 Golang …

Java中字符串.split分割转List<String>判空问题

第一种分割直接分割&#xff0c;如果cph字符串为空&#xff0c;分割后cphList会>0 List<String> cphList Arrays.asList(cph.split(","));第二种判空后分割&#xff0c;如果cph字符串为空&#xff0c;判空后再分割cphList会0 List<String> cphList…

面向城市运行“一网统管”的实景三维示范应用

在新型智慧城市建设的浪潮中&#xff0c;实景三维技术正成为推动城市治理现代化的重要力量。“一网统管”作为城市运行管理的新理念&#xff0c;强调了跨部门协作和数据共享&#xff0c;而实景三维技术为此提供了强有力的支撑。本文将探讨实景三维技术如何赋能“一网统管”&…