如何在服务器部署前后端分离项目

5,441 阅读2分钟

介绍如何通过Nginx部署前后端分离项目。

一、简介

文章结构:

  • 介绍nginx配置
  • 编写脚本实现一键发布
  • 如何使用 pm2 部署 node 服务

思路:

将 nginx 作为静态资源服务器托管html、css、js图片等静态文件,然后将满足某些条件的ajax请求代理转发到后端服务上。即可实现前后端项目的部署。

由于前后端分离模式下,前后端各自部署自己的项目,前端发送的请求到后端某一端口的服务会产生跨域,因此通过Nginx设置转发来解决跨域问题。

二、nginx配置

如果对nginx不太熟悉的同学可以参考我的另外一篇文章: 前端需要了解的Nginx知识

  • 这里直接贴出 Nginx 配置
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    access_log  /usr/local/etc/nginx/logs/access.log;  #nginx请求日志地址
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        # 前端
        location /blog {
            root /data/sites/;
            autoindex on;
            expires 30d; # 缓存30天
            # html文件不设置强缓存,每次都会向服务端确认是否更新
            if ($request_filename ~ .*\.(htm|html)$) {
                add_header Cache-Control no-cache;
            }
            if (!-e $request_filename) {
                rewrite ^/(.*) /blog/index.html;
            }
        }
        # 后端,只转发 /blog/api 开头的请求
	location /blog/api {
            proxy_pass  http://127.0.0.1:3000;
            proxy_redirect     off;
            proxy_set_header   Host             $host;        # 传递域名
            proxy_set_header   X-Real-IP        $remote_addr; # 传递ip
            proxy_set_header   X-Scheme         $scheme;      # 传递协议
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
        # redirect server error pages to the static page /50x.html
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

三、一个命令部署前端静态资源

# 直接运行脚本
sh publish.sh

# 在项目中配置启动脚本后就可以使用 npm 启动
"scripts": {
    "publish": "sh build/publish.sh"
}
npm run publish
  • publish.sh
#!/bin/bash
branch_name=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
publishFolder='/data/sites/blog' # nginx目标目录
echo On branch: $branch_name
# 发布函数
fun_publish () {
    echo '\n2. start publish...'
    if [ ! -d $publishFolder ];
        then sudo mkdir -p $publishFolder
    fi
    # 递归覆盖拷贝
    sudo cp -f -r 'dist/.' $publishFolder
    fun_green_log 'publish success!over~\n'
}
fun_run_log () {
    echo "\033[33m \n$ $* \033[0m"
    $*
}
fun_green_log () {
    echo "\033[32m$* \033[0m"
}
if [ $branch_name == 'master' ] || [ $branch_name == 'gray' ];
    then
        # build
        echo '\n1. start build...'
        fun_run_log npm run build
        current_path=$(pwd)
        fun_green_log 'build success, publish file list:'
        find ${current_path}/dist -type f
        # make sure
        echo "\nAre you sure to publish to ${publishFolder}?(yes/no)"
        read answer
        if [ $answer != 'yes' ]
            then echo Cancel publish, return!
            else fun_publish # publish
        fi
    else 
        echo "Only the branch:master can publish!You are on $branch_name."
fi

四、使用 pm2 部署服务

通常在本地启动服务时需要打开终端,运行 npm run start 来启动服务,但是当退出终端服务就停了,或者需要手动杀掉服务,才能再次重启。

pm2(process manager)是一个进程管理工具,维护一个进程列表,可以用它来管理你的node进程,负责所有正在运行的进程,并查看node进程的状态,以守护进程的方式启动node进程,终端退出也可以继续运行,也支持性能监控,负载均衡等功能。

  • 常用命令
pm2 start server.js   #  启动服务
pm2 list      # 列出所有进程
pm2 restart 0 # 0秒重启服务
pm2 stop 0    # 关闭服务
pm2 log 0     # 查看进程控制台日志
  • 参数说明
启动参数作用
watch实时监控app.js的方式启动,当app.js文件有变动时,pm2会自动reload
name为进程取名字,方便在列表中识别
  • 启动服务举例
pm2 start npm --name blog-server  -- run start

idnamenamespaceversionmodepiduptimestatuscpumemuserwatching
0blog-serverdefaultN/Afork26647s0online5.3%44.6mbusernamedisabled

五、参考