阿里云ECS服务器部署Node.js项目全过程详解

本文详细介绍如何部署NodeJS项目到阿里云ECS上,以及本人在部署过程中所遇到的问题、坑点和解决办法,可以说是全网最全最详细的教程了。同时讲解了如何申请阿里云免费SSL证书,以及一台ECS服务器配置多网站的Nginx配置方法等。

原文链接:http://www.kovli.com/2017/09/19/ecs-deploy/
作者:Kovli

1. 云服务器选择

阿里云ECS是阿里巴巴旗下,目前国内最成熟稳定的云服务器提供商

本文基于阿里云ECS云服务器讲解,目前有个人版,企业版,学生版可以选择。

个人版 新用户免费试用,0元即可拥有属于自己的服务器了。

学生版 目前是0元领取活动,需要学生身份证明。

企业版 新用户免费试用,0元即可拥有属于自己的服务器了。

优惠券 阿里云产品通用代金券最高300元。

这里以个人版 为例,流程都一样的。

选购好云服务器,初学者1核1G就足够了,也就是默认的第一个入门级配置。

操作系统选择CentOS系统

由于阿里云ECS购买页面经常改版,以下购买流程图仅供参考,入门的话参数都选最低配置即可

image

点击立即购买按钮,进入确认订单页面,这里选择自定义密码,设置ssh登录密码,后面要用,请牢记此密码

image

购买好以后,进入控制台,左侧功能栏选择云服务器ECS

image

点击箭头所指位置,即可获取服务器的公网地址,如图

image

记住公网IP,下一步要用到。

2. 登陆服务器

打开 Terminal,

输入 ssh root@公网IP

输入之前自己设的服务器登录密码(如果忘了,可以去上图右侧的管理-更多-重置密码)

即可登陆服务器。

首次登陆可能会询问公钥,yes 即可。

关于 ssh 登陆,想要详细了解的可以看阮一峰写的这篇ssh原理与应用

上述操作是使用 root 用户身份登陆,会直接进入到下图 红色箭头标出的 root 目录下。

cd .. 跳转到上一层, 再 ls -a ,就可以看到类似下图的目录结构了。

image

图片引用自《鸟哥的Linux》

3. 安装Nginx

1. 在配置 nginx 时,可能会依赖于 PCRE 包和 zlib 包,先进行安装:

cd /usr/local 切换目录

cd /usr/local
yum -y install pcre pcre-devel
yum install -y zlib-devel

2. 下载 nginx,这里nginx版本号可以根据需要选择,我选择1.13.3是当时最新的版本了,下面的node版本、mongodb版本都可以根据自己的需要选择

nginx官网版本列表

cd /usr/local/src 
wget http://nginx.org/download/nginx-1.13.3.tar.gz

3. 解压缩

tar -xvzf nginx-1.13.3.tar.gz

4. 配置nginx

下载解压openssl

wget https://www.openssl.org/source/openssl-1.0.2l.tar.gz

tar -xvzf openssl-1.0.2l.tar.gz 

cd 进入nginx解压包里,执行之前安装的pcre-devel与openssl-devel解决依赖问题

cd nginx-1.13.3
yum -y install pcre-devel openssl openssl-devel

再执行配置脚本来进行编译预处理

./configure --prefix=/usr/local/nginx --conf-path=/usr/local/nginx/nginx.conf --with-http_stub_status_module --with-http_gzip_static_module --with-http_ssl_module --with-openssl=/usr/local/src/openssl-1.0.2l

成功后显示如下信息,

Configuration summary
  + using system PCRE library
  + using OpenSSL library: /usr/local/src/openssl-1.0.2l
  + using system zlib library

  nginx path prefix: "/usr/local/nginx"
  nginx binary file: "/usr/local/nginx/sbin/nginx"
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx"
  nginx configuration file: "/usr/local/nginx/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

make

make && make install

5. 使用 openssl 生成证书(以下介绍的是自己生成的供学习用,正常面向市场的产品请用认证的)

openssl req -new -x509 -nodes -out server.crt -keyout server.key

移动证书到nginx文件夹

mv server.crt /usr/local/nginx
mv server.key /usr/local/nginx

认证的SSL证书,申请阿里云免费ssl证书:

如何申请免费SSL证书 - 阿里云云盾证书

操作技巧:想看到免费的证书,品牌选择Symantec,证书类型选择免费型DV SSL

6. 修改 nginx 配置文件:

vi /usr/local/nginx/nginx.conf

修改如下


#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    # 关闭错误页面的nginx版本数字,提高安全性
    server_tokens off;

    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    include /usr/local/nginx/sites-enabled-server/*;


}

新建文件夹用于存放多网站的nginx配置文件

cd /usr/local/nginx/
mkdir sites-enabled-server

sites-enabled-server里面新增若干文件,以便这个ECS可以给多网站使用

vim default


server {
        listen 80;
        server_name _;

        return 404;
}

server {
        listen       80;
        server_name  你的域名.com www.你的域名.com;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://127.0.0.1:nodejs配置的端口号;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

vim default-ssl

server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      server.crt;
        ssl_certificate_key  server.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
             proxy_pass http://127.0.0.1:nodejs配置的端口号;
        }
    }
~       

继续新增网站,例如,vim mywebsite.cn

server {
        listen       80;
        server_name  mywebsite.cn www.mywebsite.cn;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://127.0.0.1:nodejs配置的mywebsite的端口号;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

7. 启动nginx

/usr/local/nginx/sbin/nginx

4. 安装 node

  • node -- 编译后二进制文件应在/usr/local/bin/node 下

  • mongodb -- 安装在/usr/local/mongodb 下

下面就一步一步来

1. 首先升级CentOS
yum -y update

2. 升级后,跳转到 /usr/local/src , 这个文件夹通常用来存放软件源代码

cd /usr/local/src

3. 下载 nodejs 代码,也可以使用scp命令直接上传,因为下载实在太慢了。

wget http://nodejs.org/dist/node-latest.tar.gz(下载最新)
wget http://nodejs.org/dist/v7.10.0/node-v7.10.0.tar.gz(推荐,稳定版本)

4. 解压
tar -xzvf node-v0.12.5.tar.gz

5. 进入解压后的文件夹
cd node-v0.12.5

6. 执行配置脚本来进行编译预处理
./configure

7. 安装v8可能有警告, //需要安装gcc

8. sudo yum install gcc-c++ //安装gcc

9. 编译源代码及安装

当编译完成后,需要使之在系统范围内可用, 编译后的二进制文件将被放置到系统路径,默认情况下,Node二进制文件应该放在/user/local/bin/node文件夹下

make && make install

10. 安装pm2,建议 global 安装
npm install pm2 -g

11. 建立超级链接, 不然 sudo node 时会报 "command not found"

  • sudo ln -s /usr/local/bin/node /usr/bin/node
  • sudo ln -s /usr/local/lib/node /usr/lib/node
  • sudo ln -s /usr/local/bin/npm /usr/bin/npm
  • sudo ln -s /usr/local/bin/node-waf /usr/bin/node-waf
  • sudo ln -s /usr/local/bin/pm2 /usr/bin/pm2

Nodejs到这里就基本安装完成了。

5. 安装mongodb

  • 软件安装位置:/usr/local/mongodb

  • 数据存放位置:/var/mongodb/data

  • 日志存放位置:/var/mongodb/logs

1. 首先下载安装包

MongoDB下载中心

cd /usr/local
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.6.tgz

2. 解压安装包,重命名文件夹为mongodb

tar zxvf mongodb-linux-x86_64-2.6.0.tgz
mv mongodb-linux-x86_64-2.6.0 mongodb

3. 创建数据和日志存放目录

mkdir /var/mongodb
mkdir /var/mongodb/data
mkdir /var/mongodb/logs

4. 打开rc.local文件,添加CentOS开机启动项:

vim /etc/rc.d/rc.local

5. 将mongodb启动命令追加到本文件中,让mongodb开机自启动:

/usr/local/mongodb/bin/mongod --dbpath=/var/mongodb/data --logpath /var/mongodb/logs/log.log --logappend --auth --port 27017 --fork

6. mongo权限设置

sudo vi /etc/mongod.conf

较新版本的增加安全校验的方法是配置文件最后面加上(网上很多旧版写法都是无效的)

security: authorization: enabled

如下所示:

systemLog:
 destination: file
 path: /var/mongodb/logs/log.log
 logAppend: true
storage:
 dbPath: /var/mongodb/data
net:
 bindIp: 127.0.0.1
security:
 authorization: enabled

然后重启mongodb即可,这里说明下,初学也可以不设这个选项,这样操作数据库就不需要用户名密码了,从安全的角度看还是设了比较好,后面都是以设了安全校验来讲解。

7. 关闭 vim 后,直接手动启动mongodb

/usr/local/mongodb/bin/mongod --dbpath=/var/mongodb/data --logpath /var/mongodb/logs/log.log --logappend --auth --port 27017 --fork

8. 启动mongo shell

cd /usr/local/mongodb/bin/
./mongo

9. 在 mongo shell 中创建超级管理员以及相关数据库到管理员及数据库

use admin //admin database
db.createUser({
 user: "myAdmin",
 pwd: "******",
 roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
 }
 )

10. 使用特权进入

./mongo -u "mydmin" -p "******" --authenticationDatabase "admin"

11. 创建新数据库,并设置管理员

> use mywebsite
switched to db mywebsite
> db.createUser(
... {
... user: "mywebsiteAdmin",
... pwd: "******",
... roles: [ { role: "readWrite", db: "mywebsite" }]
... }
... )
> use secondwebsite
switched to db secondwebsite
> db.createUser(
... {
... user: "secondwebsiteAdmin",
... pwd: "******",
... roles: [ { role: "readWrite", db: "secondwebsite" }]
... }
... )

以后进入其中的数据库需要权限,如果用超级管理员则不需要

db.auth("mywebsiteAdmin", "******")

12. mongodb数据迁移(用于从指定地址数据库迁移到云服务器上)

//存放到某个目录
./mongodump -h 127.0.0.1:27017 -d mywebsite -o /home/mywebsite -u "mywebsiteAdmin" -p "******"

//取出
./mongorestore  -h 127.0.0.1:27017 -d mywebsite /home/mywebsite/mywebsite -u "mywebsiteAdmin" -p "******"

13. mongodb连接需要安全校验的配置
以app.js为例,

设置数据库连接
vim app.js

数据库连接类似下面的格式,由于数据库安装在同一服务器,因此 host 为127.0.0.1:

var dbUrl = 'mongodb://用户名:登陆密码@127.0.0.1/databaseFoo';
mongoose.connect(dbUrl)

例如我的app.js里的这一段代码

// 配置数据库
mongoose.Promise = global.Promise;
let mongoConnectUrl = 'mongodb://' + config.database.USERNAME + ':' + config.database.PASSWORD + '@' + config.database.HOST;
mongoose.connect(mongoConnectUrl);

到这里 mongodb 基本已经安装设置完成了。

6. 上传NodeJS代码到服务器上

把nodejs的程序放在 /home

cd /home

我使用码云管理代码。它的私有库是免费的。基本操作和 github 一样。

1. 注意公钥的生成与添加

ssh-keygen -t rsa -C "mywebsite@gmail.com"

查看与复制公钥

cat ~/.ssh/id_rsa.pub

2. git安装

yum install git

3. 复制代码:
git clone https://git.oschina.net/xxxxxxx/nodeapp.git //你的repo地址

4. 进入 nodeapp 文件夹
cd nodeapp
(若后续代码变更,提交到 git repo 后直接git pull即可部署代码)

5. 安装nodeapp的所有依赖

npm install

注意,使用淘宝镜像避免未知问题

npm --registry https://registry.npm.taobao.org install

7. 启动Node服务

这里根据你nodejs所使用的框架不同而不同,

例如koa2可以在package.jsonscripts里设置,参考阮一峰的npm scripts 使用指南

thinkjs或者egg都有自己的启动方式,就不一一叙述了

这里要注意的是,如果直接 npm startnode app.js 启动,则一旦退出 ssh 远程登陆,服务就会停止运行。

使用pm2就可以解决这个问题,如果跟着教程走,你已经全局安装了pm2了,可以直接使用

8. 其他说明

这篇文章是汇聚了网上诸多教程及本人从零开始部署遇到的各种问题和坑点的解决方案所形成的一篇详细教程,由于涉及点比较多,加上版本更新迭代,如果在部署过程中遇到问题,可以在下面评论提问(需要登录Github账号才可以评论),或者给我发邮件(admin@kovli.com)。

本文所述的本地操作系统:MacOS系统,阿里云ECS操作系统:CentOS 7.3,本地如果是Windows环境终端操作可能有所不同。

Nginx的一些常用操作方法:

/usr/local/nginx/sbin/nginx # 启动
/usr/local/nginx/sbin/nginx -t #检查配置文件编写是否正确
/usr/local/nginx/sbin/nginx -s reload #Nginx平滑重启 (一般用这个就可以了)
/usr/local/nginx/nginx.conf #配置文件。

文中已引用了部分参考文章,同时感谢下面的参考文章的作者:
http://www.jianshu.com/p/0496ef49b2a5
http://itbilu.com/other/relate/NJ2TJohl.html
https://segmentfault.com/a/1190000004051670
http://borninsummer.com/2015/06/17/notes-on-developing-nodejs-webapp/
https://bbs.aliyun.com/read/146189.html
https://segmentfault.com/q/1010000003937372


版权声明:
转载时请注明作者Kovli以及本文地址:
http://www.kovli.com/2017/09/19/ecs-deploy/


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容