前后端分离全栈项目的开发与部署流程

15,291 阅读8分钟

本文记录了一个前后端分离全栈项目的开发与部署流程,我会以demo的形式逐步演示。这篇文章是我各种踩坑终于把整个流程跑通之后,喜悦之余的总结分享(自己瞎琢磨,也不知道对不对)。

demo技术栈为react + koa + Mongodb及其相关技术。

centos安装环境

本想使用docker一套全搞定,但是我的服务器配置太低了,拉取docker镜像到一半就超时,尝试一整晚之后无果,无奈最后只能用yum一个一个安装。安装环境之前先更新一下已有的包

yum update

安装nodeJS

使用yum安装指定版本node

curl --silent --location https://rpm.nodesource.com/setup_10.x | sudo bash -
yum install -y nodejs

安装完成之后可以验证一下

node -v
npm -v

安装node后可以利用npm安装一下nvm和pm2

npm i nvm pm2 -g

nvm用于node版本控制,pm2用于启动node服务以及进程守护。

安装Mongodb

  1. 创建yum源文件

    vim /etc/yum.repos.d/mongodb-org-4.0.repo
    

    添加以下内容

    [mongodb-org]
    name=MongoDB Repository
    baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/4.0/x86_64/
    gpgcheck=0
    enabled=1
    

    保存后退出

  2. 安装Mongodb

    yum -y install mongodb-org
    

    安装完成之后配置Mongodb。查看并修改配置文件

    vim /etc/mongod.conf
    

    bindIp改为 0.0.0.0,支持远程访问。同时设置dbPath,目录自选。fork: true 表示后台运行mongod,这样就不用每次都重启服务了(注意设置dbPath时,需要先确认目录存在,如果是之前不存在的文件夹,需要手动创建。)。

    image-20200229164401471

  3. 启动Mongodb

    以配置文件的方式启动Mongodb

    mongod --config /etc/mongod.conf
    

    启动之后服务在后台运行,验证一下

    mongo
    

    WX20200229-165420@2x

安装Nginx

  1. 创建yum源文件

    vim /etc/yum.repos.d/nginx.repo
    

    添加以下内容

    [nginx-stable]
    name=nginx stable repo
    baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
    gpgcheck=1
    enabled=1
    gpgkey=https://nginx.org/keys/nginx_signing.key
    

    保存后退出

  2. 安装Nginx

    yum -y install nginx
    
  3. 启动Nginx

    nginx
    

本地环境安装

本机不像服务器上有带宽的限制,直接上docker

docker具体的安装步骤见 www.runoob.com/docker/maco…

同时使用docker安装 mongo, mongo-express www.runoob.com/docker/dock…

安装完成之后验证一下mongo-express,打开 http://localhost:8081/

image-20200229180554241

后端项目开发

建数据库

先建立数据库, 使用命令

mongo

image-20200229184034640

新建demo数据库,新建user集合,插入一条数据 {userName: 'tom', age: 18}

也可以使用mongo-express可视地化操作数据库,打开 http://localhost:8081/

image-20200229184253682

可以看到刚刚新建的demo数据库。这里也可以使用右上角的表单,输入数据库名,点击create DataBase 按钮新建数据库

点击View查看数据库

image-20200229184533849

可以看到已经建好的user集合,再点击View查看集合

image-20200229184615879

可以看到刚刚插入的那条数据。还可以点击 New Document 按钮可视化地添加数据

image-20200229184752654

至此大家就可以动动点赞的小手,轻松的添加删除编辑数据了

项目初始化

有了数据再开始编码吧,demo使用koa开发,本地安装脚手架

npm install -g koa-generator

初始化项目

koa2 -e koa-demo

进入项目文件夹安装依赖

npm i

启动项目

npm run dev

浏览器打开 http://localhost:3000/

image-20200229172147220

修改一下项目,这里我就直接列出修改后的代码了。

image-20200229172951188

image-20200229173201562

此时 http://localhost:3000/ 直接返回 hello

image-20200229173301772

链接数据库

操作mongodb我使用的mongoose,安装依赖

npm i mongoose

image-20200229181032693

新建 /config/mongo.js,配置链接。app.js引入配置,初始化链接

image-20200229183156408

新建数据模型

image-20200229183023869

添加model层

image-20200229183044790

写个接口

这里直接用脚手架自带的users路由,加一个/list接口,访问数据库获取数据

code

一切就绪,测试一下,访问 http://localhost:3000/users/list

image-20200229185942392

加个参数试一下

image-20200229190055076

至此,node服务编写完成

部署node程序到服务器

上传文件

上传文件到服务器有很多方式,比如scp、ftp等,这里我使用的git。首先把项目上传到github,然后进入服务器使用git拉去远程仓库文件。别忘了再linux上生成 SSH Key,添加到github。

(这里我采用的是手动拉取代码的方式,实际上有更方便的自动化部署方案,会在下面的前端项目部署中演示)

github.com/jsliushenGi…

image-20200229192742313

这里我在根目录下新建了service文件夹,然后clone下来项目。 此时项目路径为 /root/service/koa-demo

启动服务

启动项目之前先在服务器上新建数据库,新建集合,插入数据

image-20200229191906727

安装依赖

npm i

然后以pm2启动项目(脚手架生成的项目package.json中的scripts里有prd指令,以pm2启动)

npm run prd

此时服务监听3000端口,需要在阿里云的安全组规则里开放3000端口。这里同时需要开放以下端口,方便后续操作。

  • 开放27017端口,远程访问mongodb
  • 开放8081端口,远程访问mongo-express
  • 开放80端口,http访问服务器

image-20200229193448686

添加完成之后就可以访问了,地址为你的服务器外网ip加端口号

安全考虑,我上了码

image-20200229195823955

再访问接口试试

image-20200229200054304

刚刚添加的那条数据已经查询出来了

配置Nginx

我们在访问接口时,肯定不会直接以ip+端口的方式,一般是以域名的方式,所以需要配置Nginx,转发请求。我的域名是jsliushen.com,这里添加一个子域名 server.jsliushen.com,用于访问服务。同时以路径区分服务,当访问 server.jsliushen.com/demo/xxx时,转发到端口加ip

首先在阿里云添加域名解析

image-20200229200435996

然后编辑nginx配置

vim /etc/nginx/nginx.conf

image-20200229200652660

我的项目文件在root目录下,默认是没有权限访问的,需要吧user设置为root。默认的配置里有一句 include /etc/nginx/conf.d/*.conf , 也就是说在conf.d文件夹下所有conf后缀名的文件都会生效。直接在conf.d下新建 server.conf 配置文件

vim /etc/nginx/conf.d/server.conf

image-20200229201347325

保存后热重启nginx,使配置生效

nginx -s reload

验证一下, 访问 server.jsliushen.com/demo/users/…

image-20200229201715982

现在我们已经有了一个线上运行的接口。至此,node后端服务的开发与部署介绍完毕。

开发前端项目

使用react-create-app初始化项目

yarn create react-app demo-client
cd demo-client

修改app.js

image-20200229221944140

本地启动项目

yarn start

image-20200229222454941

前端项目开发完毕,接口正常返回,下面要做的就是把项目部署到服务器

部署前端项目到服务器

前端静态资源部署我采用webHooks自动部署的方式

WebHooks的原理简单来说就是本地push代码到github时,github会监测到该行为,然后请求一个接口,在该接口中拉取远程仓库的代码,达到自动化部署的目的。

在要部署项目的文件夹里初始化git,这里我放在了/root/website/demo-client

git init
git remote add origin git@github.com:jsliushenGit/demo-client.git

此时项目文件夹还是空的。

前端项目使用的yarn管理包,锁定文件是yarn.lock,所以在服务器上也全局安装yarn

curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo

yum install -y yarn

编写接口

接口接收来自github的请求,然后拉取远程仓库的代码。我们把接口放到 /root/service/webhook文件夹下

image-20200301010500047

// index.js
const http = require('http');
const exec = require('child_process').exec;

http.createServer(function (request, response) {
  response.writeHead(200, {
    'Content-Type': 'application/json'
  });
  response.end();
	// 判断接口是否来自github,触发的行为是否是push
  if (request.headers['x-github-event'] && request.headers['x-github-event'] === 'push') {
    // 部署方法
    runCommand();
  }

}).listen(7777);

function runCommand() {
  exec("/root/service/webhook/deploy.sh", function (err, stdout, stderr) {
    if (err) {
      console.log('error:' + stderr);
    } else {
      console.log("stdout:" + stdout);
    }
  });
}

上面的代码应该很好理解,就不做过多说明了。下面是deploy.sh

#! /bin/bash

WEB_PATH='/root/website/demo-client'

echo "start deployment"
# 进入要部署的项目文件夹
cd $WEB_PATH

echo "fetching from remote..."
# 拉取代码
git fetch --all

git reset --hard origin/master

echo "remove build"
# 删除之前构建的文件夹(最新的create-react-app中构建默认目录为build)
rm -rf /build

echo "install dependencies"
# 安装依赖
yarn

echo "start build"
# 开始打包
yarn build

echo "done"

使用pm2启动这个服务

pm2 start /root/service/webhook/index.js --name webhooks

服务器端的工作基本已经完成,别忘了服务监听的7777端口,还需要在阿里云安全组规则里开放7777端口。

github配置webhooks

在github仓库的设置里,webhooks中添加一个webhook,payload URL填写请求地址,也就是上面编写的那个接口的地址,服务器公网ip+端口,同样也可以配置Nginx,变成域名的方式,参考上面的部署node程序到服务器一节。secret是自己设定的密钥,用于校验。

image-20200301011151157

填写完成之后保存添加,然后试用一下。

验证webhooks

本地项目push代码至远程仓库,同时查看pm2日志

pm2 logs webhooks

image-20200301022518582

部署完成后查看项目文件夹 /website/demo-client/

image-20200301022635224

文件拉取成功,也打包成功。

配置前端Nginx

前端静态文件想要访问的话还需要配置Nginx,和之前后端服务配置Nginx一样,在/etc/nginx/conf.d目录下新建配置文件。

vim /etc/nginx/conf.d/demo_client.conf

image-20200301023226562

设置二级域名 demo-client.jsliushen.com,同时在阿里云域名解析里解析二级域名

image-20200301023645511

热启动nginx,是配置生效

nginx -s reload

访问前端项目

打开 demo-client.jsliushen.com/

image-20200301023749049

至此,前端项目的开发与部署介绍完毕。

说明

本文demo的前端和后端代码会在github一直保存,临时创建的二级域名和服务以及部分开放的端口,会在本文发出的一周后(2020.3.8)下掉,安全考虑,望理解。

本文基本没有原理性的介绍,纯步骤代码演示,希望能对大家有帮助。