NextJS项目的部署以及多环境的实现
背景
开发了个Next项目,将部署过程记录一下。另外由于项目准备了两个服务器分别作为开发自测的开发环境和交付给客户的生产环境使用;因此也介绍一下NextJS项目中多环境的配置。
项目结构

计划是让Nginx根据不同的路径前缀决定请求发给哪个后端;而路径前缀则是由Docker打包镜像的时候传递参数给Next App作为环境变量。
部署过程
设置next.config.js
导出静态文件
我们需要Next项目编译后的文件,这需要我们把next.config.js中加上output: "export"设置,这样我们在运行next build命令后,Next会生成一个静态资源文件夹out ,如图:

️注意事项
在output: "export" 模式下无法使用rewrites 或者headers 等设置,官方文档列出的完整不支持的功能如下:

设置环境变量
如上文提到,Nginx需要根据不同的路径前缀来决定请求哪个后端,那么就需要前端去判断当前是什么环境再设定当前的请求的路径前缀。
根据NODE_ENV判断当前环境【已失败】
计划是当
NODE_ENV为production的时候,请求前缀为/prod;当NODE_ENV为development的时候则为/dev。实施的时候却发现next build和next start这两条命令都会默认设置NODE_ENV为production。因此当我使用cross-env在运行命令时设置NODE_ENV为development就失败了(如图)。

这么设置,运行npm run dev后获取到的process.env.NODE_ENV还是production。

后来看到有网友说可以通过webpack的DefinePlugin插件来创建全局变量,从而改变环境。参考链接:使用process.env.NODE_ENV的正确姿势
自定义环境变量
发现NODE_ENV会被
next build和next start这两条命令修改的时候,我就决定使用别的环境变量来区别本项目的开发环境与生产环境。

注意,在这里设置的环境变量API是无法在业务代码中直接访问的。如果此时在业务代码中使用process.env.API会得到undefined的值。
因此我在next.config.js处添加了环境变量的设置,将scripts这里设置的API变量传递给Next项目里,如图:

使用方式如下:

这样就成功设置好了环境变量,让项目根据不同环境,请求带上不同的前缀。
next.config.js文件配置示例:
const nextConfig = {
output: "export", // 打包模式
reactStrictMode: true,
images: {
unoptimized: true,
},
env: {
API_PREFIX: process.env.API,
},
// async rewrites() {
// return [
// {
// source: "/api/:path*",
// destination: "http://domain:8000/:path*",
// },
// ];
// }, // 本地调试时使用
};
module.exports = nextConfig;
设置nginx.conf
Nginx的设置没啥特别的,就是根据不同前缀把请求转发到不同服务器上,下面是我用的配置:
server {
listen 80;
server_name localhost;
gzip on;
access_log /var/log/nginx/host.access.log main;
error_log /var/log/nginx/error.log error;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri.html /$uri /index.html;
}
location /dev/ {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_pass http://domain1:8000/; # 开发环境
}
location /prod/ {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $http_host;
proxy_pass http://domain2:8000/; # 生产环境
}
# error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
其中要特别注意try_files $uri $uri.html /$uri /index.html; 这条配置。其他前端项目大部分配置的都是try_files $uri $uri/ /index.html; ,但是Next项目比较特殊,观察它打包后的文件可以发现规律,这里不赘述。
配置Dockerfile
这里用的 Dockerfile也没啥特别的,就是把Next项目编译好的静态文件复制到/usr/share/nginx/html,让Nginx进行静态代理,最后启动Nginx。其中我用了ENV参数来区分前端的两个环境,ENV可以有两个值:dev和prod。
使用—build-arg就能传递参数,示例:
docker build --build-arg ENV=dev -t domain/frontend:test-v0.1 .
完整的Dockerfile配置如下:
FROM node:16-alpine as build
ARG ENV
RUN npm config set registry https://registry.npm.taobao.org \
&& npm i npm -g
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run ${ENV}
FROM nginx:alpine
COPY --from=build /app/out /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
ENTRYPOINT nginx -g "daemon off;"
部署成功
所有部署文件都已经完成了,得到docker镜像后,不管是部署到K8s的集群上面还是自己启动一个docker容器都很简单,在这里就忽略了。最后的部署效果完美地实现了我的目的:开发环境的请求前缀都有/dev,也成功请求到了开发环境的那台后端服务器。

NextJS项目的部署以及多环境的实现的更多相关文章
- java项目部署在服务器环境配置以及命令的编写
在往项目上部署java项目(即打成的jar包),要为相应的项目配置环境变量,即项目运行所需要的jar或其他第三方的jar包,java -cp derivativeAccording.jar:lib/c ...
- Tomcat热部署:Maven项目一键部署到Tomcat服务器 - 支持多环境
参考:Eclipse中的Maven项目一键部署到Tomcat服务器 - 支持多环境部署 命令 debug模式设置关联源码 eclipse --> 项目右键 --> Debug As --& ...
- 项目部署到liunx环境下访问接口返回异常
1.访问接口返回异常 已经连续踩了两次这个坑了.所以记下来了.方便下次搜索! 项目在window下运行正常,无任何异常! 但是部署到liunx环境下的服务器上就有问题 访问静态页面毫无问题,一旦涉及到 ...
- 国产中标麒麟Linux部署dotnet core 环境并运行项目 (三) 部署运行WEB API项目
部署dotnet Core Web API 上一步的文章,是我们公司最核心的一个ORM组件,在中标麒麟系统完成了一个插入数据的任务,这一步是将正式的从dot net framework 迁移到 dot ...
- 国产中标麒麟Linux部署dotnet core 环境并运行项目 (一) 安装dotnet core
背景 根据我之前写的文章 将 Net 项目升级 Core项目经验:(一)迁移Net项目为Net Core\Standard项目,我们将公司内部最核心的ORM框架迁移到net core 上面,并在win ...
- maven项目打包部署到虚拟机测试和生产环境上及查看日志操作
调试通过后提交代码到gitlab,打包部署到相应环境(测试或生产环境)步骤一样1.打包在要打包的项目上右键run as maven clean 清除原来的包,然后run as maven instal ...
- itellij idea导入web项目并部署到tomcat
概述 主要分为项目配置和tomcat配置两大步骤. 一.项目配置 打开idea,选择导入项 选择将要打开的项目路径后,继续选择项目的原本类型(后续引导设置会根据原本的项目类型更新成idea的项目),此 ...
- Greenplum 数据库安装部署(生产环境)
Greenplum 数据库安装部署(生产环境) 硬件配置: 16 台 IBM X3650, 节点配置:CPU 2 * 8core,内存 128GB,硬盘 16 * 900GB,万兆网卡. 万兆交换机. ...
- Eclipse中的Web项目自动部署到Tomcat
原因 很长时间没用Eclipse了,近期由于又要用它做个简单的JSP项目,又要重新学习了,虽然熟悉的很快,但记忆总是很模糊,偶尔犯错,以前很少写博客,现在感觉还是很有必要的,编程中每个人对于犯过的错误 ...
- 项目分布式部署那些事(2):基于OCS(Memcached)的Session共享方案
在不久之前发布了一篇"项目分布式部署那些事(1):ONS消息队列.基于Redis的Session共享,开源共享",因为一些问题我们使用了阿里云的OCS,下面就来简单的介绍和分享下相 ...
随机推荐
- 重新理解RocketMQ Commit Log存储协议
本文作者:李伟,社区里大家叫小伟,Apache RocketMQ Committer,RocketMQ Python客户端项目Owner ,Apache Doris Contributor,腾讯云Ro ...
- SMT贴片加工钢网工艺制作方法
smt贴片加工过程中,首先要进行锡膏印刷,而锡膏印刷的工作原理就是用机器刮刀将锡膏推送到钢网的孔洞中,使锡膏与pcb板的电子元器件接触,为下一步焊接做准备.钢网的作用就是与pcb板焊盘位置固定,使锡膏 ...
- devops|中小公司不要做研发效能度量
我特别反感那些不顾公司现状一上来就想要做研发效能度量的人,尤其是想把研发效能度量当成锤子四处去敲打螺丝钉的人. 没几个人的小公司上来就做研发效能度量,就如同普通人一上来直接问媒婆怎么能娶到迪丽热巴.解 ...
- 信息论之从熵、惊奇到交叉熵、KL散度和互信息
一.熵(PRML) 考虑将A地观测的一个随机变量x,编码后传输到B地. 这个随机变量有8种可能的状态,每个状态都是等可能的.为了把x的值传给接收者,需要传输⼀个3⽐特的消息.注意,这个变量的熵由下式给 ...
- C#中使用CAS实现无锁算法
CAS 的基本概念 CAS(Compare-and-Swap)是一种多线程并发编程中常用的原子操作,用于实现多线程间的同步和互斥访问. 它操作通常包含三个参数:一个内存地址(通常是一个共享变量的地址) ...
- 【Visual Leak Detector】源码编译 VLD 库
说明 使用 VLD 内存泄漏检测工具辅助开发时整理的学习笔记.本篇介绍 VLD 源码的编译.同系列文章目录可见 <内存泄漏检测工具>目录 目录 说明 1. VLD 库的依赖文件 2. 源码 ...
- 简单记录下RestTemplate使用方法
1.设置get方法 ResponseEntity<JSONObject> responseEntity= restTemplate.getForEntity(url,JSONObject. ...
- Git代码提交规范
1. 引言 思想,因人而异,难以重复 写代码时,每个人的习惯是不一样的,所以,引入了代码规范,为了省力,引入了自动格式化代码工具,前端工程中比较典型的自动格式化代码工具如:Prettier · Opi ...
- live555中ts流详细解析
live555中ts流详细解析 该文档主要是对live555源码下testProgs中testMPEG2TransportStreamer服务器端的详细分析.主要分析ts流实现的总体调用流程.(重新整 ...
- 笔记:C++学习之旅---关联容器
笔记:C++学习之旅---关联容器 关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的.与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的. ...