线上项目搭建生产环境

搭建线上环境需要做什么?
1、购买域名
2、购买服务器(就是一台带外网ip的虚拟电脑)。
3、配置服务器应用环境(用户权限、无密码登录、nodeJs应用的环境、必备依赖包、组件的安装和搭建、端口的转发、SSL证书的生产和配置、nginx的安装和配置、防火墙本地数据库自动备份的机制)
4、安装配置数据库(如果不用成本较高的云数据库,服务器的本地数据库涉及到数据库角色,读写权限,自动备份机制)
5、通过网络提供商的资源及平台对域名进行备案,接受监管。如果想用短信服务,邮件服务或者基于微信公众号小程序的服务那么备案是逃不过去的,如果在国外生活并且不使用上述的服务,那么可以不备案。
6、项目远程部署发布与更新(可以粗暴的把本地项目拷贝上传到服务器中启动,但是这样比较低效,而且容易出错,现在可以选择使用私密git仓库这种平台来把代码自动部署到线上,在线上进行服务的重启,让整个过程自动化傻瓜化,来解决效率的问题)
总结:搞定上述几大块,就是具备有一定运维能力的工程师了,距离一个合格的运维工程师还是差很远很远。

域名选购经验:
平台选择:www.22.cn爱名网或者阿里云(服务器配套域名,域名备案更方便一点)或者goDaddy(在国外注册域名,很难讲以后国内服务器部署上线是否会阻挠)。
域名选择:全英文>全数字>拼音+数字。域名越短越好,越好记越好。域名后缀不要选择太个性话后缀,不太稳定,备案时可能会遇到小困难。.cn .cc .net都行。

阿里云域名备案:
个人:身份证
单位:单位证件、单位备案负责人证件(电子版照片)
首次备案和再次备案:从未备案过就是首次备案,首次备案,备案的域名是不允许线上访问的,也就是在备案前域名不能投入使用,备案期间要关闭掉服务。再次备案,不受限制,但是需要网站内容和备案主体符合。接入备案,在阿里云备案系统中提交接入申请-初审 7小时左右网站就可以正常访问,仅限使用在ECS或虚拟主机上,如果审核失败,需要根据失败原因进行修改,之后再次提交。

服务器选择:
服务器厂商选择:尽量选择大厂商或者知名厂商的主机(阿里云ECS、亚马逊AWS、Linode、DigitOcean/Heroku、以及勉强入围青云/Ucloud/百度云),不要图便宜。尽量选择国内主机,备案和审核通过快,远程操作快。
评判服务器配置是否满足业务需求:1核1G可以对外提供2-3w请求量(几百人到上千人没问题),面对上万人数的话可以选择2核4g,人数再多的话可以买多台的服务器,做负载均衡。
IP:如果我们有好多台内网阿里云主机的话,可以通过阿里云内网ip互相访问,速度非常快。外网ip是给客户用的。

ssh远程登录服务器:
第一次登录: ssh root@ip,会说是否把服务器指纹加入到本地信任列表中。
如果购买时购买了数据盘(可以用fdisk -l来查看数据盘情况,  df -h 来查看硬盘使用情况),这个数据盘需要额外的挂载,如果没有买数据盘,阿里云服务器默认给我们挂载了一个硬盘40G,这个硬盘用来安装操作系统,如果我们把网站系统跑在这个硬盘上,也是可以的,但是一旦重装系统后所有网站数据都会丢失。如果我们挂载了自己买的数据盘的话,是不用担心这个问题的。
如果买服务器时未买数据盘,购买数据盘:https://help.aliyun.com/document_detail/25445.html?spm=a2c4g.11186623.6.676.4af21846NK4gOS
挂载数据盘:https://help.aliyun.com/document_detail/25446.html?spm=a2c4g.11186623.6.679.5d8a6a07Qc9zak
挂载后,数据盘格式化:https://help.aliyun.com/document_detail/25426.html?spm=a2c4e.11153987.0.0.59df779d57PtYP
若嫌输入[email protected]麻烦,可以通过~下的.zshrc(前提下载过zsh命令工具)配置软连接:cd 。subl .zshrc 编辑,增加一行 alias ssh_star="ssh [email protected]"。保存。source .zshrc重新载入一下。输入ssh_star就会自动调用ssh [email protected]。但若我们有几个服务器要登录管理,输密码也很麻烦,后面会介绍通过私钥认证方式无密码登录。

开发项目需要安装的基本工具包
1、sudo apt-get install git vim openssl build-essential lib ssh-dev wget curl
2、安装nvm(全系统级的切换node.js版本,绿色,安全,尤其在紧急升级项目所倚赖的版本时候,无副作用):
注意:如果安装成功但执行nvm ls报错,nvm: command not found。
1、进入nvm安装到文件目录,cd ~/.nvm。2、查看目录下文件列表。3、若无.bash_profile文件,则创建该文件:3.1 touch .bash_profile。3.2 vi .bash_profile。3.3将下部分文件粘贴至.bash_profile文件。export NVM_DIR="$HOME/.nvm" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm。(此语句是配置文件,与自己电脑有关,若不知道,可运行如下命令,会提示这段语句,curl-o-https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh| bash)。3.4保存文件,关闭此文件。3.5更新刚配置的环境变亮,source .bash_profile。4、输入nvm命令,验证是否成功。
nvm基本使用:1、nvm install v10.15.1下载特定nodeJS版本。2、切换当前使用的node版本vm use v10.15.1。设置使用的默认node版本,nvm alias default v10.15.1。

配置root及应用帐号权限:
root权限是最高权限,我们希望增加几个有各自权限的账户
创建新帐号:adduser xxx(用户名) 创建用户名(别忘记),接下来会让你设置 输入密码(别忘记)和一些个人信息(可不填)。
删除账号:userdel xxx(用户名)。
查看所有的用户信息:
新账号权限赋予第一步:gpasswd -a xxx(账户名) sudo,把xxx加入具有sudo权限的队列中(此时,该账户在sudo队列中)。
新账号权限赋予第二步:sudo visudo,我们需要找到User privilege(权限) specification(规范),它下面root ALL=(ALL:ALL) ALL再添加一行,xxx ALL(该规范对所有sudo生效)=(ALL(xxx可以以任何用户来执行命令):ALL(xxx可以以任何组来执行命令)) ALL(规则适用于所有命令),一句话,xxx只要用sudo 就可以运行任何root能运行的命令。
保存:control+x,之后shift+y ,回车,保存完毕。
测试:现在ssh xxx@ip 去登录远程服务器看看。
问题:1、如果登不上,可以先用root登录,然后执行service ssh restart重启一下,再去登录。

配置SSH无密码登录:
无密码登录原理:本地有一个私钥,通过私钥生成公钥传到服务器,服务器通过密钥算法对比,对比成功则登录成功。
查看本地私钥是否存在:找到cd .ssh文件并进入(ls -a可以找到隐藏文件),看到有id_rsa.pub(公钥)、id_rsa(私钥)、known_hosts(把id加入信誉列表)。如果没有呢,新建(mkdir)一个.ssh文件,然后在外面执行ssh-keygen -t rsa -b 4096 -C "[email protected]",接下来会询问你把rsa文件存在哪里,默认会存在.ssh文件中。
开启ssh代理:eval "$(ssh-agent -s)"
把key加入代理中:ssh-add ~/.ssh/id_rsa, 到这一步,本地的ssh已经配置好了。
远程服务器ssh配置第一步:同上,配置ssh。
远程服务器ssh配置第二步:在.ssh目录下,vi authorized_keys(管理授权的文件),新建一个authorized_keys文件。
远程服务器ssh配置第三步:把想要登录到远程服务器的主机的公钥放在远程服务器的authorized_keys文件中(cat显示出来,复制黏贴),当主机想要登录服务器时,远程服务器会验证之前放在authorized_keys中的公钥和他登录时提交的私钥,算法匹配的话,登录成功。
远程服务器ssh配置第三步:授权chmod 600 authorized_keys(修改authorized_keys文件的权限),sudo service ssh restart (重启ssh服务)。
注意:如果登录还是要密码。我把我的sshd.config里面的RSAAuthentication no,PubkeyAuthentication no。改为RSAAuthentication yes,PubkeyAuthentication yes。然后sudo service ssh restart重启下就可以了。

修改服务器默认登录端口
修改服务器配置:阿里云购买的服务器默认端口是22,出于安全考虑,我们需要修改一下。sudo vi /etc/ssh/sshd_config(去修改配置文件)。注意:修改配置前,最好多开一个窗口去连接好服务器,以防万一修改错误,登不上去,我们可以在这个窗口再进行修改。
相关修改:1、port,要选择1025-65536的端口号。2、useDNS保证是no。3、PermitRootLogin改为no, 禁止root用户登录(买阿里云服务器后,所有人都知道登录名是root,可以去扫描root下的所有端口,存在安全风险)。4、passwordAuthentication是否允许密码登录改为no,5、permitEmptyPasswords改为no。(因为我们现在不需要密码登录)。 6、passwordAuthentication yes后面加一行 AllowUsers xxx(用户名)。修改之后 sudo service ssh restart重启ssh服务。
端口相关:端口范围(0~65536, 0-1024的范围通常会被系统程序占用,必须以root身份才能启动。所以我们要选择1025-65536的端口号)。
登录:ssh -p xxx(端口号) xxx(用户名)@xxx(IP)

配置iptables防火墙(阿里云服务器可以设置安全组来配置,不用手动配置)
iptables:是允许灵活配置安全策略的防火墙框架(设置一些出入的大门,筛选掉恶意的访问)。
先升级一下服务器,sudo apt-get update && sudo apt-get upgrade。
把iptables的现有规则清空掉,sudo iptables -F。
配置iptables规则,sudo vi /etc/iptables.up.rules,新建一个空文件。首先输入一个*filter表示过滤。第一条规则:-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT(允许所有建立起来的连接)。第二条规则:-A OUTPUT -j ACCEPT (允许所有出去的流量)。第三条规则:-A INPUT -p tcp --dport 443 -j ACCEPT (允许https请求的连接)。第四条规则:-A INPUT -p tcp --dport 80 -j ACCEPT (所有网站访问服务器都是从80端口进去的,我们让80端口流量可以进出,你若要开放其他端口,再配置一条,把端口号替换一下就好了)。第五条规则:-A INPUT -p tcp -m state --state NEW --dport xxx(我们新建帐号对应的端口号) -j ACCEPT (登录服务器只能从这个端口登录,不是这个端口,在防火墙层面就把它拦截了)。第六条规则:-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT(允许从外网某台服务器pin到这台服务器,方便测试我们服务器是否停机、某个机房网络不通等)。第七条规则:-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied:" --log-level 7 (记录下被拒绝的请求)。第八条规则:-A INPUT -j REJECT  换行  -A FORWARD -j REJECT(拒绝所有其他对服务器的访问)。第九条规则:-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 (恶意访问进行拦截,如果某个ip对我们80端口在60秒内发出超过150的请求,被认为是敏感访问,进行拦截)。规则写完后,在最后写入COMMIT。
告诉服务器我们的配置文件(修改完配置都执行一下),sudo iptables-restore < /etc/iptables.up.rules
激活防火墙:sudo ufw enable,查看防火墙是否激活sudo ufw status,关闭防火墙:sudo ufw stop。
防火墙自动启动(服务器重启需要):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

配置Fail2Ben增强防护安全
一个防御性动作库,通过监控系统中的日志文件,根据监测到的任何可疑行为,触发不同的反应动作。比如把执行可疑行为的ip进行锁定。
安装: sudo apt-get install fail2ban
配置文件: sudo vi /etc/fail2ban/jail.conf。1、bantime可以设置大一点,比如3600。2、destmail = [email protected]可以改成自己的邮箱。3、action = %(action_mw)s。
Fail2Ben运行:sudo service fail2ban status(查看Fail2Ben是否运行)。sudo service fail2ban stop(停掉)。sudo service fail2ban start(开启)

安全配置总结,配置root及应用帐号权限、配置SSH无密码登录、修改服务器默认登录端口、配置iptables防火墙、配置Fail2Ben增强防护安全。通过这些基础性简单的安全配置,相对于裸机安全等级提高很多,对付一些常规简单的恶意行为绰绰有余。如果想要更高安全等级,需要更高的安全知识储备,比如我们可以对服务器登录设置ip的绑定,只有特定内网的ip才能登录到这台服务器,通俗所讲的在内网架设一台跳板机,通过本地电脑连上跳板机,再从跳板机连上生产服务器。

搭建服务器node.js环境
更新一下服务器:sudo apt-get update
安装一些模块:sudo apt-get install vim openssl build-essential libssl-dev wget curl git 回车。
安装node.js:我们会使用nvm方便管理node.js版本。安装一下nvm,wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh|bash。重新打开一个终端窗口登陆服务器,nvm install v6.9.5(去安装node.js),nvm use v6.9.5(使用node.js),nvm alias default v6.9.5(node默认版本设为6.9.5),node -v(查看node版本)。
安装cnpm:
1、npm install --registry=https://registry.npm.taobao.org -g npm(有时候会连不上npm或者下载太慢,我们可用register参数来指定使用国内淘宝镜像来下载,这里是使用国内淘宝镜像来安装npm)。
2、npm install --registry=https://registry.npm.taobao.org -g cnpm(安装cnpm,为了保证更快更稳定的速度,有时可以用cnpm替代npm,若我们npm安装不上,可以通过cnpm sync xxx来同步一个模块,它会强制把这个模块拉到国内镜像上)。
3、我们需要监控系统文件数目监控,echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p。
安装一下常用的npm包:npm i pm2 webpack
开启一个node服务(若80端口不通,需要去防火墙配置文件/etc/iptables.up.rules再去配置一下)

线上项目搭建生产环境_第1张图片
开启一个node服务

pm2启动服务(node服务启动在后台,出现异常时能自动重启):
在终端启动node服务是不合适的,一旦终端关闭服务就停止了,我们希望服务可以在后台运行,而且在出现异常时可以做到自动重启。我们会用到pm2(nodeJS部署及进程管理的工具)。pm2 start xxx.js(启动服务)。pm2 list(可以列出当前服务器上目前所运行的node服务有哪些)。pm2 show xxx(看指定node服务有哪些详细的信息,比如script path运行脚本所在的位置,error log path出现错误时错误信息的记录位置)。pm2 logs(查看实时日志)。
pm2自动拉取线上最新代码进行重新部署
pm2 deploy ecosystem.json production setup(第一次发布前初始化)
pm2 deploy ecosystem.json production (进行发布)
ecosystem.json配置见https://github.com/FishEmperor/ice。

nginx反向代理NodeJs端口(让web服务可以通过80端口,被外网能访问到)

1、因为我们当前账户下,node是不具备root的运行权限的,不能监听0-1024的任何端口(包括80端口)。我们需要启动nginx以root权限来对80端口进行监听,同时把来自80端口的流量分配给node服务的另外一个端口,实现服务的代理。
2、如果服务器只要放一个网站程序,解析网站到服务器的一个网址,网站程序监听80端口就可以了,如果服务器有很多应用,借助nginx不仅可以实现接口的代理,还可以实现负载均衡,让他来判断是来自哪个域名/ip的访问,根据配置的规则,原封不动转发给特定的端口或者是特定的某几台机器。
3、一般购买的阿里云服务器,可能会预装阿帕奇服务器,如果没有特别的项目是用不到的,可以先停掉 sudo service apache2 stop 和 sudo service apache stop。再删掉 update-rc.d -f apache2 remove 和 sudo apt-get remove apache2。更新一下包列表,sudo apt-get update。
4、安装nginx,sudo apt-get install nginx。进入到nginx配置中,cd /etc/nginx/conf.d,新建一个配置文件sudo vi xxx.conf。
配置内容
    1、upstream imooc(应用名) { server 127.0.0.1:8081(反向代理到这里) }  。upstream可以用来设置负载均衡的策略,2、server { listen 80; server_name xxx(服务器ip,比如120.26.235.4); 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://imooc;proxy_redirect off}}

5、在/etc/nginx下找到nginx.conf文件,sudo vi nginx.conf,确保配置有 include /etc/nginx/conf.d/*.conf(把conf.d下所有配置文件都加载进来);
6、测试一下配置文件有无错误,sudo nginx -t,修正错误。sudo nginx -s reload,重启一下nginx服务。如果想把开发者工具中请求显示的Server显示的nginx版本信息隐藏,可以配置nginx主配置文件 sudo vi /etc/nginx/nginx.conf,找到 "##server_tokens off" 把"##"删除,取消注释。重启一下nginx配置,sudo service nginx reload(若报错,先nginx -c /etc/nginx/nginx.conf。再sudo nginx -s reload)。
7、看到控制台请求头中会显示nginx版本信息,可以通过把nginx.conf中的#server_tokens off前面的注释“#”号拿掉。

更改域名的DNS根服务器:
需要一个域名解析服务器DNS,这个服务器通常是你购买域名的服务商来提供的,比如阿里云/goDaddy等。1个域名只可对应1个ip地址,1个ip地址可以对应多个域名。
对于域名,通过阿里云服务有免费的云解析服务,但是最好把域名放到DNSPod上进行解析,因为它是个老厂商,技术背景成熟。另一方面,我们的域名不一定是通过阿里云购买,我们可以在DNSPod上进行批量管理,更方便。
我们在阿里云-域名列表-管理-修改DNS。再进入DNSPod-常见问题-功能介绍及使用教程-各个注册商修改域名DNS地址的方法-万网 。查到解析服务器填入“修改DNS”即可。


MongoDB数据库:
阿里云有付费的云数据库MongoDB版本,有主副节点和备份机制(适合商用),数据库服务器和项目服务器分开。
我们自己玩玩的项目,能跑起来就行,那么数据库和项目在同一台服务器上。
安装mongoDB(https://docs.mongodb.com/manual/tutorial/install-mongodb-on-unbuntu/)
根据自己服务器 手动安装MongoDB,如果我们使用的是Ubuntu服务器:1、登录服务器 ssh -p 39999 [email protected]。2、导入public key。3、为MongoDB的配置文件创建一个列表。4、更新本地包。5、安装。6、开启服务、sudo service mongod start(重启的话是restart)。7、检查是否开启成功 mongo 去连接mongo数据库。8、终止mongodb服务,sudo service mongod stop。
注意:
1、如果下载安装出错,可能是因为,我们用的是阿里云服务器,他默认安装源也是阿里云,我们可以先把源屏蔽掉试试,sudo vi /etc/apt/apt.conf,可以把第一行给注释掉,最前面加入"#"。
2、如果觉得安装太慢,可以sudo vi /etc/apt/souces.list.d/mongodb-org-3.4.list,把这个文件里的 http://repo.mongodb.org/apt/ubantu  改成 http://mirrors.aliyun.com/mongodb/apt/ubantu,然后执行sudo apt-get update。
3、如果mongo 连接不上数据库,可能是防火墙没有允许本地连接27017的端口(mongo的默认端口),我们需要编辑一下防火墙 sudo vi /etc/iptables.up.rules。找到#ping 来添加2条规则 -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
4、大家都知道mongodb默认端口是27017,出于最基本的安全考虑,需要把默认端口改一下,sudo vi /etc/mongod.conf  找到port 改成19999。再改一下防火墙的端口sudo vi /etc/iptables.up.rules,把上e面3中的27017改成19999。重新载入一下防火墙 sudo iptables-restore < /etc/iptables.up.rules。之后连接mogodb 需要 mongo --port 19999 来连接数据库。

往线上MongoDB导入单表数据或数据库
备份/导出本地数据库:mongodump -h (域名)<:port>(端口号) -d dbname(需要备份的数据库实例) -o dbdirectory(备份数据库存放的位置)
打包导出的数据库:tar zcvf name1.tar.gz(打包后的文件名) name2(打包原文件名)
上传打包好的数据库到服务器:scp -P xxx(端口号)   /xxx/xxx.xx(本地文件地址) root@xxx:/xxx/xx.xx(:后面跟服务器文件地址)
服务器上解压上传的数据库包:tar xvf name.tar.gz(要解压的包名)
服务器mongodb导入数据库包:mongorestore --host 127.0.0.1:xxx(端口号) -d dbname(需要导入的数据库实例) dbdirectory(导入数据包的位置)
本地导出单条数据表:mongoexport -d dbname(需要导出的数据库实例) -c name(需要导出的数据库表名) -q '{"name": {$ne: null}}'(需要导出的数据的查询条件,这里是name不为空) -o dbdirectory(导出数据包的位置)
上传到服务器后,服务器导入单表:mongoimport --host 127.0.0.1:xxx -d dbname(需要导入的数据库实例) -c name(需要导入的数据库表名)  dbdirectory(导入数据包的位置)
清空数据库:mogo --host 127.0.0.1:xxx dbname(数据库实例名) --eval "db.dropDatabase()"

MongoDB数据库读写权限
1、MongoDB没有默认的管理员帐号,添加管理员帐号,开启权限的认证。
2、切换到admin数据库后,添加的帐号为管理员帐号。
3、用户只能访问和登录用户所在的数据库和管理员帐号。
4、管理员可以管理所有数据库,但不能直接管理,首先需要到admin中认证过才可以。
设置管理员(超级权限):
mongo --port xxx(端口号) 进入到mongo的命令行环境下。
switched to db admin 进入到admin数据库
添加admin数据库管理员:db.createUser({user(用户名): 'xxx', pwd(密码): 'xxx', roles: [{'role'(角色): 'userAdminAnyDatabase', 'db'(数据库): 'admin'}]}) 添加完管理员记得记录下账号密码,这个管理员可以间接管理所有数据库。
在admin数据库下对这个管理员进行授权:db.auth('xxx'(用户名), 'xxx'(密码)),显示是1代表授权成功
切换到指定数据库: switched to db xxx(数据库名)
添加指定数据库管理员:db.createUser({user(用户名): 'xxx', pwd(密码): 'xxx', roles: [{'role'(角色): 'readWrite', 'db'(数据库): 'xxx'}]}) 
添加指定数据库 负责备份管理员:db.createUser({user(用户名): 'xxx', pwd(密码): 'xxx', roles: [{'role'(角色): 'read', 'db'(数据库): 'xxx'}]}) 
用户创建完毕,还不能验证,需要通过配置文件开启验证:sudo vi /etc/mongod.conf 。找到"#security:",去掉#(取消注释),下一行空二格,写入 authorization: 'enabled'(同意授权)
重启mongod:sudo service mongod restart。此时我们 mongo --port xxx 进入数据库中,show dbs会报错(因为没有权限),我们需要use admin先进入admin中,再db.auth('xxx', 'xxx')去认证,此时再去show dbs 就可以了。
如果想直接进入指定数据库:mongo 127.0.0.1:xxx(端口号)/xxx(数据库名) -u xxx(账号名) -p xxx(密码) 即可。

从一台线上服务器迁移数据到另一个线上MongoDB中
1、先把线上服务器数据导出来。
    新建/进入 文件夹容器,mkdir db 。 cd db 。
     迁移整个数据库实例:通过 负责备份管理员导出数据,mongodump -h (域名)<:port>(端口号) -d dbname(需要备份的数据库实例) -u xxx(用户名) -p xxx(密码) -o dbdirectory(备份数据库存放的位置)
    迁移单表:mongoexport -h (域名)<:port>(端口号) -d dbname(需要导出的数据库实例) -c name(需要导出的数据库表名)  -u xxx(用户名) -p xxx(密码) -q '{"name": {$ne: null}}'(需要导出的数据的查询条件,这里是name不为空) -o dbdirectory(导出数据包的位置)
    打包:tar zcvf name1.tar.gz(打包后的文件名) name2(打包原文件名)
2、把数据传到本地,并发送到新服务器。
    给服务器传输文: scp -r(如果是文件夹加上-r)  /xxx/xxx.xx(本地文件地址) root@xxx:/xxx/xx.xx(:后面跟服务器文件地址)
    从服务器下载文:scp (-P xxx 如果设置了免密) root@xxx:/xxx/xx.xx(:后面跟服务器文件地址)  /xxx/xxx.xx(本地文件地址) 
3、新服务器 解压缩文件,并导入数据。
    服务器上解压上传的数据库包:tar xvf name.tar.gz(要解压的包名)
    连上数据库:mongo --port xxx 。
    进入admin:use admin。
    授权:db.auth('xxx', 'xxx')。
    切换到指定数据库:use xxx。
    添加指定数据库管理员+添加指定数据库 负责备份管理员
    服务器mongodb导入数据库包:mongorestore --h 127.0.0.1:xxx(端口号) -d dbname(需要导入的数据库实例) dbdirectory(导入数据包的位置)
    服务器导入单表:mongoimport --host 127.0.0.1:xxx -d dbname(需要导入的数据库实例) -c name(需要导入的数据库表名)  dbdirectory(导入数据包的位置)
    查看是否导入成功:mongo 127.0.0.1:xxx(端口号)/xxx(数据库名) -u xxx(账号名) -p xxx(密码) 即可。

为数据库实现定时备份方案(方案很多,介绍一种简单,易上手的方式)
原理:利用系统任务通过自动定时来对数据库备份。
写一个执行任务的脚本:
    1、新建/进入文件夹,mkdir tasks ,cd tasks。
    2、编辑一个脚本,vi movie.backup.sh。
        #!/bin/sh(表示是一个可执行的脚本)
        backUpFolder=/home/imooc_manager/backup/movie(设置一个变量,表示备份数据库导出的目录)
        date_now=`date +%Y_%m_%d_%H%M` (设置当前日期)
        backFileName=movie_$date_now(备份出的文件名)
        cd $backUpFolder(进入到需要备份数据库的目录)
        mkdir -p $backFileName(创建一个文件夹,用于存放导出的数据)
        mongodump -h (域名)<:port>(端口号) -d dbname(需要备份的数据库实例) -u xxx(用户名) -p xxx(密码) -o dbdirectory(备份数据库存放的位置)   (导出数据)
        tar zcvf name1.tar.gz(打包后的文件名) name2(打包原文件名)  (压缩)
        rm -rf $backFileName(清理导出未压缩的数据)
      3、新建文件夹用来存放导出的数据,执行脚本文件:mkdir backup。 cd backup。mkdir movie。cd 。sudo sh ./tasks/movie.backup.sh
      4、定时脚本跑起来。
            cd(进入用户根目录)。
            crontab -e (启动系统自动任务的设定),第一次进入会有一个nano编辑器选择,选择2就好了。(关于crontab的定时规则可以去了解文档)
            最后一行输入:13 00 * * * sh /home/imooc_manager/tasks/movie.backup.sh。 control+x。shift+y。回车(在凌晨13分会去执行脚本)
注意:现在我们存放备份数据都在服务器硬盘上存着,服务器被人攻击或者误操作,可能会导致数据文件被删除,建议把数据包存到第三方云平台上或者自建的服务器上。

上传项目代码到线上私有Git仓库
服务器上安装nginx和pm2,通过nginx端口映射把前端发出的http请求转发到后端的node.js上,node.js本身我们会通过pm2来进行维护。
具体详细操作请到git相关文档去看。

配置PM2,一键部署线上项目结构(在本地,登陆上服务器,服务器去拉取git仓库最新代码,部署到相应文件夹中等待进一步操作)
现在我们可以从git仓库下载到最新代码,我们需要一个傻瓜式管理代码更新和服务运行的工具(即pm2),帮助我们同步代码更新和服务重启。关于部署,pm2有详细文档(pm2.keymetrics.io)。
我们通过配置文件的方式来配置pm2,文档中有一个deployment文档,需要在项目静态文件中建一个ecosystem.json,在这里面我们来配置 仓库的地址,服务器的ip、账号等。
    {"apps": [
        {  "name"(项目名): "xxx",
            "script"(执行的脚本): "app.js",
            "env"(脚本中要传入的变量): { "COMMON_VARIABLE": "true" },
            "env_production"(生产环境的变量): {"NODE_ENV: "production"}
        }
    ],deploy(部署的任务):{
        "production":{
            "user"(服务器上用来发布的用户名): "xxx",
            "host"(IP): ["xxx.xxx.xxx"],
            "port": "xxxx",
            "ref"(主分支): "origin/master",
            "repo"(仓库地址):  git@.... ,
            "path"(需要把项目部署到服务器哪个目录下): "/www/website/production",
            "ssh_options"(把key校验取消掉): "StrictHostKeyChecking=no",
            "env": {
                "NODE_ENV": "production"
            }
        }
    }}
登上服务器,到服务器根路径 创建静态网站部署的路径。mkdir www。cd www。mkdir website。cd website。
运行:pm2 deploy ecosystem.json production(参数,配置的任务的名字) setup(命令,pm2连接上服务器,在服务创建发布项目所需要的文件夹)。执行完毕会发现服务器"/www/website/production"目录下会有三个文件夹 current(当前服务所运行的文件夹)、shared(日志文件等共享数据)、source(clone下来的源代码)
注意:我们所用的user用户名对于根目录下的website可能没有读写权限,我们需要在服务器执行 cd /www/website。sudo chmod 777 website。赋予user用户名对website文件夹的读写权限。另外,上面的直接sudo chmod 777 website,让所有用户对website有操作权限的做法其实不妥,我们应该创建一个专门操作website的用户组。

从本地发布上线和更新服务器的Node.js项目
发布流程:完成上一步操作后,我们进入本地项目中,执行 pm2 deploy ecosystem.json production(配置的任务的名字) 。
注意:
        通常会报错pm2命令找不着,那是因为pm2在服务器使用的是非交互的ssh连接方式。我们需要进入服务器对应用户下,vi .bashrc编辑该文件,把 case $- in 到esac都注释掉后保存。再通过 source .bashrc来重新加载bashrc,再去下载pm2(npm i pm2 -g)。
        也会报错ecosystem.json在服务器上没找到,我们需要提交到git。再执行 pm2 deploy ecosystem.json production(配置的任务的名字) 来重新发布。
修改域名指向:通过域名来访问到静态网站所提供的web服务。
修改nginx配置文件
    通过nginx来识别请求后,把请求转发到服务器的3000端口。服务器的nginx配置文件我们原本放在/etc/nginx/conf.d中会有一个imooc-com-8081.conf,我们把它改名成www-iblack7-com-3000.conf。编辑这个文件,upstream imooc改成upstream website;端口8081改成3000;server_name改成www.iblack7.com(域名);把location中proxy_pass改成http://website。保存。
    重启nginx服务,sudo nginx -s reload,在浏览器通过域名去访问网站。
    注意:如果访问失败502,除了nginx服务器端口映射和nodeJs本身会出问题,还有可能防火墙有问题。我们现在通过nginx把通过来自www.iblack7.com的请求转发到了服务器本地的3000端口,防火墙需要允许3000端口的访问。我们来配置一下防火墙配置,sudo vi /etc/iptables.up.rules,在mongodb connect的下面再增加2行:把前面两行复制一下,-A INPUT...和-A OUTPUT,黏贴在后面,端口号改成3000,保存。重新载入一下防火墙配置,sudo iptables-restore < /etc/iptables.up.rules。
此后,更新发布,只需要修改完毕后push到git仓库,在本地执行 pm2 deploy ecosystem.json production(配置的任务的名字) 。即可完成更新发布。

选购申请SSL证书
2017年开始,谷歌开始对采用http协议的网站标记为不安全的网站,苹果所有应用必须采用https的加密链接。国内小程序要求必须使用https协议接入域名。
如果采用http协议,很容易被联通电信劫持,注入话费充值广告等,采用https协议起码会避免asp劫持。
证书对于浏览器或操作系统的支持范围:Chrome、windows、safairs、mac OS等。
证书的类型:通常证书是向国际认证的认证机构(CA)来申请,能够申请到的证书类型:
1、域名级证书(DV),信任等级一般,一般用于个人博客、产品演示、中小企业网站,对信息安全等级不高的情况下使用,申请流程简单。
2、企业级别的证书(OA),信任等级较高,通常用于电商网站、私密社交等涉及到用户资料、订单支付场景,申请较严格,价格不亲民,对业务有一定规模的公司可以考虑。
3、增强型证书(EA),全球统一的,严格实名认证标准颁发的SSL证书,目前全球最高等级的SSL证书,安全性很高,一个网站如果使用了该证书地址栏会显示为绿色,一般用在金融支付,网上银行等一些资金交易比较敏感的场景。
证书的维护成本:时效有3个月、1年,过期后需要更新证书或者重新提交申请,我们还可以通过一些工具或者脚本来解决证书的自动更新,节省维护成本。
免费申请SSL证书的平台:有拍云、腾讯云(推荐)、七牛、阿里云。注意:域名需要已备案
证书申请机构:赛门铁克、

你可能感兴趣的:(线上项目搭建生产环境)