Essay 项目部署
虽然我之前写过有关Node项目部署的文章,但是回头看来还是有些乱,而且随着时间推移可能有些已经不适用了。本文将基于 Essay 这个开源项目为例,详细介绍如何在服务器上部署Node项目。实践过程中我个人踩了一些坑,希望看到本文的朋友少踩一些坑,皆大欢喜
服务器选择
首先服务器我使用的 Ubuntu14.4,我也实践过CentOS,但是我还是推荐Ubuntu,配置起来要简单些。
软件安装
# ubuntu 14.4 node环境安装脚本
sudo apt-get update
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4
sudo echo "deb [ arch=amd64 ] https://repo.mongodb.org/apt/ubuntu trusty/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 vim wget curl git nginx lsof
service mongod start
service nginx start
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
source ~/.nvm/nvm.sh
nvm install v8.12.0 && nvm use 8.12.0 && nvm alias default 8.12.0
npm i pm2 yarn -g
上面的命令安装了mongodb vim wget curl git nginx lsof nvm nodejs pm2 yarn
常用软件,并启动了Nginx和mongod服务,把代码直接复制到命令行运行即可
防火墙设置
Ubuntu的防火墙设置特别简单,内置了ufw
命令简化配置操作
# https 部署失败可能是端口关闭导致的,开启80 443端口
ufw allow 80 # 开启 80 端口
ufw allow 433 # 开启 443 端口
ufw allow 3000 # 开启 3000 端口
ufw allow 3010 # 开启 3010 端口
ufw delete allow [port] # 删除某端口
ufw enable # 开启
ufw disable # 关闭
ufw status # 状态查询
ufw reload # 重启
通常情况下80 、22、443这些端口默认是开启的,你可以通过ufw status
命令查看是否已开启,有些云主机需要到管理后台开启,比如阿里云。另外可以通过 ufw allow [port]
开启指定的端口。443端口是https默认端口,后面会配置https,所以如果配置失败,很可能就是端口没开启导致的
如果端口被占用,可以使用下面命令释放端口
lsof -i:80 # 查看 80 端口应用程序的pid
kill -9 $pid # 关掉 80 端口应用程序
免密码登录
本机要与服务器连接,通常使用ssh,ssh -p 22 root@116.196.17.78
,但是每次连接都需要输入密码,因此配置免密登录是很有必要的
生成公钥
公钥需要在本机和服务器生成两份,如果你本机已经安装了Git,可能已经生成过了,具体查看用户目录下.ssh
文件夹中是否有id_rsa.pub
文件。如果还没有生成,执行下面命令生成(本机和服务器)
git config --global user.name "wmui" # 换成自己的名字
git config --global user.email "qq22337383@gmail.com" # 换成自己的邮箱
ssh-keygen -t rsa -C "qq22337383@gmail.com" # 换成自己的邮箱
生成后需要把本机的公钥添加到服务器,如果你是Linux系统,可以使用ssh-copy-id -i ~/.ssh/id_rsa.pub root@116.196.17.78
复制到服务器。如果是windows系统,服务器上执行echo "[your public key]" > ~/.ssh/authorized_keys
进行拷贝
如果复制失败,可能是因为服务器的.ssh
没有写入权限,执行下面的命令进行授权
chmod 700 -R .ssh
cd .ssh
chmod 600 authorized_keys
完成以上操作就完成了免密登录
配置Nginx
Nginx主要是为了反向代理和配置https,通过域名形式访问网站
https证书可以在腾讯云免费申请,申请好后把nginx证书复制到/root/ssl
目录下
在/etc/nginx/conf.d/
下新建essay.conf
文件,内容如下
upstream www {
server 127.0.0.1:3025;
}
server {
listen 80;
listen 443;
server_name www.86886.wang;
ssl on;
ssl_certificate /root/ssl/1_www.86886.wang_bundle.crt;
ssl_certificate_key /root/ssl/2_www.86886.wang.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 ($scheme = http) {
rewrite ^(.*) https://$host$1 permanent;
}
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Nginx-proxy true;
proxy_pass http://www;
proxy_redirect off;
}
}
完成后别忘了做域名解析,把域名解析到对应的ip,最后执行sudo nginx -s reload
重启nginx
部署项目
如果你需要配置自动化部署,一定要在clone项目前配置,不然到最后你需要把项目先删掉、再配置、再clone项目,所以说顺序很重要
无论是Github还是Gitee配置的流程都是一样的,登录后点击设置的SSH选项,新增SSH key
,复制服务器和本机的id_rsa.pub
文件中的内容,添加两个配置即可
clone项目
这里我直接clone到了root目录下
git clone https://github.com/wmui/essay
在项目下执行pm2 deploy ecosystem.config.js production setup
,这是pm2的初始化操作
pm2有一个问题,无法识别nvm中的环境变量,所以需要打开root目录下.baserc
文件,把下面两行代码移动到最上面,这算是pm2的一个坑
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
完成以上操作,在本地项目下执行pm2 deploy ecosystem.config.js production
便可以自动化部署,现在应该可以通过域名的形式访问了
数据备份和导入
当更换了服务器,数据的备份和导入是很总要的,
# 使用默认的命令行而不是mongo shell
mongodump -h 127.0.0.1:27017 -d essay -o Documents/essay-backup # 备份
mongorestore -h 127.0.0.1:27017 -d essay /root/essay-backup/essay # 导入
mongo && use essay
修改数据
在mongo shell中执行下面的命令,可以修改数据库中的字段名和数据
// mongodb 数据批量替换数据
db.getCollection('articles').find({content: {$regex: 'https://blog.86886.wang/public'}}).forEach(function (item) {
item.content = item.content.replace(/(http|https):\/\/www.86886.wang\/public/g, 'https://cdn.86886.wang/blog');
db.getCollection('articles').save(item);
})
// 修改字段名: db.collection.update(query, update, options)
db.articles.update({},{$rename : {'createdAt' : 'created_at'}}, false, true)
系统重装
如果重装了系统,ssh可能会无法连接到服务器,这是因为.ssh/known_hosts
中的ip授权已经失效,所以需要把相关ip授权删除,然后就可以连接了