Jacleklm's Blog

博客项目上线部署总结

2020/02/27

前言

经过一番折腾之后项目终于上线了(喜极而泣,坑好多),博客项目部署在 JacleKlm.com,先写一篇文章记录下近期的折腾所得吧。

云服务器

买的腾讯云服务器最便宜的那种,买域名,备案审批

云服务器中,更多-安全组-配置安全组-点连接,可以设置端口的开启及可以访问的人

Linux

Linux 是一个性能稳定的多用户网络操作系统,经常用来跑服务器,eg. Linux + Nginx + MySQL + Node.js

Linux 常见命令

  • Vim(用来打开文件)
    • Vim 下,i 是进入编辑模式;esc:wq 是保存退出,:q 是退出,:q! 是强制退出;
    • Vim 查找。在 normal 模式下按下 / 即可进入查找模式,输入要查找的字符串并按下回车。在查找模式中加入 \c 表示大小写不敏感查找,\C 表示大小写敏感查找,例如: /foo\c
    • Vim 翻页:control+f; control+b
  • 查看开启的端口号
    • netstat -tlnp
  • 查看当前路径
    • pwd [-lp]
  • 查看端口号 show global variables like 'port';
  • 删除
    • rm -rf svn/ 将会删除当前目录下的 svn/ 文件夹及其下所有文件夹,包括文件
    • rm -f /opt/test.txt 将会强制删除 /opt/test.txt 这个文件
  • 解压文件 unzip react-blog.zip
  • 更换 node 版本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cd /usr/local/bin/
// 查看已有软连接:
ll -all
// 删除旧node软连接
rm -rf node
rm -rf npm
rm -rf cnpm
cd ~
// 下载跟本地node版本相同的node
wget https://nodejs.org/dist/v12.3.1/node-v12.3.1-linux-x64.tar.xz
// 解压安装包
tar xvf node-v12.3.1-linux-x64.tar.xz
// 重建软连接
ln -s /root/node-v12.3.1-linux-x64/bin/node /usr/local/bin/node
ln -s /root/node-v12.3.1-linux-x64/bin/npm /usr/local/bin/npm
sudo ln -s /root/node-v12.3.1-linux-x64/bin/cnpm /usr/local/bin/cnpm

更多常见命令详见 让你牛 B 加身的前端必会 Linux 命令
更多 Linux 教程也可见 Linux 教程-菜鸟教程

安装 cnpm

  • Linux 安装 cnpm 后 npm install -g cnpm --registry=https://registry.npm.taobao.org
  • sudo 创建软连接 sudo ln -s /root/node-v<版本号>-linux-x64/bin/cnpm /usr/local/bin/cnpm

从 Mac 本地拷贝文件到云服务器

scp

eg. 在本地命令行执行 scp -r /Users/chenjunjia/React/react_blog/admin.zip root@xx.xx.xx.xx:/root/blog ,再输入服务器密码即可

sftp

参见教程
eg. Put React/react_blog/react-blog.zip /root/blog 。注意这里的 /User/chenjunjia/ 就被省略了(至少我的 Mac 中是这样)

Nginx

Nginx 是一款轻量级的 HTTP 服务器,采用事件驱动的异步非阻塞处理方式框架,这让其具有极好的 IO 性能,时常用于服务端的反向代理和负载均衡

目前本项目的部署其实没用到 Nginx

Nginx 常见命令

  • 启动
    • 直接法:nignx 。会没有任何返回信息,这是成功状态。此时用 ps aux | grep nginx 看 nginx 的启动信息
    • 用通用的 Linux 命令:systemctl start nginx.service
  • 关闭
    • 最常用:nginx -s quit
    • 不常用的关闭(关闭效果等级从轻到重):nginx -s stopkillall nginx, systemctl stop nginx.service
  • 重启(修改 Nginx 文件后都要重启)
    • nginx -s reload
    • systemctl restart nginx.service

Nginx 基础配置文件

配置文件 /etc/nginx/nginx.config ,用 vim 打开后看内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 运行用户,默认即是nginx,可以不进行设置
user nginx;
# Nginx进程,一般设置为和CPU核数一样
worker_processes 1;
# 错误日志存放目录
error_log /var/log/nginx/error.log warn;
# 进程pid存放位置
pid /var/run/nginx.pid;

events {
worker_connections 1024; # 单个后台进程的最大并发数
}

http {
include /etc/nginx/mime.types; # 文件扩展名与类型映射表
default_type application/octet-stream; # 默认文件类型
#设置日志模式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main; # nginx访问日志存放位置

sendfile on; # 开启高效传输模式
#tcp_nopush on; # 减少网络报文段的数量

keepalive_timeout 65; # 保持连接的时间,也叫超时时间

#gzip on; # 开启gzip压缩

include /etc/nginx/conf.d/*.conf; #包含的子配置项位置和文件

用 vim 打开 include 的子配置项文件 /etc/nginx/conf.d/default.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server {
listen 80; # 配置监听端口
server_name localhost; //配置域名

#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;

location / {
root /usr/share/nginx/html; # 服务默认启动目录
index index.html index.htm; # 默认访问文件
}

#error_page 404 /404.html; # 配置404页面

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html; #错误状态码的显示页面。现在是这几种错误都是用现实这个html文件
location = /50x.html {
root /usr/share/nginx/html;
}
......
}

cd 到 /usr/share/nginx/html 默认文件夹,对 index.html 默认文件编辑并保存,然后用 nginx 命令即能启动服务器。访问 ip 地址就能看到内容了

同理编辑 /usr/share/nginx/html/404.html 是 404 时显示的页面;也可以让 404 指向其他页面:error_page 404 http://github.com;

Nginx 实现访问控制

nginx 的指令是谁写在前面就谁先生效(如果有冲突)

只允许某个主机进行访问

1
2
3
4
location / { // 这里的 / 是全部的意思
allow xx.xx.xx.xx; // // 允许访问的ip
deny all; // 也可以是某个ip
}

这里的 / 是全部的意思;改成 =/img 则是网站下的 img 目录;也可以用正则,~\.php$

Ngingx 设置虚拟机

通过设置虚拟主机,一台云服务器也能同时跑好几个 Web 服务器。配置虚拟主机可以基于端口号,基于 IP,基于域名。最常用的是基于域名设置虚拟机
都是改 /etc/nginx/conf.d/default.config 配置文件

基于端口号

1
2
3
4
5
6
server{
listen 8001;
server_name localhost; // localhost:8001端口新开虚拟机
root /usr/share/nginx/html/html8001;
index index.html;
}

编辑 /usr/share/nginx/html/html8001 下的 index.html ,即可访问 8001 端口了

基于端 IP

1
2
3
4
5
6
server{
listen 80;
server_name xx.xx.xx.xx; // 某新ip
root /usr/share/nginx/html/html8001;
index index.html;
}

基于域名(最常用)

1
2
3
4
5
6
7
8
server{
listen 80;
server_name xxx.com; // 如果有多个域名就可以配多个
location / {
root /usr/share/nginx/html/html8001;
index index.html;
}
}

Nginx 实现反向代理

反向代理

正向代理(为客户端做代理):普通的 proxy 代理,把我们不让访问的服务器的网页请求,代理到一个可以访问该网站的代理服务器上来,一般叫做 proxy 服务器,再转发给客户。eg. 翻墙(你没有权限,但是 proxy 服务器有权限)

反向代理(为服务器做代理):反向代理跟代理正好相反(需要说明的是,现在基本所有的大型网站的页面都是用了反向代理),客户端发送的请求,想要访问 server 服务器上的内容。发送的内容被发送到代理服务器上,这个代理服务器再把请求发送到自己设置好的内部服务器上,而用户真实想获得的内容就在这些设置好的服务器上。

反向代理的用途和好处

  • 安全性:正向代理的客户端能够在隐藏自身信息的同时访问任意网站,这个给网络安全代理了极大的威胁。因此,我们必须把服务器保护起来,使用反向代理客户端用户只能通过外来网来访问代理服务器,并且用户并不知道自己访问的真实服务器是那一台,可以很好的提供安全保护。
  • 功能性:反向代理的主要用途是为多个服务器提供负债均衡、缓存等功能。负载均衡就是一个网站的内容被部署在若干服务器上,可以把这些机子看成一个集群,那 Nginx 可以将接收到的客户端请求“均匀地”分配到这个集群中所有的服务器上,从而实现服务器压力的平均分配。

配置方法

1
2
3
4
5
6
7
server{ // 访问 nginx2.jspang.com 反向代理到 jspang.com 这个网站。所以当我们访问nginx2.jspang.com的时候呈现的是jspang.com的内容
listen 80;
server_name nginx2.jspang.com;
location / {
proxy_pass http://jspang.com;
}
}

Nginx 适配 PC 或移动设备

大型网站,eg. 淘宝和京东的网站,根据 PC 端或移动端会有不同的站点,而不是用自适应布局。
用 Nginx 的 $http_user_agent 可以获取到客户端的 userAgent ,进而展示不同的页面给用户

Linux 中搭建 MYSQL

安装,搜教程

Linux 操作数据库命令大全(结尾一定要带分号!)

参考自博客 1博客 2

  • 开启 mysql service mysqld startmysql -u root
  • 关闭 mysql> exit;
  • 进入 mysql 后,使用 SHOW 语句找出在服务器上当前存在什么数据库 mysql> SHOW DATABASES;
  • 创建一个数据库 test mysql> CREATE DATABASE test character set utf8;
  • 选择你所创建的数据库 mysql> USE test;
  • 使用 SHOW 语句看数据库有几个表 mysql> SHOW TABLES;
  • 创建一个表 CREATE TABLE mytable (name VARCHAR(20), sex CHAR(1),birth DATE, birthaddr VARCHAR(20));
    CREATE TABLE type (
    id int(10) unsigned NOT NULL auto_increment,
    flag_deleted enum(‘Y’,’N’) character set utf8 NOT NULL default ‘N’,
    flag_type int(5) NOT NULL default ‘0’,
    type_name varchar(50) character set utf8 NOT NULL default ‘’,
    PRIMARY KEY (id)
    ) DEFAULT CHARSET=utf8;
  • 显示表的结构 mysql> DESCRIBE mytable;
  • 用 SELECT 命令来查看表中的数据 mysql> select * from mytable;
  • 给表加入数据 mysql> insert into mytable values (′jacle′,′m′,′1996-02-04′,′china′);
    insert into test values (2,’jacle2’);
  • 用文本方式将数据装入一个数据库。创建一个文本文件“mysql.txt”,每行包含一个记录,用定位符(tab)把值分开,并且以在 CREATE TABLE 语句中列出的列次序给出,例如
    abccs f 1977-07-07 china  
    mary f 1978-12-12 usa
    tom m 1970-09-02 usa
    使用下面命令将文本文件“mytable.txt”装载到 mytable 表中:
    mysql> LOAD DATA LOCAL INFILE "/data/mytable.txt” INTO TABLE mytable;
  • 修改表结构,更详见 博客 3,其中添加字段是 ALTER TABLE <表名> ADD <字段名称> <字段定义>
  • 删除表 DROP TABLE table_name ;
  • 查看表的编码 show create table <表名>;
  • 修改数据库成 utf8 的 mysql> alter database name character set utf8;
  • 修改表默认用 utf8 mysql> alter table type character set utf8;
  • 修改字段用 utf8 mysql> alter table type modify type_name varchar(50) CHARACTER SET utf8;
  • 更新数据 UPDATE <表名> SET id=2 WHERE type_id=2;

一些 bug

mysql 的 char,varchar,text 类型的区别总结
Linux 中 mysql 表无法写入中文,解决方法是 varchar 类型建议用 utf-8

Linux 中搭建 Node.js ,npm 和 PM2

安装方法自行谷歌

pm2

pm2 是一个带有负载均衡功能的应用进程管理器,也可以用来做进程守护。pm2 简易使用手册

常用命令

  • 查看进程 pm2 list
  • 停止所有 pm2 stop all
  • 运行某个 node 文件 pm2 start xxx.js
  • 运行项目 pm2 start npm —- run start/dev
  • 重启 pm2 restart XXX
  • 停止 pm2 stop XXX
  • 删除 pm2 delete XXX
  • 查看某个进程/应用具体情况 pm2 describe Travel
  • 查看进程/应用的资源消耗情况 pm2 monit
  • 查看所有日志 pm2 logs (Travel)
  • 查看 7001 端口的进程 (PID 就是进程 id)lsof -i:7001
  • 关闭进程 kill -9 <进程id>

pm2 项目管理

1
2
3
4
5
6
7
cd <项目目录>
// 在项目目录生成pm2配置文件:ecosystem.config.js。改该文件的name属性为自定义进程名字,script属性为react项目npm run start时执行的脚本(需要先npm run eject才会出现这个脚本)
pm2 ecosystem
// 执行进程
pm2 start ecosystem.config.js
// 查看执行的进程,发现会有自定义名字的进程
pm2 list

部署流程

每次更改项目后应该先 build,再用 pm2 start;测试的时候应该用 dev

前台

对于博客项目,前台是 Next.js 项目,拷贝之后先 build ,然后再 pm2 start npm — run start 就可以了
http 默认是 80 端口,可以把前台项目改成 80 端口;其次,你还要在安全组开放相关的端口才能成功访问的(其实我没做这一步)

中台

中台是 Egg.js 项目,直接 npm run start 就行(自带进程守护)。中台连接云服务器数据库方法暂时是把 config.default.js 改成下面如下配置,可以通过 IP 或者域名+端口号访问接口

1
2
3
4
5
6
config.cluter = {
listen: {
port: 8000,
hostname: '0.0.0.0' // 其实就是localhost
}
}

后台

后台是 React 项目,是直接用 pm2 进行管理直接 start

踩坑集合

跨域

  • 前后台项目中请求应该以服务器 ip 地址为准,而不是 localhost
  • 数据中台的跨域设置是参考该贴,最后配置如下
1
2
3
4
5
6
7
8
9
10
11
// 如果只想让 domainWhiteList 的可以跨域,那就不用配置 origin
config.security = {
csrf: { enable: false },
domainWhiteList: ['*']
}
// 如果你要用 origin: '*' 又想带 withCredentials,配置改成这样
config.cors = {
credentials: true,
origin: ctx => ctx.get('origin'),
allowMethods: 'GET, HEAD, PUT, POST, DELETE, PATCH, OPTIONS'
}

修改项目默认接口

  • React 项目修改默认接口:node_modules 文件夹里的可以看到 react-scripts 文件夹,在 start.js 里可以找到修改端口的代码。直接搜索 ||
  • Next 项目改默认端口是直接在script命令最后加 -p <端口号>

React 项目 TypeError [ERR_INVALID_ARG_TYPE]: The “path” argument must be of type string. Received type undefined

react-scripts 版本问题,升级到 3.4.0。果然成功了!!!哭了!

参考文章
让你牛 B 加身的前端必会 Linux 命令-奇舞团
Linux 教程-菜鸟教程
一个前端必会的 Nginx 免费教程-技术胖
pm2 简易使用手册

CATALOG
  1. 1. 前言
  2. 2. 云服务器
  3. 3. Linux
    1. 3.1. Linux 常见命令
    2. 3.2. 安装 cnpm
    3. 3.3. 从 Mac 本地拷贝文件到云服务器
      1. 3.3.1. scp
      2. 3.3.2. sftp
  4. 4. Nginx
    1. 4.1. Nginx 常见命令
    2. 4.2. Nginx 基础配置文件
    3. 4.3. Nginx 实现访问控制
    4. 4.4. Ngingx 设置虚拟机
      1. 4.4.1. 基于端口号
      2. 4.4.2. 基于端 IP
      3. 4.4.3. 基于域名(最常用)
    5. 4.5. Nginx 实现反向代理
      1. 4.5.1. 反向代理
      2. 4.5.2. 反向代理的用途和好处
      3. 4.5.3. 配置方法
    6. 4.6. Nginx 适配 PC 或移动设备
  5. 5. Linux 中搭建 MYSQL
    1. 5.1. Linux 操作数据库命令大全(结尾一定要带分号!)
    2. 5.2. 一些 bug
  6. 6. Linux 中搭建 Node.js ,npm 和 PM2
    1. 6.1. pm2
      1. 6.1.1. 常用命令
      2. 6.1.2. pm2 项目管理
  7. 7. 部署流程
    1. 7.1. 前台
    2. 7.2. 中台
    3. 7.3. 后台
  8. 8. 踩坑集合
    1. 8.1. 跨域
    2. 8.2. 修改项目默认接口
    3. 8.3. React 项目 TypeError [ERR_INVALID_ARG_TYPE]: The “path” argument must be of type string. Received type undefined