记一次完整的项目部署

Posted qianduanwriter

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记一次完整的项目部署相关的知识,希望对你有一定的参考价值。

前段时间在公司部署项目的时候,运维同学说了一堆关于服务器的东西,顿时感觉不知所云,云里雾里。。。

技术图片

索性拿这个项目练习一下,简单了解项目部署到服务器的这个流程是怎么处理的

预备知识

pm2

pm2 是启动node进程管理工具

常用命令

···

pm2 start app.js : 启动服务,入口文件是app.js

pm2 list 查看有哪些进程启动

pm2 show xxx 查看某一个服务的详情

npm restart [name or id] : 重启服务

pm2 monit : 对服务进行监控

···

一个项目的package.json 文件

技术图片

平时启动服务我们可以使用 node run app.js

如果借助pm2 来启动服务 就可以输入 pm2 start app.js

在命令行输入 pm2 list 可以查看正在运行的项目

技术图片

pm2支持配置文件启动

技术图片

  • script 启动脚本路径
  • exec_mode 应用启动模式,支持fork和cluster模式
  • instances 应用启动实例个数,仅在cluster模式有效,默认为fork

fork和cluster模式

fork为单进程 cluster可以启动多个进程

在项目中新增一个pm2配置文件 pm2.config.json

{
  "name": "mxx-project",
  "script": "./index.js",
  "error_file": "./logs/err.log",
  "out_file": "./logs/out.log",
  "log_date_format": "YYYY-MM-DD HH:mm Z",
  "instances": 3,
  "merge_logs": true,
  "exec_mode": "cluster",
  "node_args": "",
  "ignore_watch": ["node_modules"],
  "env": {
    "NODE_ENV": "development"
  }
}

在命令行输入

pm2 start pm2.config.json

则会有三个进程被创建

技术图片

注: 如果你的服务器是多核的 那么很有可能在cluster 模式下 被创建多个进程

可以查看一下自己的服务器是几核的

技术图片

shipit

shipit 是自动化的服务器部署工具

一个简单的shipit配置文件

module.exports = shipit => {
  require(‘shipit-deploy‘)(shipit)
  shipit.initConfig({
    default: {
      workspace: ‘/tmp/myapp‘,
      deployTo: ‘/var/myapp‘,
      repositoryUrl: ‘你的GitHub地址‘,
      ignores: [‘.git‘, ‘node_modules‘],
      keepReleases: 2,
      deleteOnRollback: false,
      key: ‘/path/to/key‘,
      shallowClone: true,
    },
    staging: {
      servers: ‘你的服务器地址‘,
    },
  })
}

连接服务器

购买服务器之后 得到IP地址 可以尝试登陆服务器

一般自己的服务器可以使用root身份登陆操作

ssh root@ipipip

由于后面项目要部署到服务器中 建议可以先做ssh-copy-id 建立信任 这样就不用重复输入密码了

技术图片

在服务器上配置环境

一般来说 需要安装 npm cnpm node pm2 git nginx

  • 安装npm
yum install npm  
  • 安装 cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
  • 安装pm2
npm i pm2 
  • 安装node
npm i n
  • 安装git
yum install git
  • 安装nvm
 wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

需要调整 vim ~/.bashrc

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm

指定默认node版本

nvm alias defalut 8

启动一个简易服务

我们来写一个简单的脚本 在服务器上, 我这里是在 /home/work 目录下新建了一个app.js (依次执行)

cd home
mkdir work
touch app.js

在app.js中 写一个最简单的服务

const http = require(‘http‘)
const port = 3389

http.createServer((req, res) => {
  res.end(‘Hello word!‘)
}).listen(port, () => {
  console.log(port, ‘port‘)
})

启动app.js

node app.js

技术图片

然后打开浏览器,输入IP+端口号,就能在页面中看到hello word了

技术图片

--补充--

1 这里使用的端口号是 3389 是因为我的服务器中 安全组中已经配置了 3389 这个端口号

如果你使用的是其余端口 要注意去查看有没有配置安全组

2 关于启动服务

如果使用的是node 那么一旦退出服务器,则无法再访问此服务

可以换成使用pm2 来启动 这样一旦启动 除非报错,将会一直有此进程存在

技术图片

准备部署

  • 准备项目

项目是用koa1 + React

react的项目地址 点我查看GitHub地址

启动的端口号调整到3389

  • 准备pm2启动文件

创建pm2文件夹 在其中写一个 production.json 用于启动pm2

  • 在项目中创建一个 shipit.js 基本配置如下
module.exports = function (shipit) {
  require(‘shipit-deploy‘)(shipit)
  require(‘shipit-cnpm‘)(shipit)
  require(‘shipit-pm‘)(shipit)
  shipit.initConfig({
    default: {
      workspace: ‘/tmp/deploy/your-project‘,
      deployTo: ‘/home/work/your-project‘,
      repositoryUrl: ‘https://github.com/youproject.git‘,
      ignores: [‘.git‘, ‘node_modules‘],
      keepReleases: 2,
      deleteOnRollback: false,
      key: ‘/path/to/key‘,
      shallowClone: true,
      cnpm: {
        flags: ‘--production‘,
        local: false,
        npm: ‘cnpm‘,
        remote: true
      },
      pm: {
        production: {
          path: ‘/home/work/your-project/current/pm2/production.json‘
        }
      }
    },
    production: {
      servers: [‘root@你的IP地址‘]
    }
  })
}

这里 pm2 使用的配置文件来启动 所以配置了 pm 参数 会根据这个文件路径来启动pm2

  • 在项目的package.json中 添加两个字段
    "deploy": "shipit production deploy",
    "rollback": "shipit production rollback",
  • 将项目push到GitHub中
  • 执行 npm run deploy

项目部署完毕后,去服务器查看下项目进程

pm2 list

技术图片

打开页面 看下效果

技术图片

到目前为止,算是部署完毕了

部署过程出现的问题

  • 报错1

技术图片

解决: 服务器上忘记安装git了

  • 报错2

技术图片

这个就很明显了,没有安装 cnpm

  • 部署成功之后去服务器查看 项目并没有启动

原来部署完毕是

技术图片

然后求助一位大神,发现是shipit配置文件中 没写

require(‘shipit-pm‘)(shipit)

[摔桌子!]

调整文件后重新上线

技术图片

会启动三个进程

根据项目端口号配置阿里云

如果你的项目启动时候端口号并没有在安全组中配置,需要在后台中添加安全组

技术图片

在访问页面的时候 还需要输入端口号 3389。非常懒,不想输入端口号

在安全组中添加默认端口80,将启动文件app.js中端口调整为80。这样就不需要输入端口号了

技术图片

技术图片

那如果不想修改app.js文件怎么办,使用NGINX

配置NGINX

  • 安装 nginx

yum install nginx

查看NGINX配置文件

cat  /etc/nginx/nginx.conf

很简单的配置

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        location / {
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }

}

将项目入口文件app.js中端口号调整为 9999

处理Nginx.conf.js

最后调整为 (比较重要的是server 这里只展示server部分)

 server {
        listen       80;
        server_name  localhost;
 
        location / {
          proxy_pass  http://127.0.0.1:9999/;
        }
    }

启动Nginx

nginx -s reload

Nginx配置出现的问题

  • 重启Nginx

在重启Nginx的时候 一直报错

技术图片

查阅文章后处理

nginx -c /etc/nginx/nginx.conf
nginx -s reload

搞定~

欢迎访问 点我查看项目

参考文章

以上是关于记一次完整的项目部署的主要内容,如果未能解决你的问题,请参考以下文章

记一次项目部署经历

记一次完整的pc端整站开发

记一次项目部署中遇到的问题

记一次完整 C++ 项目编译成 WebAssembly 的实践

记一次腾讯云部署项目过程

记一次完整的系统业务代码重构——why