在 Ubuntu 部署基于 Meteor 的 Web 应用程序
本篇教程帮助大家完成 Meteor 的安装和部署一个简单的 Todo List DEMO 程序。教程参考自 Digital Ocean 的一篇外文教程。
会涉及到下面的一些知识:
- 安装 Meteor.js
- 搭建轻量级的 WebServer(Nginx) 和后端数据库( MongoDB )
- 配置 Web 应用程序
- 配置日常的数据库备份方案
这是 Meteor 的一个介绍:
介绍来自于 IBM 论坛这篇不错的中文教程:http://www.ibm.com/developerworks/cn/web/w...
Meteor
是一种新的 JavaScript 框架,用于自动化和简化实时运行的 Web 应用程序的开发。它使用一个名为分布式数据协议 (Distributed Data Protocol, DDP) 的协议来处理实时通信,使用 WebSockets 的新浏览器以及使用 Asynchronous JavaScript + XML (Ajax) 长轮询的旧浏览器来支持这种协议。在这两种情况下,浏览器到服务器的通信是透明的。
DDP 协议旨在处理 JavaScript Serialized Object Notation (JSON) 文档集合,使 JSON 文档容易创建、更新、删除、查询和访问。因为 DDP 是一种开源协议,所以您可将它连接到任何客户端或数据存储。它为 MongoDB 提供了开箱即使用支持。
事实上,Meteor 提供了两个 MongoDB 数据库:一个客户端缓存数据库和服务器上的一个 MongoDB 数据库。当一个用户更改一些数据时(例如通过单击 Save),在浏览器中运行的 JavaScript 代码会更新本地 MongoDB 中的相应的数据库项,然后向服务器发出一个 DDP 请求。该代码立即像操作已获得成功那样继续运行,因为它不需要等待服务器回复。与此同时,服务器在后台更新。如果服务器操作失败或返回一个意外结果,那么客户端 JavaScript 代码会依据从服务器新返回的数据立即进行调整。这种调整称为延迟补偿,向用户提供了更高的认知速度。
显然,甚至连 Meteor 的模板系统也是为简化实时通信而设计的。在大多数 Web 框架中,您可以轻松地混合使用超文本标记语言 (HTML) 和代码,或者与 HTML 等效的标记,比如 HTML 抽象标记语言 (Haml)。这使您能够轻松地将来自数据库的动态值插入发送给用户的页面中。在这之后,您应该负责准备提供一个系统来观察对数据的更改,然后更新您的标记。但是,Meteor 中的模板系统用于记录访问了模板中的哪些数据,并自动回调,以便在底层数据更改时调用此 HTML,使实时模板变得更加简单快捷。
Meteor 的目录结构: http://docs.meteor.com/#/full/structuringy...
Github
: https://github.com/meteor/meteor
官方网站
:https://github.com/meteor/meteor
完整文档
: http://docs.meteor.com/
在开始之前需要你做些准备:
- VPS 的 SSH 账号,拥有 sudo 权限;
- 公网可以访问的域名,没有的话就直接拿 IP 访问;
- 一个本地开发好的 Meteor 测试项目(本文中拿 Meteor 官网上面的 Todo List 示例程序做演示)
如果你创建了一台 VPS,可以参考这篇教程进行初始化
Ubuntu 14.04 CheckList : 分享:[Server Hacks] New Ubuntu 14.04 Server Checklist
配置 Nginx Web 服务器
下载安装 Nginx
sudo apt-get install nginx
在 /etc/nginx/sites-available
目录下面创建一个虚拟主机配置 todo
:
sudo touch /etc/nginx/sites-available/todo
文件内容:
server_tokens off; # 安全考虑:不显示 nginx 的版本
# Websocket 代理连接配置
upstream meteor_server {
# additional health checks for each instance
# do not send requests to a backend server if they failed to respond 3 times in a row
# define fail as no request for 30s
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; #locally running Meteor on port 3000
server 127.0.0.1:8080 max_fails=3 fail_timeout=30s weight=2; # second backend server receives twice the requests as the first server
ip_hash; # send the same IP always to the same backend server
}
## redirect all non-www requests to the www subdomain
## Also redirect non-ssl to ssl, remove the server block if you do not use SSL
server {
listen 80;
server_name DOMAIN;
if ($host = 'DOMAIN') {
return 301 https://$host$request_uri;
}
}
## actual site configuration
server {
server_name DOMAIN
#listen 80 spdy; #uncomment this line if you do not use SSL
# delete the following SSL block if you do not need https
listen 443 ssl spdy;
ssl_certificate /etc/nginx/ssl/todo.crt;
ssl_certificate_key /etc/nginx/ssl/todo.key;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:DES-CBC3-SHA:!ADH:!AECDH:!MD5;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/todo.crt;
resolver 8.8.8.8 8.8.4.4;
# end of SSL block
## performance boost using gzip
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# end of GZIP block
## this is the actual load balancing to the meteor backend servers
location / {
proxy_pass http://meteor_server; # the name used in upstreams, substituted for any of the defined instances
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
# Make sure to use WebSockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
## if nginx has access to the js and css files created by meteor, you can proxy these as well
#location ~* "^/[a-z0-9]{40}\.(css|js)$" {
# root /home/meteor/app/programs/web.browser; # where to find the meteor created files
# access_log off;
# expires 30d;
# add_header Pragma public;
# add_header Cache-Control "public";
#}
## serve static files by nginx instead of Meteor (the public/ folder)
location ~ \.(jpg|jpeg|png|gif|mp3|ico|pdf) {
root /home/meteor/app/programs/web.browser/app; # this should point at the content from the public folder
access_log off;
expires 30d;
add_header Pragma public;
}
}
关于 SSL 的配置,可以看这篇文章 https://www.digitalocean.com/community/tut...
更多关于 Nginx 的虚拟主机配置,可以看这里:https://www.digitalocean.com/community/tut...
如果没有域名,你可以暂时把 server_name
配置为 IP 地址;
我们需要移除掉默认的虚拟主机配置:
sudo rm /etc/nginx/sites-enabled/default
启用新的虚拟主机配置:
sudo ln -s /etc/nginx/sites-available/todo /etc/nginx/sites-enabled/todo
快速查看一下配置语法是否有问题:
sudo nginx -t
立刻应用最新的配置:
sudo nginx -s reload
现在访问配置的域名或者 IP,你应该看到 ·502 Bad Gateway· , 这是正确的,应为我们还没有把 Meteor 部署上去;
设置 MongoDB 数据库
sudo apt-get install mongodb-server
因为我们目前只通过本地连接 MongoDB 数据库,所以没有加任何权限认证,需要保证系统没有非法的 SSH 用户登录。
查看一下 MongoDB 是否正常运行:
netstat -ln | grep -E '27017|28017'
输出结果:
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:28017 0.0.0.0:* LISTEN
unix 2 [ ACC ] STREAM LISTENING 207113 /tmp/mongodb-27017.sock
创建一个 bash
脚本来完成日常的数据库备份工作:
sudo touch /etc/cron.d/mongodb-backup
文件内容:
@daily root mkdir -p /var/backups/mongodb; mongodump --db todos --out /var/backups/mongodb/$(date +'\%Y-\%m-\%d')
安装 Meteor 应用程序
首先,需要安装一下 nodejs
,因为 Meteor 需要较新版本的 nodejs,需要添加一下 nodejs 的仓库源:
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
最佳实践是为运行 Meteor 创建一个用户:
sudo adduser --disabled-login todo
写一点开机启动脚本帮我们完成启动一些服务的重复性工作:
sudo touch /etc/init/todo.conf
文件内容:
# 启动脚本文件 at /etc/init/todo.conf
description "Meteor.js (NodeJS) application"
author "Jobs Long <jobslong@ideas.top>"
# 启动服务
start on started mongodb and runlevel [2345]
# 停止服务
stop on shutdown
# 崩溃的时候自动重启
respawn
respawn limit 10 5
# 禁用系统内置的日志记录
# console log
# 切换到 todo 用户来执行
setuid todo
setgid todo
# 这个脚本语言大家如果看不懂,可以先略过
script
export PATH=/opt/local/bin:/opt/local/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
# set to home directory of the user Meteor will be running as
export PWD=/home/todo
export HOME=/home/todo
# leave as 127.0.0.1 for security
export BIND_IP=127.0.0.1
# the port nginx is proxying requests to
export PORT=8080
# this allows Meteor to figure out correct IP address of visitors
export HTTP_FORWARDED_COUNT=1
# MongoDB connection string using todos as database name
export MONGO_URL=mongodb://localhost:27017/todos
# The domain name as configured previously as server_name in nginx
export ROOT_URL=https://todo.net
# optional JSON config - the contents of file specified by passing "--settings" parameter to meteor command in development mode
export METEOR_SETTINGS='{ "somesetting": "someval", "public": { "othersetting": "anothervalue" } }'
# this is optional: http://docs.meteor.com/#email
# commented out will default to no email being sent
# you must register with MailGun to have a username and password there
# export MAIL_URL=smtp://postmaster@mymetorapp.net:password123@smtp.mailgun.org
# alternatively install "apt-get install default-mta" and uncomment:
# export MAIL_URL=smtp://localhost
exec node /home/todo/bundle/main.js >> /home/todo/todos.log
end script
部署 Meteor 应用程序
我们在自己本地机器上面安装 Meteor
程序来创建示例程序:
Mac OS or Linux
curl https://install.meteor.com | /bin/sh
Window 环境请下载官网的二进制包进行安装
创建示例程序 Todo List :
meteor create --example todos
切换到项目目录里面构建项目:
meteor build . --server http://172.21.4.58
通过 scp
或者 ftp 把构建好的二进制包上传到服务器:
scp todos.tar.gz root@ServerIP:/home/todo
解压
tar -zxvf todos.tar.gz
进入程序服务端目录更新 npm 依赖:
cd /home/todo/bundle/programs/server && npm install
授予运行用户合适的权限:
chown todo:todo /home/todo -R
大功告成
启动一下应用程序:
start todo
当你之后本地修改做了一些程序更改之后,需要按照部署的流程重新上传部署一下,你也可以写个脚本完成自动化部署;
在安装过程中你肯定会遇到各种麻烦,但不希望你去问别人我安装不上去,程序运行不了这种问题。日志文件和 Google 是你首要而且很重要的解决途径。
/home/todo/todo.log
Meteor 应用程序的日志文件/var/log/nginx/error.log
Nginx 日志文件/var/log/mongodb/mongodb.log
MongoDB 数据库日志文件
示例程序界面:
推荐文章: