/ meteor

deploy-meteor-app

开始之前

  • An existing Meteor app on a separate development computer
  • A fresh Ubuntu 14.04 server; existing Meteor installations should work in most cases
  • root access to the server to execute commands
  • Replace todos.net with the domain name you are actually using (or leave it if you don't have a domain and will be using an IP address instead)
  • Replace todos with the name of your application

本地准备工作

查看 Node.js 版本:

cat .meteor/local/build/.node_version.txt

Output: v0.10.45

在build之前,master 分支需要移除 insecureautopublish,执行命令:

meteor remove insecure autopublish
meteor build ../output

insecure 包是 meteor 默认安装的,它的作用是允许客户端代码可以直接修改数据库中的数据。例如:在项目中我们创建了一个叫做 Messages 的 mongodb collection,因为 insecure 软件包的存在,其实我们可以在客户端代码中直接调用 Messages.insert() 接口把聊天内容插入到数据库中,在生产环境下会引发安全问题。

命令执行完之后,会生成文件 todos.tar.gz。请参考 meteor build

然后把 todos.tar.gz 软件包传送到服务器上 home 主目录下,运行命令:

cd ../output
scp todos.tar.gz root@todos.net:~/

到目前为止,本地开发机上的工作就全部完成了,后续工作全部在服务器上完成。

服务器上的准备工作

首先要登录到远端服务器,执行命令:

ssh root@todos.net

Updated package lists

apt-get update

Step1 - Setting Up an Nginx Web Server

apt-get install nginx

创建配置文件

vi /etc/nginx/sites-available/todos

添加如下内容:

server_tokens off; # for security-by-obscurity: stop displaying nginx version

# this section is needed to proxy web-socket connections
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# HTTPS server
server {
    listen 443 ssl spdy; # we enable SPDY here
    server_name todos.net www.todos.net;

    # ssl_certificate /etc/letsencrypt/live/todos.net/fullchain.pem;
    # ssl_certificate_key /etc/letsencrypt/live/todos.net/privkey.pem;

    ssl_stapling on;
    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;

    ssl_prefer_server_ciphers on;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK';

    add_header Strict-Transport-Security "max-age=31536000;";

    root /usr/share/nginx/html; # root is irrelevant
    index index.html index.htm; # this is also irrelevant

    # pass all requests to Meteor
    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade; # allow websockets
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header X-Forwarded-For $remote_addr; # preserve client IP

        # this setting allows the browser to cache the application in a way compatible with Meteor
        # on every applicaiton update the name of CSS and JS file is different, so they can be cache infinitely (here: 30 days)
        # the root path (/) MUST NOT be cached
        if ($uri != '/') {
            expires 30d;
        }
    }
}
# HTTP
server {
  listen 80;
  server_name todos.net www.todos.net;
  return 301 https://$host$request_uri;
}

Disable the default vhost:

rm /etc/nginx/sites-enabled/default

And enable our Meteor vhost:

ln -s /etc/nginx/sites-available/todos /etc/nginx/sites-enabled/todos

Test that the vhost configuration is error free:

nginx -t

If everything is looking good we can apply the changes to Nginx:

nginx -s reload

At this point, you can use your web browser to visit https://todos.net (or your IP address). It will show us 502 Bad Gateway. That is OK, because we don't have Meteor running yet!

Step2 - Setting Up a MongoDB Database

安装步骤按照 mongodb 官方提供的文档,Ubuntu v14.04 中安装 mongodb 3.0

sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10

echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list

sudo apt-get update

sudo apt-get install -y mongodb-org

安装成功之后,执行命令 mongo:

server@aliyun:~$ mongo
>

In order to have daily backups available in case something goes wrong, we can optionally install a simple command as a daily cron job. Create a file /etc/cron.d/mongodb-backup:

@daily root mkdir -p /var/backups/mongodb; mongodump --db todos --out /var/backups/mongodb/$(date +'\%Y-\%m-\%d')

Step 3 — Installing the Meteor Application

安装 NVM

安装

首先,安装 NVM

nvm install v0.10.45
nvm alias default 0.10.45

It's a good practice to run our Meteor application as a regular user. Therefore, we will create a new system user specifically for that purpose:

adduser --disabled-login todos

Output:

Adding user `todos' ...
Adding new group `todos' (1001) ...
Adding new user `todos' (1001) with group `todos' ...
Creating home directory `/home/todos' ...
Copying files from `/etc/skel' ...
Changing the user information for todos
Enter the new value, or press ENTER for the default
        Full Name []:
        Room Number []:
        Work Phone []:
        Home Phone []:
        Other []:
Is the information correct? [Y/n]

Step 4 — 使用 PM2 管理应用

内容参考 pm2 部分。之前用的是 /etc/init/app.conf 的方法,但不如 pm2 好用。

Step 5 — Deploying the Meteor Application

mv todos.tar.gz /home/todos
cd /home/todos
tar -zxf todos.tar.gz

Take a look at the project README:

cat /home/todos/bundle/README

The bundle includes a README file with contents:

This is a Meteor application bundle. It has only one external dependency:
Node.js 0.10.40 or newer. To run the application:

  $ (cd programs/server && npm install)
  $ export MONGO_URL='mongodb://user:password@host:port/databasename'
  $ export ROOT_URL='http://example.com'
  $ export MAIL_URL='smtp://user:password@mailhost:port/'
  $ node main.js

Use the PORT environment variable to set the port where the
application will listen. The default is 80, but that will require
root on most systems.

Find out more about Meteor at meteor.com.

Now we need to install some required npm modules. To be able to build some of them, we also need to install g++ and make:

apt-get install g++ make
# apt-get install build-essential
cd /home/todos/bundle/programs/server
npm install

We are almost ready to run the application, but since we operated on files as root, and they should be owned by the todos user, we need to update the ownership of the project directory:

chown todos:todos /home/todos -R

Step 6 — Showtime

At this point we have everything we need to run our Meteor application:

Node.js environment installed
Application installed in its project directory
Upstart service configured to run the application
MongoDB database
Nginx proxy server in front of our Meteor application to provide SSL encryption
To start our application, let's execute this command from the project directory:

start todos

Now you should be able to view your application in the browser at https://todos.net.

Re-deploying the Application

Development server:

Build:

meteor build /app/dir

Upload:

scp todos.tar.gz root@todos.net:/home/todos

Production server:

Expand:

tar -zxf /home/todos/todos.tar.gz

Move into the project folder:

cd /home/todos/bundle/programs/server

Update the npm modules (you may see a few warnings):

npm install

Restart the app:

sudo restart todos

SEO

Enable SEO