云服务器 Linux + Ubuntu + Meteor + Mogodb + PM2 + Docker + Nginx 部署从入门到把坑填平
本文仅供参考,有不正确的部份,请参考第二版更新:正在发布
介于很多网友对meteor部署不太熟悉,特将部署经验记录并分享给大家。
宗旨:希望这篇文章可以成为 永不落后的 Meteor 配置经验分享,随着 NodeJs Meteor MongoDB Ubuntu 等等的升级,不断更新和填坑,有任何问题可以留言,大家一起填坑(填坑的内容会整理成为内容更新在第七部份中,成为正式内容),成为新人的日不落的配置的指引的目标。
环境规划:
1: (完成)服务器 -- 阿里云 *任何云都可以,只要是一台纯净或可控的服务器即可
2: (完成)系统 -- Linux ubuntu 16.04 x64位,*你也可以使用其它,如 16.04 x64位
3: (完成)环境 -- NodeJs 9.x 最新版本 + NPM 5.x 最新 *随时升级最新
4: (完成)数据库 -- MongoDB 3.4 社区版
5: (完成)单项目部署上线运行
6: (完成)容器 -- Docker 虚拟容器
7: (完成)分流 -- Nginx 分流控制
8: (完成)管理 -- PM2
9: (完成)统一执行管理脚本
部署目的:
以云服务器为基础托管多个 Meteor 项目,并采用容器技术 将项目与宿主机隔离,在宿主机配置公共数据库,由 Docker 容器共同使用,同一台服务器,多个域名接入,由 Nginx 进行分流管理,由Metoer 生成的 Web 项目 和 APP 项目都以这台服务器为 中心 生产运行。
结果:
1: 可不断增加新的 Web 项目进来,方便的管理和重启
2: 统一数据库管理,并在开发 环境进行数据库远程管理
3: 采用 Windows 纯净 CMD 环境 进行 Metoer 开发,SSH 进行远程 部署管理
4: 部署 微信+网站+APP 于一体的统一的云端 服务器,并统一管理,包括 域名解析等一系列全方位海陆空的宇宙级操作
实操:
在进行如此枯燥的操作之前,先给大家一点福利,
第一部份: 服务器和操作系统镜像安装
目前,可以选择的服务器推荐: 云服务器,如阿里云,腾讯云等,任何云都是可以的,没有太多差别。操作系统,可以选择Linux Ubuntu 也可以选择CentOS,没有什么关系,只是使用习惯问题,可以根据自己的习惯来选择。
1.1: 购买云服务器后(以阿里云为例),第一步,安装镜像,我们选择纯净的公共镜像,即仅安装操作系统,根据习惯选择你的操作系统,这里以 Ubuntu 16.04 64位(无论什么操作系统,必需选择64位)为例,如图1-1所示:
1.2: 等云服务器配置好镜像,重启后,即可进行远程管理了,由于我们是在Windows 系统操作管理,推荐使用 Xshell 和 Xftp 这两款软件进行 服务器远程管理和FTP文件传输。Xshell 和 Xftp必需进入国外官网通过邮件申请的方式下载,选择家庭和学生用户即可免费使用,如图1-2所示:
Xshell 下载传送门
1.3: 配置Xshell 名称、主机、端口、用户密码,即可远程登陆,如图 1-3 ~ 1-5 所示:
第二部份: 安装 NodeJs 生产环境
1: 目前,NodeJs 版本是 9.2.0,后续有升级可按照指定最新版本的方法安装最新的升级版本,在开发的时候,如果你使用了最新的 Meteor, 由于 Meteor 在不断升级,建议安装 8.9.1版本(注意:截图中安装的是9.x,最后使用发现有一些问题,还是推荐安装8.x),Meteor1.6官方支持是8.x,如图1-6 所示:
如果有旧版本,请先删除:
apt-get remove nodejs
2: 在远程管理中,使用命令来安装NodeJs,安装过程如图 1-7 所示:
apt-get update
apt-get install sudo
curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
这时,程序进行安装前的配置和对 apt-get 库的升级操作, 运行完成后,根据提示,输入:
apt-get install nodejs
进入正式安装,如图 1- 8 所示:
安装完成后,输入:
node -v
检测是否安装成功,如下图所示, 如图 1-9 所示:
第三部份 MongoDB社区版 数据库安装配置
目前MongoDB版本最新稳定版本为 3.4社区版,3.6即将到来,但还没有正式发布,这里,我们先以3.4为例进行安装配置,打开官网:
https://docs.mongodb.com/master/tutorial/install-mongodb-on-ubuntu/?_ga=2.22855547.1392086098.1510974328-384431769.1508637743
在文档左侧目录选中: Install on Ubuntu 根据提示进行安装,如果你选择了其它操作系统,可以根据自己的选择来选择安装指引,如图 1-10 所示:
以下内容为官方原版引用,如官方有变更,请以官网为准,sudo命令是使用管理员身份执行,如已经是 root 最高权限登陆,可以省略 sudo 命令,当然,使用 root 进行管理是不好的,但这里对 Linux 权限就不展开讲解了,有兴趣和需求的同学自行研究。
1: 导入包管理系统使用的公钥
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
2: 为MongoDB创建一个列表文件
注意这里官方给出了三个不同版本,请选择匹配的,这里选择 16.04
echo “deb [arch = amd64,arm64] http://repo.mongodb.org/apt/ubuntu xenial / mongodb-org / testing multiverse” | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
以上两个命令运行完毕后,应当如图 1-11 所示:
为什么我喜欢把运行结果的图也贴上来呢,是因为,对不太熟悉Linux 的同学会有很大帮助,特别是首次使用,因为太陌生。所以,做得比较详细一些。
3: 重新加载本地包库
apt-get update
注:遇坑1,解决方法在第七部份,没遇到请跳过
4: 安装MongoDB,安装过程如图 1-12 所示:
apt-get install -y mongodb-org
安装完成后,默认
数据存储于: /var/lib/mongodb
日志文件在: /var/log/mongodb
配置文件在: /etc/mongod.conf
5: 启动 MongoDB,首次安装后必需先启动
service mongod start
6: 停止 MongoDB
service mongod stop
7: 重启 MongoDB
service mongod restart
8: 进入 MongoDB shell (进入MongoDB 命令行管理界面),输入:
mongo
成功进入,你应当如图 1-13 所示:
补充知识:三种 Shell 的理解
这里讲的 Shell 通常是指命令行操作窗口,在计算机科学中,Shell俗称壳(用来区别于核),是指“提供使用者使用界面”的软件(命令解析器)。它类似于DOS下的command和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序,记住,今年不考明年一定会考。
a: 本地操作系统 Shell
指本地 cmd 窗口,以 Windows 为例,运行 Ctrl + R,输入 cmd 回车,打开的本地 cmd 窗口,注意:通常直接运行是没有管理员权限的,如果需要管理员权限,最简单的方式是,直接在所有程序中 > Windows系统 > 命令提示符 上右键,选择,以管理员身体运行,不同的 Windows 版本会有差别,但操作方式相同。
b: 远程操作系统 Shell
指通过 Xshell 远程 登陆的 云服务器的 命令操作窗口,即当前我们操作的这台服务器,如果不是管理员登陆,需要使用 sudo 来执行管理员权限,如果已经是 root 最高权限,就不需要,直接运行所有命令。
c: MongoDB Shell
指在 本地或远程 Shell 中 运行 mongo 命令打开MongoDB ,执行 MongoDB 命令的窗口,当然他处于当前窗口中,是以 > 符号开始的,如果需要退出MongoDB Shell,输入 exit 或直接 按下 Ctrl + C 即可。
好了,重要的环节来了,就是配置 MongoDB 管理员及创建数据库和数据库独立管理员用户密码
注意了注意了
9: 创建 MongoDB 管理员及用户密码
通常,MongoDB 是不需用户密码就可以访问的,这导致了很大的数据库入侵事件,甚至引发了,MongoDB是不安全的言论,我只想说,你家里不关门,却怪世上小偷太多,这不科学。
9.1: 操作数据库,在操作数据库前,必需先进入数据库,无需事先创建,直接进入:
use admin
进入管理员数据库,如图 1-14 所示:
9.2: 创建管理员用户名和密码,输入:
db.createUser({user:"admin", pwd:"jindaoke.com", roles:["root"]});
成功创建后如图 1-15 所示:
9.3: 当创建管理员用户密码后,需要打开 配置文件中的 身份验证,否则所有操作都会无权限,提示: Error: Authentication failed,所以,退出当前的MongoDB shell,按下 Ctrl + C 退出到 远程云服务器的 操作命令行,陌生的同学给你们一个图,凡显示为1-16所示的界面,即处于 云服务器远程 shell,显示了你的云服务器ID的当前的用户名。
9.4: 打开 MongoDB 身份验证功能
在 第三部份的第4小节中,看到 MongoDB 配置文件位置: /etc/mongod.conf,现在开始编辑配置文件,输入:
vim /etc/mongod.conf
vim 是 Utuntu 的 命令行文件编辑命令,进入编辑状态后,如图 1-17 所示:
按下 键盘 Insert 键,移动光标,通过键盘上下左右方向键移动光标,对文件进行编辑修改,找到:security 去除前面的 # 注释,注意前面不能留有空格,在下面输入两个空格,再输入 authorization: enabled,先按下 ESC退出编辑状态,再按下 Shift + : 即 按住 Shift 键的同时,按下 L键右边的键,进入文件操作状态,输入 wq,回车保存修改并退出,如图 1-18 所示:
重要补充:
注意,net: 中的 bindIp地址,如果在服务器需要使用外网或者内网非127.0.0.1 方式连接数据库,需要将IP添加进来,以逗号分隔,如果不需要绑定,可以注释网络IP地址绑定。
bindIp: ip1,ip2...
9.4: 重启 MongoDB
service mongod restart
9.5: 重启后,在准备进入 MongoDB shell 创建其它数据库和独立用户密码前,需要使用管理员身份登陆,首先,通过验证管员权限的方式进入 Mongo shell,输入:
mongo admin -u admin -p jindaoke.com
进入新数据库,提示: switched to db admin,即表示进入成功
use jindaoke
创建新数据库用户密码:
db.createUser({user:"jindaoke",pwd:"jindaoke.com",roles:[{role:"dbOwner",db:"jindaoke"}] })
创建成功后,如图 1-19 所示:
9.6: 测试 MongoDB ,创建集合数据和查询
创建集合和写入数据,执行命令,即创建 demo 集合,并在集合中登陆 数据 title:1,
db.demo.insert({title:1})
查询,执行
db.demo.findOne();
结果如图 1-20 所示,即表示,你的数据库 完美配置了,可以任意创建具有用户密码身份验证的数据库了。
注意了注意了注意了,要来了要来了
第三部份核心:开始部署 Meteor 项目
1: 以上我们配置了服务器NodeJs 环境 和 数据库,现在开始上传 Meteor 项目,进行部署,准备工作做了这么多,是时候收获成果了。打开 Xftp 软件,上传打包好的 Meteor 项目,如图 1-21 所示:
2:将 Meteor 项目部署到 网站目录,创建你的网站存储文件夹,例如:
/home/wwwroot/meteor/domain/jindaoke.com/web
直接通过 FTP 创建即可,创建完成,将本地打包好的 Meteor 文件压缩包,上传到 web 文件夹中,如图 1-22 所示:
注: 打包方法见第第六部份
3: 通过远程操作文件
进入远程服务器 shell,执行:
cd /home/wwwroot/meteor/domain/jindaoke.com/web
3.1: 进入目录和查看文件,进入到你的 Meteor 项目文件夹,执行:
ls
命令查看目录文件,看到刚上传的压缩包,如图1-23 所示:
3.2: 解压, 将文件解压到当前目录,执行:
tar -zxvf demo.tar.gz
解压完成,如图 1-24 所示:
这时候,所有文件在 bundle 文件夹中,应该将所有文件移到当前位置,即 web 文件夹下。
3.3: 删除文件, 执行:
rm demo.tar.gz
将压缩包删除
3.4: 移动文件,进入bundle 文件夹,执行:
cp -rf * ../
即将 bundle 全部复制到 上一级,即 web 文件夹下,回退到 web 文件夹,并删除 bundle 文件夹,执行:
cd ../ && rm -rf bundle
现在,完成了项目的上传和解压,当然你也可以通过FTP来进行文件的移动删除等操作,看个人习惯。
4: 配置环境变量
直接执行 Meteor 项目,需要配置环境变量,你可以将环境变量写在 packages.js 文件中,也可以直接在命令行中输入全局变量,
4.1: 配置数据库链接,执行:
export MONGO_URL=mongodb://jindaoke:[email protected]:27017/jindaoke
这里的数据库链接分别是:mongodb://用户名:密码@云服务器IP:默认数据库端口/数据库名
4.2: 配置默认网址,执行:
export ROOT_URL=http://www.jindaoke.com
4.3: 配置默认web 访问端口,执行:
export PORT=80
5: 运行项目
5.1: 安装项目依赖,进入web,即项目的 /programs/server 目录,执行:
npm install
注: 这里有一个巨坑,参见 第七部份坑2
万事具备,回到web根目录,你现在只需要一个命令即可运行项目,执行:
node main.js
运行成功,如图 1-25 所示:
* 重要提示: 由于 node 项目是自带 服务器运行环境的,所有处于运行中状态时,当前命令窗口是独占式运行的,光标是不可以执行其它操作的,这时候,如果想执行其它操作,需要另外打开一个 shell 窗口,执行:
curl http://127.0.0.0.1
在 shell 中查看网页,如图 1-26 所示,即表示你的项目已经正常运行,绑定环境变量指定的域名到当前服务器IP,即可正常访问。
结束了,结束了.....
但是,很多同学,需要部署多个项目,是否也按照当前的方式运行呢? 其实只需扩展容器即可,使容器共享宿主机的物理(这里所谓的物理文件,是指在云服务器上不通过Docker,通常访问的文件,只是一个表示方法,较真的话,他也是虚拟的)文件,并通过 Nginx 对域名分流转向到不同的服务器内部 IP 地址,实现多项目共存。
结束是另一个开始......
单项目部署结束分隔线
多项目多域名多容器分离部署开始
如果你仅有一个项目部署,可以到此为止了,直接上传打包的 Meteor 项目,在目录中配置环境变量,启动运行即可。以下部份针对多项目部署者,请明确需求。
多项目部署者,开始吧
第四部份 Docker 容器配置安装
Meteor 属于 NodeJs 的框架,所以 Meteor 打包生成的项目可以直接在 NodeJs环境中运行,只需要配置好 NodeJs 即可运行 Meteor 项目。由于我们需要在 服务器 运行多个项目,并可能会对环境版本有不同的细节要求,为了方便维护,采用 Docker 容器技术 生成多个隔离空间,可以理解为多个虚拟主机,互相独立。
1: 安装 Docker 容器,以下安装以官方原文为主,官方如有变化,请以官方为主:
官方指南传送门
更新 apt-get 本地库
apt-get update
2: 安装软件包以允许apt通过HTTPS使用存储库,全部复制粘贴到命令行执行:
apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
3: 添加Docker的官方GPG密钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
4: 设置稳定的存储库,全部复制粘贴到命令行执行:
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
5: 再次更新 apt-get 包
apt-get update
6: 开始安装 Docker
apt-get install docker-ce
7: 安装完成后,查看容器列表
docker ps
如图 1-29 所示,即表示 Docker 安装成功
8:创建容器
现在,我们安装了Docker 软件,在创建容器之前,需要从 Docker 服务端拉取一个镜像,因为本机还没有镜像,先摘取一个纯净版的 Ubuntu 16.04 最新版本,执行:
docker pull ubuntu:16.04
由于镜像较大,所以会下载一段时间,如图 1- 30所示
拉取镜像成功后,就可以通过镜像创建 Docker 容器了,执行:
docker run --restart=always -itd --net=none --name jindaoke.com -v /home/wwwroot/meteor/domain/jindaoke.com/web:/var/www/jindaoke.com/web ubuntu
创建一个名为:jindaoke.com 的 Docker 容器,执行: docker ps 查看容器列表,如图 1-31 所示:
由于,这篇文章,并不着重于讲解Docker的使用,所以这里,建议对 Docker 感兴趣的同学自行搜索每一个参数的含义,平时使用记住命令,创建时,只需修改参数即可,因为我们是 meteor 开发者,并不是 docker 运维者,会用即可,不用深究。
补充:创建容器镜像
创建好的容器,为了方便下次复用,可以创建一个镜像。
执行:
docker commit 容器名 self/meteor:3
在:后面可以设置镜像的标签,完成后会显示镜像名称:
补充:打包镜像和载入镜像
执行以下命名将镜像打包:
docker save self/meteor > meteor_image.tar
镜像打包后,可以下载到本地,上传到另外的服务器,直接 使用镜像,通过以下命令,载入镜像:
docker save self/meteor > meteor_image.tar
补充:查看本地镜像
执行:
docker images
补充:删除本地镜像
在删除本地镜像前,必需先执行:
docker stop 镜像ID
停止镜像,然后使用:
docker rmi 镜像ID
删除镜像
9: 关于容器IP地址
注意,我们这里创建的容器是,取消了自动分配的内部IP地址,所以是没有内部IP地址的,如果去掉: --net=none 参数,即由 Docker 容器自动分配IP地址,以 192.168.0.x 的形式进行自动分配。
因为每次,Docker 重启,如果是自动分配的IP地址,多个容器,重启宿主机后,容器的自动分配 IP会变,所以不利于长久的运维和管理。所以,这里对每一个Docker 容器进行手动分配 IP的方法,保持长久的IP不变。
知识补充:关于 宿主机和Docker 容器的关系
a: 宿主机
宿主,就是主体,母体的意思,在这里,意指 你购买的这台远程阿里云服务器,现在在我们的使用下,是物理主机,远程登陆后的 shell命令即是宿主机操作 shell。顺便扯一扯,在我们手中是宿主,在阿里云整体的云计算中,他也只是一个虚拟的容器,并不是真正的宿主机,当然,这个不是我们关系的,至少,在目前我们手中,他就是宿主机。
b: 容器
容器,相当于在 宿主机上分隔了一个独立的系统出来,这个系统和宿主机只要是同一个内核的,比如都是 Linux 内核,操作系统版本可以是不同的,便于理解,在这里,将容器理解为 虚拟主机,和宿主机完全独立的虚拟主机,有独立控制权限的虚拟主机即可。如有问题,欢迎留言提出更正。
第五部份 Nginx 域名分流解析配置
1:Nginx 安装配置
请自行搜索Nginx安装过程,这一部我已经安装好了,就跳过了,安装文章比较多,这不是重点。
2:域名解析分流
首先,需要将你的域名解析到服务器的外网IP地址,再执行以下操作。
在meteor项目文件夹目录创建 vhost 文件夹,创建项目同名 conf文件,如下所示:
在总的Nginx conf 文件中包含项目的子conf文件,以方便管理,找到你的Nginx配置文件:
在http 最后添加以下内容
include /项目的路径/vhost/*.conf;
做域名分流处理,在文件中输入以下内容,使域名指向内部容器的IP地址:
在执行以下转向的时候,请确保在宿主机,正确访问到容器的项目,可使用 curl 进行测试,如图所示:
第六部份 本地打包上传 PM2统一管理
1: Meteor Web项目本地打包
在 Meteor 项目根目录,执行:
meteor build ../build --architecture os.linux.x86_64
打包,并且 将打包的文件存储到上一级 build 文件夹中,同时指定运行环境为 Linux x86 64位操作系统。
打包过程:
配置安装 PM2,PM2官方传送门
PM2需要安装在 Docker 容器中,进入 Docker 容器,执行,
npm install pm2@latest -g
完成后如图所示:
PM2 常用命令
1: pm2 logs 查看服务端log
2:pm2 monit 图形界面监控管理
完结:安装 pipework 及统一脚本命令执行和重启管理
注意了:
因方法更改,以下安装配置固定ip及统一管理方法过旧,中间或有缺失内容,仅供参考,如有按此方法成功请补充回复给我,以更新修改为正确的方式,现在采用的是:
docker network create --subnet=192.168.0.0/16 mynetwork
docker run -itd --name web --net mynetwork --ip 192.168.0.10 ubuntu
这样的方式进行创建docker容器及固定IP,以下内容请谨慎使用
我们需要为容器分配固定的IP地址,以防止服务器重启后容器IP地址变更,首先需要安装 pipework,进行容器IP地址的配置,分别执行以下命令,进行pipework的安装
git clone https://github.com/jpetazzo/pipework.git
cp pipework/pipework /usr/local/bin/
11: 配置统一启动脚本
我们配置启动脚本进行,统一的项目IP地址的指定和不进入 容器在宿主机直接 进行PM2的启动,以及依赖包的安装,等操作,以方便管理所有项目,在/root目录创建以下文件,命名为docker.sh,内容根据以下脚本进行扩展,注意格式及缩进,增加项目的时候,只需要在container中增加行即可,注意了,这里的脚本是需要在容器中安装PM2后才能执行的
统一脚本命令
在Ubuntu系统中,可以使用 vim 进行文件的编辑和修改保存。
编写好后,在任何位置执行:
/root/docker.sh
即可执行脚本
如果提示权限不对,执行以下命令:
chmod +x ./docker.sh
至此,所有知识点都已分解完成,以上所有内容,需要融会贯通,穿插执行,不一定需要按照以上的顺序,尽量一致即可,多操作,就可以全部手动管理项目了
第七部份 各种填坑
坑1: 安装 MongoDB 在第3步运行命令出现:
The list of sources could not be read.
原因:应该是没有全屏运行1,2步,复制命令时出错,重新全屏 shell 即命令行窗口,重新执行1,2步,即可解决
坑2: 生产服务器部署,提示 meteor npm install bcrypt --save
当使用了account用户系统包后,必需安装 bcrypt 加密模块,以上提示是在开发环境执行的语句,同时,最新版本直接使用 npm i bcrypt --save 即可,不需要再使用 meteor npm,当在生产服务器时,执行命令是无效的,目前发现解决方法是进入 programs/server/npm/node_modules 目录,运行:
npm i bcrypt 或者 cnpm i bcrypt
安装即可有效解决,如此解决方法欠妥或并不是正确的方法,请留言给我予以更正。
坑3:npm install 部署死活安装不上 fibers 模块
问题:在宿主机部署 进入 programs/server 执行: npm install 死活安装不上 fibers 模块,包括 使用 cnpm 淘宝源。
解决:升级 宿主机 npm 为最新版本,发现原版本为 2.x,升级时间太长,使用 cnpm i -g npm 淘宝源升级
坑4: 生产部署时,提示,const { pause } = require("./debug.js");
问题: 当采用 Meteor 1.6 开发,默认 nodeJs 已升级为 8.x,如果原来 镜像内的 NodeJs 是 4.x,即版本冲突,在部署环境,用 node -v 检测版本是否一致,如显示 v4.7.3,需要升级,请使用第二部份,安装NodeJs 的方法升级,直接升级为,8.x
第八部份 总结和散花求赞
作者来自墨子品牌, 官方网站: www.mozibrand.com 承接网站建设、APP、微信业务
喜欢请关注,有问题请留言
另外,你可以加群:606933416