Next.js 项目部署到云服务器

最近在学习 Next.js, 搭建了个简单的个人博客,地址:大胖猫,本篇文章详细记录了完整的部署过程,包括从零配置云服务器、使用 GitHub Actions 自动化部署、nginx 反向代理、https 配置等。

不同于传统的静态文件部署,Next.js 是运行在 node.js 上的,项目部署一般有三种选择:

  • 部署到 Vercel,但因为网络关系,国内无法访问
  • 使用 Docker 部署
  • 部署到自己的服务器

本篇文章选择了最后一种方式,个人用的是腾讯云服务器,接下来是完整的配置过程。

准备工作

在有了云服务器之后,首先安装操作系统,我选择的是 CentOS Stream 9。

接下来使用 dnf 包管理器来安装需要的软件,因此在连接到服务器之后,先更新一下 dnf:

bash 复制代码
sudo dnf update

环境安装

要用到的软件很简单,只有三个:

  • Node.js:用来运行 Next.js 项目
  • nginx:做为反向代理服务器
  • git:用来拉取项目代码

1. 安装 Node.js

CentOS 安装 Node.js 很简单,可以参考 Node.js 安装文档

首先查看可用的版本:

bash 复制代码
dnf module list nodejs

之后选择一个版本安装,我这里安装了 Node.js v20.

bash 复制代码
dnf module install nodejs:20/common

安装完成之后,运行 node -v 看到版本号输出,说明安装成功。

2. 安装 nginx

接下来安装 nginx,只需要按照官方文档操作即可。

  1. 安装和更新 EPEL 仓库:
bash 复制代码
sudo dnf install epel-release

sudo dnf update
  1. 安装 nginx
bash 复制代码
sudo dnf install nginx
  1. 查看版本,输出版本号,说明安装成功
bash 复制代码
sudo nginx -v

nginx 默认的配置路径在 /etc/nginx/nginx.conf,稍后我们会用到。

3. 安装 git

接下来安装 git,用来从 GitHub 拉取项目代码。

bash 复制代码
sudo dnf install git

安装完成之后查看版本:

bash 复制代码
git --version

如果输出类似于 git version 2.43.0 说明安装成功。

安装完成之后配置用户信息:

bash 复制代码
git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"

之后需要配置 SSH key。

bash 复制代码
# 1. 生成新的 SSH 密钥对
ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

# 2. 启动 SSH 代理并添加 SSH 密钥
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa

# 3. 复制公钥内容
cat ~/.ssh/id_rsa.pub

到 GitHub setting 页面添加复制的 SSH key。

创建项目

接下来创建项目。为了演示简单,我使用 create-next-app 创建了一个空项目:

bash 复制代码
sudo npx create-next-app@latest

接下来会提示你输入项目名,之后一路回车选择默认选项就可以。创建项目之后推送到 GitHub。

推送到 GitHub 之后登录服务器,到 /usr/www 目录(按个人喜好,随便某个目录,用来拉取项目文件),将项目 clone 下来。

之后到项目的目录,安装依赖、打包、启动项目。

bash 复制代码
npm install
npm run build
npm run start

现在应该可以在控制台看到启动成功,就像平时在本地启动项目一样。但现在是访问不到的,因为云服务器默认不会开启 3000 端口。我们需要到云服务器的防火墙配置一下,开启 3000 端口,具体的添加方式取决于使用的云服务商。之后用浏览器访问一下(xxx 是你的公网 IP)项目地址:

bash 复制代码
http://111.xxx.xx.xxx:3000

已经可以访问到项目页面了!

自动化部署

到现在为止,我们通过手动克隆代码、手动打包并启动的方式把项目在云服务器跑起来了。但我们肯定不希望每次有代码改动都登录服务器重新操作一遍。接下来使用 PM2 和 GitHub actions 来自动化这个过程。

安装 PM2

PM2(Process Manager 2)是一个用于管理和监控 Node.js 应用程序的进程管理器。它简化了在生产环境中部署、运行和维护 Node.js 应用的过程。

我们将通过 PM2 来启动我们的应用。

首先安装 PM2:

bash 复制代码
npm install pm2@latest -g

安装完成之后可以通过 pm2 -version 查看版本,之后运行以下命令启动项目:

bash 复制代码
pm2 start npm --name "your-app-name" -- start

会看到类似上图中的输出,继续通过 IP 加端口号访问应用,应用照常运行。

配置 GitHub Actions

GitHub Actions 是 GitHub 提供的一项功能,用于自动化软件开发工作流程。它允许我们在 GitHub 上设置和执行自定义的 CI/CD(持续集成/持续部署)工作流。通过 GitHub Actions,我们可以在代码存储库中设置各种自动化任务,例如构建、测试、部署、发布和其他自定义工作流程。

打开代码仓库页面,点击 Settings -> Sectets and variables -> Actions -> New repository sectet

依次添加以下变量:

Name:SERVER_HOST / Secret:服务器公网 IP
Name:SERVER_USERNAME / Secret:服务器用户名
Name:SERVER_PASSWORD / Secret:服务器密码
Name:SERVER_PORT / Secret:服务器端口

在代码仓库页面点击 Actions -> set up a workflow yourself

在编辑窗口写入以下代码:

yaml 复制代码
name: Build and Deploy # 为GitHub Actions工作流命名

on:
  push:
    branches:
      - main # 当推送到main分支时触发工作流

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest # 使用Ubuntu操作系统作为运行环境

    steps:
      - name: Checkout # 步骤1:从仓库检出代码
        uses: actions/checkout@v3
        with:
          persist-credentials: false # 不保留凭据

      - name: Build and Deploy # 步骤2:构建和部署
        uses: appleboy/ssh-action@master # 使用SSH Action插件
        with:
          host: ${{ secrets.SERVER_HOST }} # 从GitHub Secrets中获取服务器主机名
          username: ${{ secrets.SERVER_USERNAME }} # 从GitHub Secrets中获取服务器用户名
          password: ${{ secrets.SERVER_PASSWORD }} # 从GitHub Secrets中获取服务器密码
          port: ${{ secrets.SERVER_PORT }} # 从GitHub Secrets中获取服务器端口号
          script: |
            cd /usr/www/xxx  # 切换到项目目录
            git pull  # 从远程仓库拉取最新代码
            npm install  # 安装项目依赖
            npm run build  # 执行构建脚本
            pm2 restart dapangmao --interpreter none -- start  # 使用PM2重启应用程序

注意 workflow 中最后一行代码:

bash 复制代码
pm2 restart dapangmao --interpreter none -- start

因为我们已经在服务器通过 pm2 启动了项目了,因此这里用的是 restart,即使应用程序已经在运行,也会停止当前的进程并重新启动。

记得把 branches 和项目目录替换为你自己的值,点击保存。保存之后 GitHub 就会按照我们写的 workflow 开始拉取代码、构建并重启项目。

要查看构建进度的话,可以访问 https://github.com/<username>/<project-name>/actions 页面,会列出所有的 workflow。

如果显示构建成功,仍然可以通过端口号 + ip 的方式访问项目。

为了查看项目确实是通过 GitHub Actions 自动部署的,可以编辑 app/page.tsx 中的 html 并提交,等新的 workflow 构建完成之后,访问页面看修改是否生效。

nginx 配置

到现在为止,我们实现了代码自动部署,并且可以通过 IP 加端口号的方式访问到页面。如果你不光有云服务器,也有自己的域名,也备案了。可以继续往下看,我们来配置 nginx。

上文也有提到过,nginx 默认的配置位于 etc/nginx/nginx.conf,打开并编辑这个文件,将默认的 server 部分替换为以下内容,代理请求到本地运行的 Next.js 项目。

ini 复制代码
server {
    listen       80;
    listen       [::]:80;
    server_name  www.your_domain.com your_domain.com;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

保存之后重启 nginx:

bash 复制代码
sudo systemctl restart nginx

OK,现在可以通过域名访问项目了,访问 http://your_domain.com/,网站访问正常。

配置 https

最后我们还需要配置 https,首先申请免费的 https 证书。这一步操作可能各大云服务商有些差异,本文还是以腾讯云为例。

首先前往控制台 申请免费 https 证书,按照提示操作就行。

申请完成之后点击右侧的下载:

选择 nginx 下载:

下载完成之后,在服务器的 etc/nginx 目录下创建一个 ssl 目录,将下载的 your_domain.com.keyyour_domain.com_bundle.crt 两个文件拷贝进去(可以借助各种 ftp 工具)。

修改 nginx 配置文件:

ini 复制代码
server {
    listen       80;
    listen       [::]:80;
    server_name  www.your_domain.com your_domain.com;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        return 301 https://$host$request_uri;
    }
}

# Settings for a TLS enabled server.

server {
    listen       443 ssl http2;
    listen       [::]:443 ssl http2;
    server_name  www.your_domain.com your_domain.com;
    root         /usr/share/nginx/html;

    ssl_certificate "/etc/nginx/ssl/your_domain.com_bundle.crt";
    ssl_certificate_key "/etc//nginx/ssl/your_domain.com.key";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers PROFILE=SYSTEM;
    ssl_prefer_server_ciphers on;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;

    location / {
        proxy_pass http://127.0.0.1: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;
    }
}

上面的配置中,我们不光添加了 https 部分的配置,也把原来的 http 重定向到了 https 地址。

保存之后重启 nginx:

bash 复制代码
sudo systemctl restart nginx

访问 https://your_domain.com/,会发现我们的网站已经是 https 加密访问了,OK,大功告成!

总结

第一次在云服务器部署 Next.js 项目,个人感觉这种方式还算简单,如果有任何问题或者更好的部署方式欢迎大家评论。

相关推荐
敲啊敲952726 分钟前
5.npm包
前端·npm·node.js
brrdg_sefg40 分钟前
Rust 在前端基建中的使用
前端·rust·状态模式
m0_748230941 小时前
Rust赋能前端: 纯血前端将 Table 导出 Excel
前端·rust·excel
qq_589568101 小时前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
黑客老陈2 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
正小安2 小时前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite
暴富的Tdy3 小时前
【CryptoJS库AES加密】
前端·javascript·vue.js
neeef_se3 小时前
Vue中使用a标签下载静态资源文件(比如excel、pdf等),纯前端操作
前端·vue.js·excel
m0_748235613 小时前
web 渗透学习指南——初学者防入狱篇
前端