部署 vue(前端) 和 node(后端) 到线上简单demo

一.准备vps和域名.

二.宝塔面板的使用.

三.准备一个demo,本地调通后,上传至服务器

一.准备vps和域名.

由于域名的缘故,所以都不选国内的.
1.在vps上安装centos系统.

安装centos

记住vps的ip地址,密码和端口.
保存好这个数据.
机器配置:
RAM:512MB,大小:10GB。

2.购买配置域名
域名是godaddy的.
购买后,配置DNS解析即可.


配置DNS

这里需要添加2条
类型选A,姓名填@,值填ip地址.
A @ 67.xxx.xxx.xxx
类型选CNAME,姓名填www,值填域名+.(域名为xxxxx.xx,填入xxxxx.xx.)
CNAME www xxxxx.xx.

通过ping 域名,来检查DNS配置是否正确,ping域名会得到得到从ip返回的信息

ping xxx.xx

二.宝塔面板的使用.

下面通过宝塔面板一键安装环境.
https://www.bt.cn/new/index.html

一键安装

填上购买的vps的ip,端口和密码数据.SSH账号一般默认为root,无需修改.


安装默认推荐

安装中

安装完会显示
面板地址,用户名和密码这3个数据.
保存好这个数据.(我一般习惯通过notepad或有道笔记去保存一些数据)

三.准备一个demo,本地调通后,上传至服务器

1.准备一个简单的前端和后端demo.
新建OnlineDeployment,新建Server存放后台源码.
先创建后台项目源码.

cd Server
//初始化
npm init -y
自动生成package.json

创建app.js.

const express = require('express')

// 创建 express 应用
const app = express()

// 监听 / 路径的 get 请求
app.get('/', function(req, res) {
res.send('hello node')
})
// 使 express 监听 5000 端口号发起的 http 请求
const server = app.listen(5000, function() {
const { address, port } = server.address()
console.log('Http Server is running on http://%s:%s', address, port)
})

安装express依赖,使用npm或根据webstorm提示安装.

npm i -S express

使用

 node app.js

启动node项目.


启动node项目

访问 http://localhost:5000/
会显示hello node

创建Vue项目.
package.json文件如下所示.

{
  "name": "client",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "axios": "^1.2.3",
    "core-js": "^3.6.5",
    "vue": "^2.6.11"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.13",
    "@vue/cli-plugin-eslint": "~4.5.13",
    "@vue/cli-service": "~4.5.13",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^6.2.2",
    "vue-template-compiler": "^2.6.11"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "parserOptions": {
      "parser": "babel-eslint"
    },
    "rules": {}
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

修改App.vue.

<template>
  <div id="app">
    <button @click="test">NodeTest</button>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'App',
  components: {

  },
  methods:{
    test() {
      axios
          // http://localhost:5000
          .get('http://localhost:5000')
          .then((res) => {
            console.log(res)
          })
          .catch((err) => {
            console.log(err)
          })
    }
  }
}
</script>

运行serve


run serve

点击按钮后,打印数据hello node.


本地调试ok后,就可以上传至服务器.
在宝塔里安装pm2管理器.
在软件商店里,搜索pm2,安装.


image.png

安装后设置Node版本.


image.png

电脑本地node版本为v14.21.0,vps上的最好配置成一样的,不然还要切版本.

node -v
v14.21.0

在/www/wwwroot目录下,新建OnlineDeployment/Server文件夹.上传除了node_modules之外的文件.


上传文件

然后进入pm2管理器添加项目.


添加node项目

选择启动文件,即对应的app.js文件

image.png

添加项目后如下所示



需放行端口.这里app.js里面监听的是5000,所以需要放行的是5000.进入安全里面设置.

然后点击管理,添加依赖.选择一键安装依赖.


image.png

image.png

image.png

然后点击启动.


image.png

image.png

然后就可以通过 ip+端口访问.
http://xx.xx.xx.xx:5000/

现在将前端中的接口修改下.

由于需要跨域,所以配置下vue.config.js中的devServer(这个配置不会打包,打包到服务器需另行配置).

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://xx.xx.xx.xx:5000',
                pathRewrite: {'^/api' : ''}
            }
        },
    }
}

修改下请求api.

    test() {
      axios
          // http://localhost:5000
          // .get('http://localhost:5000')
          .get('/api')
          .then((res) => {
            console.log(res)
          })
          .catch((err) => {
            console.log(err)
          })
    }

可以看到这里访问的是http://localhost:8080/api
状态代码: 304 Not Modified.

image.png

如果使用devServer代理后数据无法正常返回,
1.确认配置写法与版本是否对应.不同版本的cli配置不一样.这里不再赘述.
2.确认 http://xx.xx.xx.xx:5000/ 可正常访问.
3.排除转发url异常(可以使用wireshark查看)

这里为了测试 屏蔽掉pathRewrite.

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://xx.xx.xx.xx:5000',
               // pathRewrite: {'^/api' : ''}
            }
        },
    }
}
image.png

当访问 http://localhost:8080/api 时,返回 404 Not Found.

image.png

可使用 tcp.port == 5000 (node中监听的端口)或
ip.addr ==xx.xx.xx.xx(linux服务器的ip地址)监听.
下面来看看错误的代理配置情况下的url.

image.png

发送请求后,过滤ip.addr ==xx.xx.xx.xx,找到协议为http,404的那条.查看Hypertext Transfer Protocol中的Request URI.
Request URI

可以看到此时的请求为
http://xx.xx.xx.xx:5000/api,这里是错误的url,需要将api替换成空.

把pathRewrite解除屏蔽后,重新编译,发送请求.可以看到此时的请求为 http://xx.xx.xx.xx:5000/ 可以正常返回数据.

实际项目一般会配置.env.development和.env.production去写入对应的url.这里主要演示下所以不配置.

本地vue项目调试好之后,需run build,生成dist文件夹.将dist文件上传至/www/wwwroot/OnlineDeployment/client/目录下.


image.png

选择网站-php项目-添加站点.


image.png

根目录选择/www/wwwroot/OnlineDeployment/client/dist.填入域名后提交.
然后要配置ssl,不然无法访问.因为宝塔面板默认配置的是https。
这里就用Let's Encrypt.

image.png

然后需要配置nginx反向代理,否则就是404(因为devServer配置不会被打包).


image.png
   location ^~/api/ {
      proxy_pass http://xx.xx.xx.xx:5000/;
    }

然后就可以通过域名访问前端项目,并向后端发送请求.
https://xxxx.xxx/

这里的 location和 proxy_pass 这2个写的时候要注意.
location 规则匹配可参考这篇:
Nginx配置请求转发location及rewrite规则

location  = / {
  # 精确匹配 / ,主机名后面不能带任何字符串
  [ configuration A ] 
}

location  / {
  # 因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求
  # 但是正则和最长字符串会优先匹配
  [ configuration B ] 
}

location /documents/ {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration C ] 
}

location ~ /documents/Abc {
  # 匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索
  # 只有后面的正则表达式没有匹配到时,这一条才会采用这一条
  [ configuration CC ] 
}

location ^~ /images/ {
  # 匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条。
  [ configuration D ] 
}

location ~* \.(gif|jpg|jpeg)$ {
  # 匹配所有以 gif,jpg或jpeg 结尾的请求
  # 然而,所有请求 /images/ 下的图片会被 config D 处理,因为 ^~ 到达不了这一条正则
  [ configuration E ] 
}

location /images/ {
  # 字符匹配到 /images/,继续往下,会发现 ^~ 存在
  [ configuration F ] 
}

location /images/abc {
  # 最长字符匹配到 /images/abc,继续往下,会发现 ^~ 存在
  # F与G的放置顺序是没有关系的
  [ configuration G ] 
}

location ~ /images/abc/ {
  # 只有去掉 config D 才有效:先最长匹配 config G 开头的地址,继续往下搜索,匹配到这一条正则,采用
    [ configuration H ] 
}

location ~* /js/.*/\.js

注意:这里proxy_pass的写法, 最后一个字符这里需要加/,
下面来看看 错误的写法:
把配置文件中的5000后的/删去.发送请求后,返回404.

    location ^~/api/ {
      proxy_pass http://xx.xx.xx.xx:5000;
    }
image.png

nginx转发的url这里的抓包,可以在linux中使用tcpdump,生成.cap,再使用wireshark打开.

image.png

监听5000端口,并生成文件.

tcpdump -n -i any port 5000 -w ./nginx_5000.cap

发送请求后,中断监听(我这里是用的xshell,所以用ctrl+c).

image.png

把nginx_5000.cap文件使用xftp拖出来,用wireshark打开.
找到 get 请求. 可以看到,uri为/api/.
请求的是 http://xx.xx.xx.xx:5000/api/,这实际是不存在的接口,所以返回404.
返回404

正常返回 hello node的uri应该是/,host一致,但是uri不一样.需访问的是http://xx.xx.xx.xx:5000/

正常返回 hello node

proxy_pass最后一个字符为/时,与location匹配的请求 URI 部分将被替换为proxy_pass中指定的 URI,
最后一个字符不为/时,请求 URI (即/api/等参数),那么请求URI也会被一起发送.
官方文档解释如下所示。
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

nginx 相关知识可参考这几篇.
Nginx(三)------nginx 反向代理
nginx 之 proxy_pass详解
官方文档
:https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass

其他需注意的点
1.宝塔linux面板-重启后导致PM2管理器项目列表丢失

# 查看创建的项目是否存在
pm2 list
//保存项目
pm2 save
//开机启动
pm2 startup    

碎碎念:本篇其实写于2022年年底,由于年底阳了,所以佛了一段时间。
参考链接:
宝塔linux面板-重启后导致PM2管理器项目列表丢失或清空,解决方案
【已记录】关于PM2管理器 重启服务器后项目丢失临时解决...

Nginx(三)------nginx 反向代理
Nginx配置请求转发location及rewrite规则

Vue项目打包部署上线时devServer.proxy代理失效如何解决?使用nginx的proxy_pass 代理跨域转发
nginx中proxy_pass配置说明
关于Nginx location中配置proxy_pass转发时斜线‘/‘导致的404问题
部署上线node+vue全栈项目的全部流程 (超详细~~)
【你应该了解的】详尽&全面的前端部署(从零起步,前端上线不用愁)
宝塔node项目的部署(https)
前后端分离全栈项目的开发与部署流程
宝塔部署nodejs项目

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容