> For the complete documentation index, see [llms.txt](https://gb.akanote.cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gb.akanote.cn/cms/part10ssr-xuan-ran-yu-xian-shang-bu-shu.md).

# Part10-SSR渲染与线上部署

## 一、Koa2+MySQL项目线上部署

### 1、上传与安装依赖

#### a、上传项目并安装项目依赖

先将你的项目（除了 `node_modules`）放到服务器指定的位置，例如我存放的位置：

```shell
# 我的项目名称就叫cms-server
/usr/local/html/cms-server
```

然后通过ssh连接服务器，进入该目录，执行 `npm i` 安装依赖包。

> 这里很有可能会安装失败，原因是被package-lock.json影响。解决方案：
>
> ```shell
> $ rm package-lock.json
> # 方法一：
> # 如果没安装过yarn就全局安装一下
> $ npm i yarn -g
> $ yarn
>
> # 方法二：
> # 如果不愿意使用yarn，也可以用cnpm淘宝镜像
> $ npm install -g cnpm --registry=https://registry.npm.taobao.org
> $ cnpm i
> ```

安装完依赖包之后，安装压缩与解压工具：

```shell
# ubuntu新系统已自带解压与压缩工具，这一步可不做
$ sudo apt-get install unzip zip
```

#### b、ubuntu卸载MySQL

首先在终端中查看MySQL的依赖项：

```shell
$ dpkg --list|grep mysql
```

卸载：

```shell
$ sudo apt-get remove mysql-common
$ sudo apt-get autoremove --purge mysql-server-5.7
```

清除残留数据：

```shell
$ dpkg -l|grep ^rc|awk '{print$2}'|sudo xargs dpkg -P
```

再次查看MySQL的剩余依赖项：

```shell
$ dpkg --list|grep mysql
```

继续删除剩余依赖项：

```shell
$ sudo apt-get autoremove --purge mysql-apt-config
```

至此已经没有了MySQL的依赖项，彻底删除！

#### c、ubuntu安装与配置MySQL

**\* Ubuntu换源**

备份原来的sorce文件：

```shell
$ cd /etc/apt
$ sudo cp sources.list sources.list.old
```

清空并编辑sources.list内容：

```shell
$ echo "" > sources.list
$ vim sources.list
```

写入一个这里选择清华镜像源：

```shell
# 清华镜像源
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ xenial main restricted universe multiverse
```

**\* 更新镜像源与软件**

```shell
# 更新镜像源
sudo apt-get update
# 更新软件
sudo apt-get upgrade
```

#### d、ubuntu安装mysql

```shell
# 安装mysql5.7服务端，安装时会提示输入密码，暂时设置为123456
$ sudo apt-get install mysql-server-5.7
```

出现下图选Y：

[![image-20211231204112300](https://tva1.sinaimg.cn/large/008i3skNgy1gxxat4dje4j30v602edg5.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxat4dje4j30v602edg5.jpg)

```shell
# 继续安装mysql5.7客户端
$ sudo apt-get install mysql-client-5.7
```

接下来查看mysql版本：

```shell
# 查看mysql版本
$ mysql -V
# 查看mysql服务
$ netstat -tap | grep mysql
```

会看到下图代表完全安装成功：

[![image-20211231204749492](https://tva1.sinaimg.cn/large/008i3skNgy1gxxazyw9lqj31f404sq3y.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxazyw9lqj31f404sq3y.jpg)

#### e、忘记密码方案【备用】

```shell
# 停止mysql服务
$ sudo service mysql stop

# 修改MySQL的登录设置，暂时不校验登陆密码
$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf

# 将[mysqld]下的“skip-external-locking”注释掉
# 添加 “skip-grant-tables” 然后保存退出
例如：
================================================
[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
#skip-external-locking
skip-grant-tables
=================================================

# 重启mysql数据库
$ sudo service mysql restart

# 免密登陆mysql数据库
$ mysql -u root mysql

# 修改root密码
$ update mysql.user set authentication_string=password('123456') where user='root';

# 刷新生效
flush privileges;

# 还原MySQL的登录设置
# 将[mysqld]下添加的“skip-grant-tables” 删除
# 将“skip-external-locking”的注释放开然后保存退出
sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
例如：
================================================
[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
=================================================

# 重启mysql数据库
sudo service mysql restart

# 使用新密码登陆mysql
mysql -u用户名 -p密码
# 例如： 
mysql -uroot -p123456
```

#### f、mysql启动停止命令【备用】

```shell
查看mysql运行状态：sudo service mysql status
运行mysql：			 sudo service mysql start
结束mysql：			 sudo service mysql stop
取消开机启动：			sudo update-rc.d -f mysql remove
```

### 2、pm2部署

先解释一下什么是pm2：

简单点说就是让你不需要像执行 `node app.js` 一样，必须一直保持终端开启，而是可以在你退出命令行界面时，依然将你的项目运行着。

#### a、pm2安装

```shell
# 全局安装pm2
$ npm install pm2 -g
# 查看pm2列表
$ pm2 ls
# 运行项目
$ cd /usr/local/html/cms-server
$ pm2 start app.js --name cms-server --watch
# 保存pm2列表
$ pm2 save
# 设置pm2开机自启动
$ pm2 startup					# 禁止的话是pm2 unstartup
```

pm2运行出来的列表如图：

[![image-20220101102913635](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyqmxornj326a06sdhn.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyqmxornj326a06sdhn.jpg)

停止或开启该服务可以：

[![image-20220101103047382](https://tva1.sinaimg.cn/large/008i3skNgy1gxxys9loxpj32720jkafa.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxys9loxpj32720jkafa.jpg)

#### b、配置安全组

例如你项目名为cms-server，端口为6688，那么就需要到实例的安全组中：

[![image-20220101093357386](https://tva1.sinaimg.cn/large/008i3skNgy1gxxx54hyzfj31xo0a4wga.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxx54hyzfj31xo0a4wga.jpg)

#### c、访问IP+端口

例如：我的IP为8.130.20.212，端口号为6688，那么我的访问方式应为：[8.130.20.212:6688](https://github.com/Macharf/aka-note/blob/main/note/cms/8.130.20.212:6688)，这也是我整个后端项目的根路径。

### 3、MySQL线上配置

#### a、连接本地数据库

目前我们只能访问根路径，因为其他路径基本都需要请求并访问数据库读取数据。因此我们需要把电脑本机的数据库搬运到服务器上。打开navicat，连接本地数据库：

[![image-20220101100230256](https://tva1.sinaimg.cn/large/008i3skNgy1gxxxyu0atuj31d60u0di3.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxxyu0atuj31d60u0di3.jpg)

#### b、连接远程数据库

我们采用ssh连接：

[![image-20220101100958959](https://tva1.sinaimg.cn/large/008i3skNgy1gxxy6m16p6j31da0u043j.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxy6m16p6j31da0u043j.jpg)

#### c、创建远程数据库

右键并新建数据库：

[![image-20220101101800372](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyeylxb6j31d90u0jum.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyeylxb6j31d90u0jum.jpg)

新建后就会出现：

[![image-20220101101853229](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyfvshwgj31d20u076d.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyfvshwgj31d20u076d.jpg)

#### d、数据传输

点击顶部工具栏，`工具 - 数据传输`：

[![image-20220101102032579](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyhlkvs9j30y30u0tau.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyhlkvs9j30y30u0tau.jpg)

点击 `下一步`：

[![image-20220101102106225](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyi6m3xtj30y30u0jta.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyi6m3xtj30y30u0jta.jpg)

选择 `开始`，传输完成后就会看到：

[![image-20220101102130989](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyim2o1lj30y30u041j.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyim2o1lj30y30u041j.jpg)

这时候点击 `关闭`，再打开远程数据库的表，就会发现所有数据已经迁移：

[![image-20220101102228734](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyjm606uj31dc0u0mzs.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxyjm606uj31dc0u0mzs.jpg)

此时，我们完成了将本机数据库迁移至服务器的数据库，大功告成！

此时假设你的后端路由：`8.130.20.212:6688/web/home/banner` 可以返回首页banner数据，那么你将立刻看到：

[![image-20220101102616941](https://tva1.sinaimg.cn/large/008i3skNgy1gxxynkk7vpj32la0oc78x.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxxynkk7vpj32la0oc78x.jpg)

那么，至此，服务端部署全部完成！

### 4、持续化部署【扩展】

然而，如果项目需要频繁修改，并且实时查看线上环境，那可能就需要频繁打包并上传，这一点非常麻烦。有没有什么更好的解决方案？答案是有的：

## 二、 Nuxt项目线上部署

### 1、本地运行项目

#### a、先给 `package.json` 中添加：

```json
"config": {
  "nuxt": {
    "host": "localhost",
    "port": "8765"
  }
}
```

#### b、命令行执行

```shell
$ npm run dev
```

### 2、项目打包

所有图片的引入改为require的形式。

#### a、`nuxt.config.js` 中：

```js
server: {
 port: 8765, // default: 3000
 host: '私网IP', // default: localhost (推荐)
},
    
    
router: {
  // base: "/"
},
```

#### b、`package.json` 中：

```json
{
  "script": {
    "serve": "pm2 start npm --name cms-web -- run start"
  }
}
```

#### c、命令行执行客户端打包：

```shell
$ npm run build
```

#### d、上传项目到服务器

把除了以下文件(夹)的所有内容都放到服务器任意指定的目录：

> **.git** / **dist** / **.gitignore** / **package-lock.json** / **yarn.lock**

#### e、安装依赖并打包

服务器进入该目录，再次安装依赖并打包

```shell
$ npm install
$ npm run build
```

如果安装过程中总是自动出现 `package-lock.json`，可以先做这一步设置：

```shell
$ npm config set package-lock false
```

#### f、pm2运行项目

首先确定pm2已经安装，未安装请参考nginx教程。

```shell
# 项目目录中：
$ npm run serve
```

### 3、Nginx配置

#### a、修改配置

vim你的 `nginx.conf`：

```nginx
http {
    upstream nuxt {
        server localhost:8765;	# 项目中nuxt.config.js怎么写，这里就怎么写
        keepalive 64;
    } 

    server {
        listen 80;
        server_name codesohigh.com;
        location /cms-web {
            proxy_pass http://nuxt;
        }
    }
}
```

#### b、配置安全组

[![image-20211213115112974](https://tva1.sinaimg.cn/large/008i3skNgy1gxdg0eqvkoj314q06ft9b.jpg)](https://tva1.sinaimg.cn/large/008i3skNgy1gxdg0eqvkoj314q06ft9b.jpg)

#### c、访问

浏览器访问 `http://codesohigh.com/cms-web` 即可。
