# 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` 即可。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://gb.akanote.cn/cms/part10ssr-xuan-ran-yu-xian-shang-bu-shu.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
