node.js 线上服务部署

Node.js 线上服务部署

注意:以下文章没有设么逻辑,只是对一下线上部署的记录

1. 阿里云域名服务器购买

2. 远程登录

  1. 进入命令行
  2. 输入 ssh 用户名@公网 IP ssh [email protected]
  3. 切换到英文输入法 按照提示输入 yes
  4. 输入密码
  5. fdisk -l 查看挂载硬盘
  6. df -h 查看硬盘使用情况
  7. ctrl + D 退出远程
  8. adduser [name] 按照提示添加用户
  9. gpasswd -a mjz sudo 给 mjz 用户升级权限
  10. sudo visudo 进入到配置权限文件
  11. 找到 root ALL=(ALL:ALL) ALL 这一行 在他下边添加 mjz ALL=(ALL:ALL) ALL 使得用户 mjz 有与 root 一样的权限
  12. srevice ssh restart 重启
  13. SSH 实现无密码登录
    • 登录到服务器
    • 命令行执行 ssh-keygen -t rsa -b 4096 -C “[email protected]” 一路回车
    • 继续命令行 eval “$(ssh-agent -s)” 回车 跑起来代理
    • 加入到代理中 ssh-add ~/.ssh/id_rsa 回车
    • cd .ssh 进入 .ssh 目录下 vi authorized_keys 回车 写授权文件
    • shift + : 然后输入 wq! 回车 完成授权文件
    • 回到本地的主屏幕 进入到本地的 .ssh 目录下拷贝公钥 cat id_rsa.pub
    • 在回到服务器命令行 vi authorized_keys 编辑,将公钥粘贴过来
    • shift + : 输入 wq! 将内容保存
    • chmod 600 authorized_keys 修改权限
    • sudo srevice ssh restart 重启 ssh 服务
    • 完成
  14. 目前登录的都是 Linux 默认端口 :22,出于安全考虑需要修改默认端口
    • 进入服务器命令行输入 sudo vi /etc/ssh/sshd_config 点击 i 修改配置文件
    • 找到 Port 配置项修改端口 Port 11111 末尾添加配置项 AllowUsers mjz
    • 点击 esc 退出编辑模式 shift + : 输入 wq! 回车保存文件
    • 进入阿里云重启实例
    • 登录时 命令改为 ssh -p [port] mjz@[IP] ssh -p 39999 [email protected]
  15. 关闭 root 密码登录
    • 再次进入 sshd_config 配置中 sudo vi /etc/ssh/sshd_config
    • 找到 PermitRootLogin 设置为 no 退出保存
  16. 配置安全项、防火墙

    • 进入服务器命令行
    • sudo apt-get update & sudo apt-get upgrade 更新
    • sudo iptables -F 清空所有 iptables 规则
    • sudo vi /etc/iptables.up.rules 重新编写规则文件

      *filter
      
      
      # 允许所有建立起来的链接
      
      -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
      
      # 允许所有出去的流量
      
      -A OUTPUT -j ACCEPT
      
      # 允许https 请求下的链接
      
      -A INPUT -p tcp --dport 443 -j ACCEPT
      -A INPUT -p tcp --dport 80 -j ACCEPT
      
      
      # 设置只能从 39999 端口登录服务器
      
      -A INPUT -p tcp -m state --state NEW --dport 39999 -j ACCEPT
      
      
      # 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  
    • 编辑完成后保存

    • 告诉 iptables 配置文件位置 sudo iptables-restore < /etc/iptables.up.rules
    • 查看防火墙状态 sudo ufw status
    • 开启防火墙 sudo ufw enable
    • 设置开机自动启动防火墙

      • 编写文件 sudo vi /etc/network/if-up.d/iptables
      • 写入脚本
      
      #!/bin/sh
      
      iptables-restore /etc/iptables.up.rules
      • 保存退出
      • 给与脚本执行权限 sudo chmod +x /etc/network/if-up.d/iptables
    • 安装 Fail2ban sudo apt-get install fail2ban
    • 更改 fail2ban 配置文件 sudo vi /etc/fail2ban/jail.conf
    • 查看状态 sudo service fail2ban status
    • 停止 sudo service fail2ban stop
    • 开启 sudo service fail2ban start

3. 搭建 node.js 生产环境

  • 进入服务器命令行
  • 更新 sudo apt update & sudo apt upgrade
  • 安装一些之后会用到的工具 sudo apt install vim openssl build-essential libssl-dev wget curl git
  • 安装 nvm 用来控制 node 版本 wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
  • 安装后重新登录一次
  • nvm install v8.10.0 安装 node
  • nvm use v8.10.0 nvm 指定使用的 node 的版本
  • nvm alias default v8.10.0 设置 node 默认使用版本
  • npm config set registry https://registry.npm.taobao.org 设置淘宝镜像
  • 增加系统文件监控数目 echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
  • npm install -g pm2 全局安装 pm2
  • 测试 node 服务

    • 创建 一个 node 服务器
    const http = require('http');
    
    http
        .createServer(function(req, res) {
            res.writeHead(200, { 'Content-Type': 'text/plain' });
            res.end('this is test vi');
        })
        .listen(8081);
    
    console.log('server runing on http://47.xx.139.xx:8081');
    • node app.js 启动
    • 开启防火墙对 8081 的限制
    • 新开一个命令行链接到服务器,并打开防火墙配置文件 sudo vi /etc/iptables.up.rules
    • 增加一行配置 -A INPUT -p tcp –dport 8081 -j ACCEPT 允许 8081 访问
    • 保存后重启防火墙 sudo iptables-restore < /etc/iptables.up.rules
    • 如果有问题就在阿里云中配置安全组规则,然后重新启动实例
    • 访问 http://47.xx.139.xx:8081 即可
  • 开启一个静态站点,

    • pm2 是一个 node.js 部署和进程管理工具,通过它可以实现 node.js 后台运行(不是向上边那样关闭命令行服务就没了)和出错自动重启
    • 没有安装的话就安装 npm install -g pm2
    • 运行 pm2 start app.js 即可运行 node 服务
    • pm2 list 列出当前运行的 pm2-node 服务
    • pm2 show [App name|id] 查看详细信息
    • pm2 log app 查看实时日志

4. nginx 实现反向代理

  • 先更新安装包 sudo apt update & sudo apt upgrade
  • 安装 nginx sudo apt install nginx
  • 查看安装版本 nginx -v
  • 进入 nginx 配置文件夹 cd /etc/nginx/conf.d
  • 编辑配置文件 sudo vi mjz-8081.conf
upstream mjz {
    server 127.0.0.1:8081;
}

server {
    listen 80;
    server_name 47.XX.139.XX;

    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://mjz;
        proxy_redirect off;
    }
}
  • 保存后测试 sudo nginx -t 检查配置有没有错误
  • 重启一下 nginx sudo nginx -s reload
  • 这样在浏览器地址栏 直接使用 ip 地址不加上 8081 端口号 (http://47.XX.139.XX/)一样可以得到 8081 端口的返回
  • 隐藏返回数据 Headers 中的服务器信息
    • 进入 nginx 主配置文件 cd /etc/nginx
    • 编辑主配置文件 sudo vi nginx.conf
    • 在 http 配置中 开启 server_tokens off;
    • 保存退出 重启 nginx sudo nginx -s reload

5. 解析域名到服务器 IP

  • 域名是需要域名解析服务器的,也就是需要 DNS 服务器将域名解析到我们的服务器 IP 地址
  • 一个服务器 IP 可以托管很多个 网站应用,但是一个域名只能对应某一个 IP 地址
  • 域名需要提供一个 DNS 地址,这个 DNS 会负责解析和如何转向这个 DNS 地址
  • 阿里云 的 DNS 在 ‘云解析 DNS’ 中设置
  • 在解析设置中可以添加解析记录
    • 其中 ‘A 记录’ 表示将域名指向一个 IP 地址 添加时的主机记录如果是 ‘@’ 则直接解析主域名 如果是 ‘*’ 就是泛解析,匹配所有其他域名
    • CNAME 记录 是将域名指向另一个域名
  • 添加一个解析记录 A 类型 主机记录 www 记录值为服务器 IP 地址
  • 添加 CNAME 记录 一般用来重新指向静态资源域名,在阿里云中可以设置对象存储 OSS 的域名管理,但是需要域名备案

6. 安装 mongoDB 数据库

  • 正常开发中数据库要与程序分离,不在一个服务器,但是这里处于成本考虑将数据库就安装在程序所在的服务器
  • 进入到服务器命令行
  • 安装 mongoDB 教程

    • 导入公钥所使用的包管理系统 sudo apt-key adv –keyserver hkp://keyserver.ubuntu.com:80 –recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
    • 创建对应 Ubuntu 版本的文件列表 echo “deb [ arch=amd64,arm64,ppc64el,s390x ] http://repo.mongodb.com/apt/ubuntu xenial/mongodb-enterprise/3.6 multiverse” | sudo tee /etc/apt/sources.list.d/mongodb-enterprise.list
    • 更新本地包 sudo apt update
    • 安装 mongoDB sudo apt-get install -y mongodb-enterprise
    • 上一步安装较慢,我们可以将镜像切换到阿里云的
      • echo “deb [ arch=amd64,arm64 ] http://mirrors.aliyun.com/mongodb/apt/ubuntu xenial/mongodb-org/3.6 multiverse” | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
      • 更新源 sudo apt update
      • 重新执行下载 sudo apt-get install -y mongodb-org
    • 开启 mongodb 服务 sudo service mongod start
    • cat /var/log/mongodb/mongod.log 检查 mongodb 日志文件判断是否开启服务
    • 或者输入 mongo 查看
    • 如果连接失败,检查是否防火墙没有开启对应端口的访问
    • 打开防火墙配置文件 sudo vi /etc/iptables.up.rules 添加
    
    # 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 ESTABLISHED -j ACCEPT
    • sudo iptables-restore < /etc/iptables.up.rules 重载防火墙
    • 再次输入 mongo 就进入到 mongodb 的实例中
    • sudo service mongod stop 停止服务
    • sudo service mongod restart 重启服务
    • 更改 mongodb 的默认端口号

      • 进入到 MongoDB 配置文件 sudo vi /etc/mongod.conf
      • 更改配置项 net: port: 19999 为预期端口号
      • 重启 mongo 服务 sudo service mongod restart
      • 再更改一次防火墙设置
      
      # mongodb connect
      
      -A INPUT -s 127.0.0.1 -p tcp --destination-port 19999 -m state --state NEW,ESTABLISHED -j ACCEPT
      -A OUTPUT -d 127.0.0.1 -p tcp --source-port 19999 -m state --state ESTABLISHED -j ACCEPT
      • sudo iptables-restore < /etc/iptables.up.rules 重载防火墙
      • 输入 mongo –port 19999 完成链接进入

7. node 上线服务器

  • 开启一个第三方 git 平台托管代码
  • 建立第三方 git 平台与 服务器的联系
    • 将服务器的 ssh 公钥也存到 git 平台
    • 进入服务器命令行 cat .ssh/id_rsa.pub 复制公钥到 git 平台
    • 在服务器中将项目克隆下来
  • node 项目代码中配置 pm2 用来部署和发布的配置文件

    • 创建 ecosystem.json 配置文件 http://pm2.keymetrics.io/docs/usage/deployment/#complete-tutorial
    {
       "apps": [
          {
             "name": "Website",
             "script": "app.js", // 入口
             "env": {
                "COMMON_VARIABLE": true
             },
             "env_production": {
                "NODE_ENV": "production"
             }
          }
       ],
       "deploy": { // 部署配置
          "production": {
             "user": "mjz",
             "host": ["47.XX.139.XX"], // 阿里云上的服务器IP地址
             "port": "39999", // 端口号
             "ref": "origin/master", // 确定那个分支
             "repo": "[email protected]:xxx/node-website.git", // 仓库地址
             "path": "/www/website/production", // 程序在服务器上的路径
             "ssh_options": "StrictHostKeyChecking=no", // 取消 key 校验
             "post-deploy" : "npm install && pm2 startOrRestart ecosystem.json --env production", // 克隆后执行命令 安装依赖
             "env"  : {
                "NODE_ENV": "production"
              }
          }
       }
    }
    • 将代码同样提交到 git 仓库中
    • 服务器中创建 sudo mkdir /www ||| cd /www ||| sudo mkdir website 并进入到 /www/website 文件夹下
    • 修改 在服务器 /www/website 文件夹下的权限 cd /www & sudo chmod 777 website 变为可读可写权限
    • 重开一个命令行 进入到本地的项目文件夹 cd express-demo/
    • 在本地安装 pm2 sudo yarn global add pm2
    • 让 pm2 连上服务器 从服务器创建发布项目所需要的文件夹 pm2 deploy ecosystem.json production setup
    • 这个时候服务器 /www/website 下就有了 production 项目文件夹
    • 其下又有
      • current 文件夹,当前运行文件夹
      • source 源代码
      • shared 日志文件
    • pm2 使用原理
      • 通过本地 pm2 工具在本地命令行登录服务器,然后通知服务器从 git 仓库将代码clone 到服务器部署到相应文件夹,然后等待进一步操作

8. 本地控制代码更新和服务器重启

  • 进入服务器终端 编辑 .bashrc vi .bashrc 将一下内容注释掉
# If not running interactively, don't do anything
#case $- in
#    *i*) ;;
#      *) return;;
#esac
  • 保存后通过 source .bashrc 加载这个 .bashrc
  • 进入到开发项目文件夹 执行 pm2 deploy ecosystem.json production 将项目重新发布
  • 阿里云中添加一个域名解析记录 记录类型为 A 主机记录为 www 记录值为服务器 IP
  • 进入到服务器终端,修改 nginx 配置

    • cd /etc/nginx/conf.d/ 创建 mjz-3322.conf 配置文件
    upstream mjz {
        server 127.0.0.1:3322;
    }
    
    server {
        listen 80;
        # 下边的这个如果是域名需要备案,没有备案不让访问 这里暂时使用 47.XX.139.XX IP 代替
        server_name 47.XX.139.XX;
    
        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://mjz;
            proxy_redirect off;
        }
    }
    • 保存后执行 nginx 重启 sudo nginx -s reload
    • 设置防火墙对对应端口的放行
    • sudo vi /etc/iptables.up.rules 添加如下两行
    -A INPUT -s 127.0.0.1 -p tcp --destination-port 3322 -m state --state NEW,ESTABLISHED -j ACCEPT
    -A OUTPUT -d 127.0.0.1 -p tcp --source-port 3322 -m state --state ESTABLISHED -j ACCEPT
    • 保存后退出
    • 阿里云中对应实例的安全组添加对应端口号的配置规则 重启实例
    • 本地项目目录中 pm2 deploy ecosystem.json production setup
    • sudo nginx -s reload 重启 nginx 服务
  • 测试部署流程

    • 更改项目内容
    • git 提交到仓库 git add . & git commit -m ‘debug’ & git push origin master
    • 重新发布项目 pm2 deploy ecosystem.json production
    • 浏览器测试 完成

9. 配置 HTTPS

  • 将 ssl 证书的 key 上传到服务器用户根目录 Nginx scp -P 39999 ./xxx.key [email protected]:/home/mjz
  • 将 ssl 证书的 crt 上传到服务器用户根目录 Nginx scp -P 39999 ./xxx.crt [email protected]:/home/mjz
  • 将证书等保存到服务器 /www/ssl 下
  • 进入对应网址的 nginx 配置文件中编辑
  • 边界 server 部分代码

你可能感兴趣的:(服务器部署上线)