Node.js 线上服务部署
注意:以下文章没有设么逻辑,只是对一下线上部署的记录
1. 阿里云域名服务器购买
2. 远程登录
- 进入命令行
- 输入 ssh 用户名@公网 IP
ssh root@47.XX.139.XX
- 切换到英文输入法 按照提示输入 yes
- 输入密码
- fdisk -l 查看挂载硬盘
- df -h 查看硬盘使用情况
- ctrl + D 退出远程
- adduser [name] 按照提示添加用户
- gpasswd -a mjz sudo 给 mjz 用户升级权限
- sudo visudo 进入到配置权限文件
- 找到 root ALL=(ALL:ALL) ALL 这一行 在他下边添加 mjz ALL=(ALL:ALL) ALL 使得用户 mjz 有与 root 一样的权限
- srevice ssh restart 重启
- SSH 实现无密码登录
- 登录到服务器
- 命令行执行 ssh-keygen -t rsa -b 4096 -C “youxiang@163.com” 一路回车
- 继续命令行 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 服务
- 完成
- 目前登录的都是 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 mjz@47.XX.129.XX
- 关闭 root 密码登录
- 再次进入 sshd_config 配置中 sudo vi /etc/ssh/sshd_config
- 找到 PermitRootLogin 设置为 no 退出保存
配置安全项、防火墙
- 进入服务器命令行
- 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 服务
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 数据库
7. node 上线服务器
- 开启一个第三方 git 平台托管代码
- 建立第三方 git 平台与 服务器的联系
- 将服务器的 ssh 公钥也存到 git 平台
- 进入服务器命令行 cat .ssh/id_rsa.pub 复制公钥到 git 平台
- 在服务器中将项目克隆下来
node 项目代码中配置 pm2 用来部署和发布的配置文件
{
"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": "git@gitee.com: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 mjz@47.XX.139.XX:/home/mjz
- 将 ssl 证书的 crt 上传到服务器用户根目录 Nginx scp -P 39999 ./xxx.crt mjz@47.XX.139.XX:/home/mjz
- 将证书等保存到服务器 /www/ssl 下
- 进入对应网址的 nginx 配置文件中编辑
- 边界 server 部分代码