Node.JS线上服务器部署与发布


前言


本文是个人对慕课网《Node.js线上服务器部署与发布》的图文总结。


第一章 课程预热


生产环境所需因素:

  1. 购买域名
  2. 购买服务器
  3. 域名备案
  4. 配置服务器应用环境
  5. 安装配置数据库
  6. 项目远程部署发布与更新

第二章 待部署的5个本地Node.JS项目


部署之路


第三章 选购域名服务器及备案


一、选择域名

  1. 爱名网
  2. 阿里云
  3. GoDaddy

二、选择主机

  1. (国外)亚马逊AWS、Linode、DigitOcean/Heroku
  2. (国内)阿里云ECS、青云/UCloud/百度云

第四章 登录远程服务器


一、使用xshell作为linux登录工具

使用xshell作为登录工具

(注:可以到xshell官网使用邮箱申请下载Home/School的免费版本,尽量不要使用网上下载的,毕竟服务器操作事务就要小心谨慎。)

二、常用的linux命令

  1. 查看数据磁盘

    1
    fdisk -l
  2. 查看磁盘占用情况

    1
    df -h
  3. 切换用户

    1
    su - [username]

    (注:如果是从普通用户切换到root则不需要写username)

三、配置权限账号

因为直接使用root超级管理员账号操作容易造成严重后果,所以需要配置低权限的账号进行日常使用。

  1. 添加用户

    1
    adduser [username]
  2. 分配权限

    1
    gpasswd -a [username] sudo
  3. 编辑权限

    1
    sudo visudo

    编辑用户权限

四、通过SSH配置免密登录

  1. 首先,确认本地是否已配置过SSH公钥及私钥

    确认本地是否已配置过SSH

  2. 若本地无SSH,则生成一个:

    1
    ssh-keygen -t rsa -b 4096 -C "email@email.com"
  3. 登录服务器,执行以下操作:

    3.1 生成服务端SSH(命令与上面本地一样)

    3.2 跑起代理

    1
    2
    3
    eval "$(ssh-agent -s)"
    ssh-add ~/.ssh/id_rsa
    vi authorized_keys

    3.3 将本地的公钥(.ssh/id_rsa_pub)复制到服务器根目录下.ssh/authorized_keys文件内

    3.4 更改authorized_keys文件的授权

    1
    chmod 600 authorized_keys

    3.5 重启服务端ssh服务:

    1
    sudo service ssh restart

    3.6 新建一个终端,发现不用输密码即可登录了:

    成功配置后登录


第五章 增强服务器等级


一、修改配置文件

1
sudo vi /etc/ssh/sshd_config
  1. 修改端口号

    修改端口号

  2. 授权角色

    授权角色

  3. 禁止root、密码登录

    禁止root、密码登录

  4. 重启SSH服务

    1
    sudo service ssh restart
  5. 更新阿里云安全组配置

    更新阿里云安全组配置

二、配置IP防火墙规则

  1. 清空现有的iptables

    1
    sudo iptables -F
  2. 自定义iptables,创建iptables.up.rules

    1
    sudo vi /etc/iptables.up.rules
  1. 编辑iptables.up.rules文件:

    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
    *filter
    # allow all established input
    -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

    # allow out traffic
    -A OUTPUT -j ACCEPT

    #allow http(80) and https(443)
    -A INPUT -p tcp --dport 443 -j ACCEPT
    -A INPUT -p tcp --dport 80 -j ACCEPT

    # allow ssh port login
    -A INPUT -p tcp -m state --state NEW --dport 48273 -j ACCEPT

    # allow ping
    -A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

    # log denied calls
    -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied:" --log-level 7

    # drop incoming sensitive connections
    -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set
    -A INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 150 -j DROP

    #reject all other inbound
    -A INPUT -j REJECT
    -A FORWARD -j REJECT

    COMMIT
  2. 激活iptables.up.rules

    1
    sudo iptables-restore < /etc/iptables.up.rules
  3. 查看防火墙激活状态

    1
    sudo ufw status
  4. 激活防火墙

    1
    sudo ufw enable
  5. 创建开机启动脚本

    1
    sudo vi /etc/network/if-up.d/iptables
  6. 写入脚本内容:

    1
    2
    #!/bin/sh
    iptables-restore /etc/iptables.up.rules
  7. 授权脚本

    1
    sudo chmod +x /etc/network/if-up.d/iptables

三、安装Fail2Ban阻止暴力破解

  1. 更新服务器APT软件包

    1
    sudo apt-get update && sudo apt-get upgrade
  2. 安装Fail2Ban

    1
    sudo apt-get install fail2ban
  3. 打开fail2ban配置文件

    1
    sudo vi /etc/fail2ban/jail.conf

    修改以下内容:

    1
    destmail = shaolong.chuang@qq.com
  1. 查看fail2ban运行情况
    1
    sudo service fail2ban status

第六章 搭建Node.JS生产环境


一、安装必要的依赖包

  1. 基本的依赖

    1
    sudo apt-get install vim openssl build-essential libssl-dev wget curl git
  2. 安装nvm(node版本管理器)

    1
    wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

    (注:相关命令在nvm的github上可以找到,点击这里)

  3. 安装Node.JS

    1
    nvm install v6.9.5
  4. 使用指定版本的Node.JS

    1
    2
    nvm use v6.9.5
    nvm alias default v6.9.5
  5. 配置NPM淘宝镜像

    1
    npm --registry=https://registry.npm.taobao.org install -g cnpm
  6. 增加新的文件结构树

    1
    echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
  7. 安装全局NPM包

    1
    npm i -g pm2 webpack gulp grunt-cli

二、在服务器上跑Node.JS(测试)

  1. 根目录下新增app.js

    1
    vi app.js

    编写内容:

    1
    2
    3
    4
    5
    6
    const http = require('http')
    http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'})
    res.end('Node.JS web server test')
    }).listen(37234)
    console.log('server is running on http://29.184.39.92:37234')
  2. 临时更改防火墙配置

    2.1 打开37234端口接收权限

    1
    sudo vi /ect/iptables.up.rules

    编辑内容:

    1
    -A INPUT -p tcp --dport 37234 -j ACCEPT

    2.2 重载iptables

    1
    sudo iptables-restore < /etc/iptables.up.rules

    2.3 到阿里云控制台里新增37234端口的安全组规则

  3. 打开浏览器请求http://29.184.39.92:37234

    即可看到成功请求。

三、安装pm2管理线上环境

  1. 安装pm2

    1
    npm install pm2 -g
  2. 通过pm2启动线上项目

    1
    pm2 start app.js

    成功启动pm2

  3. 查看pm2线程列表

    1
    pm2 list
  4. 查看pm2线程详情

    1
    pm2 show [thread name]
  5. 查看实时日志

    1
    pm2 logs

第七章 配置Nginx实现反向代理


一、停用阿里云自带apache服务

  1. 关闭apache服务

    1
    2
    sudo service apache stop
    sudo service apache2 stop

    (注:这是由于阿里云服务器往往自带apache,但该服务不一定为开启状态)

  2. 移除apache

    1
    2
    sudo update-rc.d -f apache2 remove
    sudo apt-get remove apache2

二、安装Nginx

  1. 更新软件包列表

    1
    sudo apt-get update
  2. 安装Nginx

    1
    sudo apt-get install nginx
  3. 新建Nginx配置文件

    1
    sudo vi /etc/nginx/conf.d/test-com-37234.conf

    编写配置文件内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    upstream test {
    server 127.0.0.1:37234;
    }

    server {
    listen 80;
    server_name 29.184.39.92;
    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Nginx-Proxy true;
    proxy_pass http://test;
    proxy_redirect off;
    }
    }

    (注:上面配置upstream,实际上就是配置负载均衡,只不过当前“test”均衡配置里只有127.0.0.1:37234一个server而已,可以在此添加多个server并配置weight权重)

  4. 检查/etc/nginx/nginx.conf配置文件内是否已引入上面创建的目录下的配置文件,如否则开启。

    检查/etc/nginx/nginx.conf配置文件内是否已引入上面创建的目录下的配置文件,如否则开启。

  5. 测试配置文件

    1
    sudo nginx -t
  6. 重启Nginx

    1
    sudo nginx -s reload
  7. 打开浏览器,直接访问http://29.184.39.92 (即访问默认的80端口),可以看到成功将80端口的访问请求转发到37234端口了。

    成功将80端口的访问请求转发到37234端口

  8. 隐藏response里的nginx版本信息

    1
    sudo vi /etc/nginx/nginx/conf

    http->Basic Setting,开启server_tokens off;

    1
    sudo service nginx reload

    重载nginx后,浏览器中发现已经隐藏了nginx版本信息了。


第八章 利用DNSPod管理域名解析


该部分内容由于可以直接在阿里云控制台里配置域名解析,所以在此不赘述。


第九章 服务器上使用MongoDB


一、安装MongoDB

注:可以谷歌搜索“mongodb install on ubuntu docs”

  1. 安装MongoDB

    1
    2
    3
    4
    sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
    echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.0.list
    sudo apt-get update
    sudo apt-get install -y mongodb-org

    (注:该部分代码需对应文档查找最新内容)

  2. 启动MongoDB服务

    1
    sudo service mongod start
  3. 检查服务是否开启

    1
    mongo

    mongodb开启失败

  4. 配置防火墙以启动mongodb

    1
    sudo vi /etc/iptables.up.rules

    新增以下内容:

    1
    2
    3
    # mongodb connect
    -A INPUT -s 127.0.0.1 -p tcp --destination-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT
    -A OUTPUT -d 127.0.0.1 -p tcp --source-port 27017 -m state --state NEW,ESTABLISHED -j ACCEPT

    重载iptables:

    1
    sudo iptables-restore < /etc/iptables.up.rules
  5. 修改mongodb默认端口(安全起见)

    1
    sudo vi /etc/mongod.conf

    更改mongodb默认端口

    重启mongodb

    1
    sudo service mongod restart

    更新防火墙规则iptables.up.rules(方法同上)
    连接新端口:

    1
    mongo --port 29374

二、将本地MongoDB数据库备份到服务器上

  1. 本地备份(本地执行命令)

    1
    mongodump -h 127.0.0.1:27017 -d imooc-movie -o imooc-moive-backup

    本地备份命令
    本地备份文件

  2. 打包本地备份数据库(本地执行命令)

    1
    tar zcvf imooc-movie.tar.gz imooc-movie-backup

    打包本地备份数据库
    (执行后,本地多了一个.tar.gz文件)

  3. 服务器上根目录下新建dbbackup文件夹

    1
    mkdir dbbackup
  1. 把本地压缩包上传到服务器dbbackup目录下(本地执行命令)

    1
    scp -P 48273 C:/Users/dragon/Desktop/imooc-movie.tar.gz manager@29.184.39.92:/home/manager/dbbackup/

    本地上传服务器成功
    本地上传服务器成功
    在服务器上manager根目录下查看,复制成功
    在服务器上manager根目录下查看,复制成功

  2. 将服务器上的压缩数据库解压:

    1
    tar xvf imooc-movie.tar.gz
  1. 将服务器上解压后的文件导入服务器线上的MongoDB数据库:

    1
    mongorestore --host 127.0.0.1:29374 -d imooc-movie ./dbbackup/imooc-movie-backup/imooc-movie/

    将服务器上解压后的文件导入服务器线上的MongoDB数据库
    导入成功后,查询服务器上的数据库内容:

    1
    2
    3
    4
    5
    mongo --port 29374
    show dbs
    use imooc-movie
    show tables
    db.users.find()

    查询线上数据库内容

三、导出本地单张表格或数据到线上数据库内

  1. 本地新建一个manager的用户
    本地新建一个manager的用户

  2. 本地将该条数据导出

    1
    mongoexport -d imooc-movie -c users -q "{'name':'manager'}" -o ./movie-users.json

    本地导出某条数据
    本地导出的json文件

  3. 上传到服务器目录下(本地执行命令)

    1
    scp -P 48273 C:/Users/dragon/Desktop/movie-users.json manager@29.184.39.92:/home/manager/dbbackup/
  4. 服务器上导入该条数据库内容:

    1
    mongoimport --host 127.0.0.1:29374 -d imooc-movie -c users ~/dbbackup/movie-users.json

    服务器上导入该条数据库内容

  5. 服务器上查询数据库,发现确实已导入成功:

    1
    2
    3
    mongo --port 29374
    use imooc-movie
    db.users.find()

四、删除线上数据库

  1. 删除数据库

    1
    2
    3
    mongo --port 29374
    use imooc-movie
    db.dropDatabase()

    删除线上数据库

  2. 删除集合

    1
    2
    3
    mongo --port 29374
    use imooc-movie
    db.users.drop()

    删除线上集合

五、配置数据库用户权限

  1. 配置超级管理员权限

    1
    2
    3
    mongo --port 29374
    use admin
    db.createUser({user: 'imooc_cases_owner', pwd: '******', roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]})

    (注:以上的“userAdminAnyDatabase”为用户管理员总权限,即只有具备该权限的用户,才能开通其他用户)
    成功开通数据库用户管理员权限:
    成功开通数据库用户管理员权限

  2. 授权admin数据库

    1
    2
    use admin
    db.auth('imooc_cases_owner', '******')
  3. 切换到其他数据库,分别创建普通管理员及备份管理员

    1
    2
    3
    use imooc_movie
    db.createUser({user: 'imooc_cases_manager', pwd: '******', roles: [{role: 'readWrite', db: 'imooc_movie'}]})
    db.createUser({user: 'imooc_cases_backup', pwd: '******', roles: [{role: 'read', db: 'imooc_movie'}]})

    成功开通imooc_movie数据库普通管理员权限:
    成功开通imooc_movie数据库普通管理员权限
    成功开通imooc_movie数据库备份员权限:
    成功开通imooc_movie数据库备份员权限

  1. 开启MongoDB验证模式

    1
    sudo vi /etc/mongod.conf

    找到#security,取消注释,同时增加:

    1
    2
    security:
    authorization: 'enabled'

    重启MongoDB服务:

    1
    sudo service mongod restart
  2. 重新进入数据库,发现没有权限了

    1
    2
    mongo --port 29374
    show dbs

    发现没有权限了

  3. 授权后才能查看数据库

    1
    2
    3
    use admin
    db.auth('imooc_cases_owner', '******')
    show dbs

    授权后才能查看数据库

  4. 直接以某个账户权限进入某个数据库

    1
    2
    mongo 127.0.0.1:29374/imooc_movie -u imooc_cases_backup -p ******
    show tables

六、将数据库从一台线上服务器迁移、合并、更新到另一台

  1. 在旧服务器上备份数据库

    1
    mongodump -h 127.0.0.1:29374 -d imooc-movie -u imooc_cases_backup -p ****** -o imooc-moive-backup

    (注:上面使用了备份账户来操作)

  2. 压缩要迁移的数据库

    1
    tar zcvf imooc-movie.tar.gz imooc-movie-backup

    若迁移单表:

    1
    mongoexport -h 127.0.0.1:29374 -d imooc-movie -c users -q "{'name':'manager'}" -o ./movie-users.json
  3. 将旧服务器上的压缩包下载到本地电脑上

    1
    scp -P 48273 manager@29.184.39.92:/home/manager/dbbackup/imooc-movie.tar.gz C:/Users/dragon/Desktop/

    若迁移单表:

    1
    scp -P 48273 manager@29.184.39.92:/home/manager/dbbackup/movie-users.json C:/Users/dragon/Desktop/
  4. 将本地电脑上的数据库包、单表上传到新的服务器上

    1
    2
    scp -P 48273 manager@29.184.39.92:/home/manager/dbnew/imooc-movie.tar.gz
    scp -P 48273 manager@29.184.39.92:/home/manager/dbnew/movie-users.json

    (注:由于暂时只有一台服务器,所以上述代码中先用旧服务器代替新服务器演示)

  5. 在新服务器上解压缩

    1
    tar xvf imooc-movie.tar.gz
  6. 不覆盖新服务器上原有的数据库,先切换到新的数据库,并创建对应的账户权限

    1
    2
    3
    4
    5
    mongo --port 29374
    use admin
    db.auth('imooc_cases_owner', '******')
    use imooc-movie-new
    db.createUser({user: 'imooc_movie_new', pwd: '******', roles: [{role: 'readWrite', db: 'imooc_movie_new'}]})
  7. 导入数据库到新的数据库内

    1
    mongorestore -h 127.0.0.1:29374 -d imooc-movie-new -u imooc-movie-new -p ****** ~/dbnew/imooc-movie/

    若迁移单表:

    1
    mongoimport -h 127.0.0.1:29374 -d imooc-movie-new -c users -u imooc_movie-new -p ****** ~/dbnew/movie-users.json

    建议上述命令都在本地或测试服务器上通过后,再到生产服务器上执行,避免造成严重的错误。

七、数据库的定时备份任务(24:00)

(一)利用系统定时任务,对数据库进行备份

  1. 创建定时脚本movie.backup.sh

    1
    2
    3
    mkdir tasks
    cd tasks
    sudo vi movie.backup.sh

    编辑内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/sh
    backupFolder=/home/manager/dbbackup/imooc_movie_backup
    dateNow=`date +%Y_%m_%d_%H%M`
    backFileName=imooc_movie_backup_$dateNow
    cd $backupFolder
    mkdir -p $backFileName
    mongodump -h 127.0.0.1:29374 -d imooc-movie -u imooc_cases_backup -p ****** -o $backFileName
    tar zcvf $backFileName.tar.gz $backFileName
    rm -rf $backFileName

    (注:这里为了防止本台服务器被攻击,备份后的数据库文件应该上传到其他云服务器更好)

  2. 创建备份目录

    1
    2
    3
    4
    cd
    mkdir dbbackup
    cd dbbackup
    mkdir imooc_movie_backup

    (注:如果已经有备份目录则无需重复创建)

  3. 尝试执行备份脚本

    1
    sudo sh ./tasks/movie.backup.sh

    成功运行定时备份数据库的脚本:
    成功运行定时备份数据库的脚本

  4. 启动系统定时任务设定

    1
    crontab -e

    (注:第一次打开会需要选择编辑器,建议选择2,即/bin/nano,为最简单的编辑器)
    设置测试定时任务(下面命令含义为10:47执行一次):

    1
    47 10 * * * sh /home/manager/tasks/movie.backup.sh

    等到10:47,发现果然执行了:

    1
    cd ~/dbbackup/imooc_movie_backup/

    果然执行了定时任务

(二)结合Node.JS将备份的数据库自动上传阿里云OSS

  1. 查看阿里云OSS Node.JS SDK文档

  2. 服务器上安装阿里云OSS SDK

    1
    npm install ali-oss
  3. 创建js文件

    1
    2
    cd tasks
    sudo vi db_backup_upload_alioss.js

    编辑内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    const OSS = require('ali-oss')
    const client = new OSS({
    region: 'oss-cn-shenzhen',
    accessKeyId: '*******',
    accessKeySecret: '********',
    bucket: '********'
    })
    const put = async () => {
    try {
    const parts = process.env.NODE_ENV.split('@')
    const fileName = `${parts[1].tar.gz}`
    const filePath = `${parts[0]}/${fileName}`
    const result = await client.put(`imooc_movie_backup/${fileName}`, filePath)
    console.log('result', result)
    } catch (err) {
    console.log(err)
    }
    }
    put()

    (注:需要Node版本在7以上才支持async/await)

  4. 修改上面创建的定时任务的脚本movie.backup.sh,传递process.env.NODE_ENV参数

    1
    2
    cd ~/tasks
    sudo vi movie.backup.sh

    编辑内容,在最下面增加命令:

    1
    NODE_ENV=$backupFolder@$backFileName node /home/manager/tasks/db_backup_upload_alioss/db_backup_upload_alioss.js

    如果这里发现movie.backup.sh脚本可执行但node命令并无执行,则是终端运行时找不到node命令导致的(原因看这里)。
    解决办法:

    1
    2
    which node
    NODE_ENV=$backupFolder@$backFileName /home/manager/.nvm/versions/node/v10.15.0/bin/node /home/manager/tasks/db_backup_upload_alioss/db_backup_upload_alioss.js
  5. 执行脚本试试

    1
    2
    cd ~/tasks
    ./movie.backup.sh

    (注:这里直接运行.sh脚本可能会报Permission denied错误,需要执行sudo chmod 777 movie.backup.sh命令进行授权)

  6. 成功上传到OSS
    成功上传到OSS
    在阿里云OSS浏览器中可以看到上传的数据库文件了


第十章 正式部署服务器和上线项目


一、使用git仓库上传代码

  1. 服务器上安装git

    1
    sudo apt-get install git
  2. 把服务器的ssh钥配置到git上

    1
    2
    cd .ssh
    cat id_rsa.pub

    把公钥复制到github或其他git平台上:
    把服务器的ssh公钥配置到git上
    这样配置后,就可以在服务器端克隆git仓库了。

  3. 在服务器上下载git仓库的后台代码

    1
    git clone git@github.com:shaolonger/practice-movie-website.git

    (其实通过pm2部署服务器上的后台代码,是不需要自己登录服务器去执行git clone的,通过下面第二步的部署即可)

二、通过pm2配置文件的方式,将git代码部署到服务器上,并启动服务

  1. 在本地项目根目录新建ecosystem.config.js
    编辑内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    module.exports = {
    apps: [{
    name: 'movie-website',
    script: './src/app.js',
    env: {
    NODE_ENV: 'development'
    },
    env_production: {
    NODE_ENV: 'production'
    }
    }],
    deploy: {
    production: {
    user: 'manager',
    host: ['29.184.39.92'],
    port: '48273',
    ssh_options: 'StrictHostKeyChecking=no',
    ref: 'origin/master',
    repo: 'git@github.com:shaolonger/practice-movie-website.git',
    path: '/home/manager/www/movie/production'
    }
    }
    }

    具体配置可以查看官方文档

  2. 服务器根目录下创建/www/website路径,用来存放线上代码

    1
    2
    3
    4
    5
    cd
    sudo mkdir www
    cd www
    sudo mkdir website
    sudo chmod 777 website
  3. 本地项目根目录下执行deploy部署命令

    1
    pm2 deploy ecosystem.config.js production setup

    (注:上面命令实际就是在本地通过pm2登录服务器,然后把git仓库下的代码clone –bare到指定的服务器目录下)
    注意,上面这步很可能出错:
    部署失败
    这里出错原因不明,但换成git bash后就成功了:
    git bash里部署成功
    服务器上部署的文件,其中current为线上跑起来的文件,source为源码:
    服务器上部署的文件

  4. 启动线上服务
    在本地项目根目录下执行启动命令:

    1
    pm2 deploy ecosystem.config.js production

    这里可能会出现的几个报错:

    1
    bash: pm2: command not found

    或者是:

    1
    /usr/bin/env: 'node': No such file or directory

    解决办法是把pm2和node加入环境变量路径,使得可以在主机全局下操作:

    1
    2
    3
    4
    which pm2
    which node
    sudo ln -s /home/manager/.nvm/versions/node/v10.15.0/bin/pm2 /usr/local/bin/
    sudo ln -s /home/manager/.nvm/versions/node/v10.15.0/bin/node /usr/local/bin/

    成功在本地开启线上pm2服务:
    成功在本地开启线上pm2服务

三、更新nginx配置

  1. 根据域名,重命名nginx配置文件

    1
    2
    cd /etc/nginx/conf.d
    mv test-37234.conf movie-shaolonger-com-37234.conf
  2. 更新配置文件

    1
    sudo vi movie-shaolonger-com-37234.conf

    编辑内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    upsteam movie_website {
    ...
    }
    server {
    server_name: movie.shaolonger.com
    location / {
    proxy_pass http://movie_website;
    }
    }

四、创建线上数据库并导入本地备份数据库

  1. 导出线下数据库

    1
    mongodump -h 127.0.0.1:29374 -d imooc-movie -u imooc_movie_manager -p ****** -o ./backup/
  2. 创建线上数据库、创建对应的用户权限

    1
    2
    3
    4
    5
    6
    7
    mongo --port 29374
    use admin
    db.auth('admin', '******')
    use movie-website
    db.createUser({user: 'movie-website-admin', pwd: '******', roles: [{role: 'dbAdmin', db: 'movie-website'}]})
    db.createUser({user: 'movie-website-runner', pwd: '******', roles: [{role: 'readWrite', db: 'movie-website'}]})
    db.createUser({user: 'movie-website-backup', pwd: '******', roles: [{role: 'read', db: 'movie-website'}]})
  3. 将线下数据库上传到服务器

  4. 线上导入数据库

    1
    mongorestore -h 127.0.0.1:29374 -d movie-website -u movie-website-runner -p ****** ~/backup/imooc-movie/
  5. 查看线上数据库

    1
    2
    mongo 127.0.0.1:29374/movie-website -u movie-website-runner -p ******
    show tables

五、更新pm2配置

  1. 修改ecosystem.config.js配置文件
    修改ecosystem.config.js配置文件
    这里的“post-deploy”,含义就是在服务器上执行pm2的前置动作,即先安装项目依赖(设置为淘宝镜像),然后执行grunt build来压缩代码,最后启动服务。

  2. 更新.gitignore配置,将项目根目录下的public/build文件夹剔除

    1
    2
    public/build
    public/build/*
  3. 将本地代码更新到git上,保证线上git仓库的代码是最新的

  4. 重新通过pm2部署代码并启动线上服务
    在本地项目根目录下执行:

    1
    2
    pm2 deploy ecosystem.config.js production setup
    pm2 deploy ecosystem.config.js production

    这里与上面第一次部署一样,可能会出现报错:

    1
    2
    bash: npm: command not found
    bash: grunt: command not found

    解决办法是把npm和grunt加入环境变量路径,使得可以在主机全局下操作:

    1
    2
    3
    4
    which npm
    which grunt
    sudo ln -s /home/manager/.nvm/versions/node/v10.15.0/bin/npm /usr/local/bin/
    sudo ln -s /home/manager/.nvm/versions/node/v10.15.0/bin/grunt /usr/local/bin/

    还有可能出现bcrypt模块的报错,解决办法是取消淘宝镜像,改回使用npm install即可。

  5. 重新部署成功
    重新部署成功

  6. 到服务器上检查是否顺利开启服务

    1
    pm2 list

    发现服务报错:
    服务报错
    输入pm2 logs查看日志,发现是bcrypt模块错误导致的,猜测可能是bcrypt版本过旧,在本地deploy远程时,远程未顺利安装bcrypt导致。
    于是进入到远程目录下:

    1
    2
    cd ~/www/movie/production/current/
    npm rebuild

    重新在本地代码目录下执行deploy命令,然后再到服务器上检查是否正常执行,发现还是报错:
    线上mongodb报错
    这里实际上是因为我们用的connect-mongo这个依赖版本太低导致,本地更新该模块并git push到远程,然后再deploy。

    1
    npm install connect-mongo@lastest
  7. 其他错误:环境变量
    如果发现服务里接收到的环境变量不是production,则需要检查ecosystem.config.js里是否设置了环境变量:
    检查环境变量配置是否为production

六、更新nginx配置文件,开放服务器静态资源访问

1
2
cd /etc/nginx/conf.d/
sudo vi movie-shaolonger-com-37234.conf

增加一段location的配置:

1
2
3
location ~* ^.+\.(jpg|jpeg|git|png|ico|css|js|pdf|txt) {
root /www/movie/production/current/public;
}

七、浏览器尝试打开刚部署的网站

发现可以成功打开了:
发现可以成功打开网站了


第十一章 使用和配置更安全的HTTPS协议


一、SSL证书的分类

  1. DV SSL
  2. OV SSL
  3. EV SSL

二、较为可靠的证书颁发机构

  1. 赛门铁克(Symantec)
  2. GeoTrust
  3. TrustAsia

三、可选的免费SSL证书颁发机构

  1. 又拍云
  2. 七牛云
  3. 腾讯云
  4. 阿里云
  5. Let’s Encrypt

四、使用腾讯云申请免费的DV SSL证书

  1. 选择申请证书
    选择申请证书

  2. 填写相关的资料
    填写相关的资料

  3. 选择手动DNS验证
    选择手动DNS验证

  4. 到阿里云内添加DNS解析
    到阿里云内添加DNS解析1
    到阿里云内添加DNS解析2

  5. 回到腾讯云上,刷新即可看到证书已成功颁发
    证书已成功颁发

  6. 下载证书,并上传服务器
    下载证书
    将Nginx文件夹下的证书上传到服务器上:
    将Nginx文件夹下的证书上传到服务器上

  7. 到服务器上,把下载的ssl证书放到/www/ssl文件夹下

    1
    2
    3
    4
    5
    cd www/
    mkdir ssl
    cd
    mv 1_* ./www/ssl/
    mv 2_* ./www/ssl/
  8. 修改nginx配置文件
    参考腾讯云官方文档来修改:
    腾讯云官方文档

    改写/etc/nginx/conf.d/movie-shaolonger-com-37234.conf:

    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
    32
    33
    34
    35
    36
    upstream movie_website {
    server 127.0.0.1:37234;
    }
    server {
    listen 80;
    server_name movie.shaolonger.com;
    return 301 https://movie.shaolonger.com$request_uri;
    }
    server {
    listen 443;
    server_name movie.shaolonger.com;
    ssl on;
    ssl_certificate /home/manager/www/ssl/1_test.shaolonger.com_bundle.crt;
    ssl_certificate_key /home/manager/www/ssl/2_test.shaolonger.com.key;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
    ssl_prefer_server_ciphers on;

    if ($ssl_protocol = "") {
    rewrite ^(.*) https://$host$1 permanent;
    }

    location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Nginx-Proxy true;
    proxy_pass http://movie_website;
    proxy_redirect off;
    }

    location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|js|pdf|txt) {
    root /home/manager/www/movie/production/current/public;
    }
    }

    保存后重载nginx:

    1
    sudo nginx -s reload
  9. 打开网站https://movie.shaolonger.com
    https协议已生效,还可以看到证书信息:
    https协议已生效

0%