Node.js生产环境完整部署指南

项目上线之前的最后一步,生产环境搭建、代码部署,在一些公司可能是运维同事在做这些事,但是做为一名Developer掌握如何进行服务部署也是你通往全栈工程师的必经之路。本文编程语言主要讲解了Node.js,对于用户权限管理、服务器安全等级增强、MongoDB生产部署、Nginx映射等不论你使用Java、PHP、Python等编程语言在进行部署时都是可以应用到的。

快速导航

用户权限管理及登陆服务器

增强服务器安全等级

Node.js生产环境部署

Mongodb生产环境部署

代码部署

用户权限管理及登陆服务器

创建用户

  • 创建用户名: adduser demo_manager 之后会提示设置密码 和一些信息

  • 修改用户权限: gpasswd -a demo_manager sudo

    成功之后会出现一个添加user的提示 Adding user demo_manager to group sudo

  • 编辑文件:sudo visudo

找到 root ALL=(ALL:ALL) ALL 在这段代码下面添加 这个刚创建的user ```bash demo_manager ALL=(ALL:ALL) ALL

#demo_manager  指我们新增的这个用户 以上这些规则对这个用户生效
#第一个ALL 这些规则对所有用户生效
#第二个ALL demo_manager可以任意用户来执行命令
#第三个ALL demo_manager 可以以任何的组来执行命令
#第四个ALL 这个适用于所有命令

* 重启配置:``` service ssh restart

用户查找

  • 查看用户:cat /etc/passwd
  • 查看用户组:cat /etc/group
  • 查看当前活跃的用户列表:w
  • 查看指定用户:cat /etc/passwd|grep root
  • 查看当前服务用户:whoami

用户删除

userdel 是一个底层用于删除用户的工具。在 Debian 上,我们通常会使用 deluser 命令。userdel 会查询系统账户文件,例如 /etc/password 和 /etc/group。那么它会删除所有和用户名相关的条目。在我们删除它之前,用户名必须存在。

  • 删除用户:userdel testuser
  • 完全删除用户家目录:userdel -r testuser

登录远程服务器

  • 方法1:ssh root@ip地址

  • 方法2:

    • 安装zsh并编辑配置文件 subl .zshrc
      # 通过软链接加入命令
      alias ssh_demo="ssh root@ip地址"
      
    • 重载配置文件 source .zshrc
    • 控制台输入ssh_demo将自动调用上面配置好的这个命令
  • 方法3:

    如果有多台服务器,每次都需要输入密码 这样还是有些繁琐的 适合通过私钥认证的方式来,实现无密码登录。

    先确定本地有没生成过秘钥,如果之前生成过就不要在生成,这样会覆盖你之前的电脑上的秘钥,也许会影响到你的其他程序。

    • 进入 .ssh 目录执行以下配置秘钥命令:
      ssh-keygen -t rsa -b 4096 -C "demo_manager@qq.com"
      
      将会生成 id_rsa id_rsa.pub 两个文件, cat id_rsa 查看内容

    进入.ssh目录,开启ssh代理 eval "$(ssh-agent -s)"

    进入.ssh目录,将ssh key加入这个代理中 ssh-add ~/.ssh/id_rsa

    以上操作是在本地电脑上生成私钥,同样现在我们登入服务器,按照上面的步骤在服务器上生成私钥,如果已经有了,就不需要了。

    进入服务器,如果没有生成过密钥,重复上述步骤在服务器端生成密钥,进入.ssh目录,创建一个授权文件 vim authorized_keys,将本地电脑生成的公钥放入这个授权文件里 现在服务器已经持有了某台电脑的上的公钥,此时这台电脑就可不需输入密码来登录这台服务器

    修改授权文件权限 chmod 600 authorized_keys

    重启ssh服务 sudo service ssh restart

    采用了密钥登录,如果本地链接还需要输入密码,可参考这个解决方案 [issue]

增强服务器安全等级

修改端口号

服务器默认端口是22, 出于基本的安全考虑也是需要来修改这个端口号的

修改配置文件 vim /etc/ssh/sshd_config 执行此命令会提示输入密码

# 修改port端口号 范围为1 到 65536, 0 1024之间的可能会被系统所占用,因此最好采用1024之外的  

Port 39999 # 此时将会禁用22端口

UseDNS no # 此处确保为 no

# 加入我们为这个服务创建的用户
AllowUsers demo_manager

# 出去安全层面考虑 可以关闭root密码登录
PermitRootLogin no

# 已经配好了秘钥登录的 可以将下面是是否允许密码登录(授权) 给关掉
PasswordAuthentication no

# 是否允许空密码
# PermitEmptyPasswords no

重启ssh服务,使端口生效 sudo service ssh restart

设定iptables规则

清空掉所有的iptables 规则 sudo iptables -F

修改配置文件 sudo vim /etc/iptables.up.rules

*filter

#允许所有建立起来的链接
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

#允许所有出去的流量, 此处也可以设置一些特定的流量规则
-A OUTPUT -j ACCEPT

# 允许https协议下的请求链接
-A INPUT -p tcp --dport 443 -j ACCEPT

# 所有的网站访问一台服务器都是从80端口进去的,因此让80端口的流量可以进出
-A INPUT -p tcp --dport 80 -j ACCEPT

# 通过这条设定 我们登录服务器就只能通过这个端口,如果是别的防火墙就会拦截
-A INPUT -p tcp -m state --state NEW --dport 39999 -j ACCEPT

# 允许外网来ping这台服务器
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT

# 记录下被拒绝的这些请求
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied:" --log-level 7

# 对一些恶意的请求做一些拦截 ,下面的例子意思是 如果一个ip在60内对80端口 发出了150次请求 我们就认为他是恶意请求
-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


# reject all other inbound 拒绝所有其他的进入到这台服务器的流量
-A INPUT -j REJECT
-A FORWARD -j REJECT

COMMIT

告诉iptables 配置文件的位置 sudo iptables-restore < /etc/iptables.up.rules

查看防火墙的状态 sudo ufw status

如果为 inactive 表示没被激活,执行此命令来激活(如果激活状态为 active) sudo ufw enable

设置防火墙开机自启动 sudo vim /etc/network/if-up.d/iptables

#!/bin/sh
iptables-restore /etc/iptables.up.rules

给予这个脚本执行的权限 sudo chmod +x /etc/network/if-up.d/iptables

设置fail2ban

Fail2Ban可以看做是个防御型的动作库,通过监控系统的日志文件,根据检测到的任何可疑的行为,可以触发不同的环境动作

安装 sudo apt-get install fail2ban

安装过程中出现以下错误,执行 sudo apt-get update 更新下源即可

Reading package lists... Done
Building dependency tree       
Reading state information... Done
E: Unable to locate package fail2ban

进入配置文件 sudo vim /etc/fail2ban/jail.conf

#bantime 可以设置的稍微大点
bantime = 3600

# destemail 可以设置为我们自己的邮箱
destemail = 2105324852@qq.com

# 定义下action
action = %(action_mw)s

查看fail2ban的运行状态 sudo service fail2ban status

停掉fail2ban服务 sudo service fail2ban stop

开启fail2ban服务 sudo service fail2ban start

nodejs生产环境部署

安装相关依赖模块

sudo apt-get install vim openssl build-essential libssl-dev wget curl git

nvm版本管理

可以使用nvmhttps://github.com/creationix/nvm这个工具来安装nodejs 方便后面的升级与管理

在控制台执行命令,安装nvm wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash

nvm安装成功,控制台 nvm 找不到命令,解决办法 [issue]

查看所有node版本 nvm ls-remote

查看本地node版本 nvm ls-remote

node安装

安装nodejs版本为v6.9.5 nvm install v6.9.5

把这个版本指定下 nvm use v6.9.5

设定系统的默认版本为 v6.9.5 nvm alias default v6.9.5

查看node版本 node -v

配置npm源为国内的淘宝源 npm --registry=https://registry.npm.taobao.org install -g npm

增加一个系统的文件监控树 echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p

为了保障更快更稳定的速度,此处采用cnpm来替代npm npm --registry=https://registry.npm.taobao.org install -g cnpm

查看cnpm版本 cnpm -v

在网络不是太慢或者连不上的情况下 还是推荐使用 npm,如果有些模块如果实在拿不到我们可以通过cnpm sync 同步到npm 上 例如koa cnpm sync koa

安装一些常用的工具包 npm i pm2 webpack gulp grunt-cli -g

demo验证

到此有关nodejs的环境已安装完毕,下面给个例子来测试,上面的安装是否成功。

新建一个app.js vim app.js

const http = require('http');

http.createServer( (req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World!');
}).listen(8081);

// 注意:如果设置了防火墙,需要在防火墙强的规则里面添加8081这个端口-A INPUT -p tcp --dport 8081 -j ACCEPT

console.log('Server Runing at http://120.26.89.1:8081');

到此Node.js的环境已安装完毕,如果想要通过不带端口号的ip或者域名直接来访问到服务器的80端口, 下一步则需要配置Nginx反向代理,来实现。

nginx映射

新购买的服务器一般都会预装apache如果用户可以删除, 此处给出关于删除apache的命令。

sudo service apache2 stop

sudo service apache stop

#删除apache2
update-rc.d -f apache2 remove

#移出apache2
sudo apt-get remove apache2

安装nginx sudo apt-get install nginx

查看版本 nginx -v

进入 etc/nginx/conf.d 创建配置文件 sudo vim yuming-com-8081.conf

upstream yuming {
  server 127.0.0.1:8081;
}

server {
  listen 80;

  # 当通过这个ip地址来访问,服务器的server_name会匹配到这个地址,向这个地址发起请求的所有流量 都转发到上面的 upstream yuming 里面去
  server_name 服务器IP地址;

  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forward $proxy_add_x_forwarded_for;

    proxy_set_header Host $http_host;
    proxy_set_header X-Nginx-Proxy true;

    //配置指令实现代理 把域名代理到集群(这个应用的名字上面)
    proxy_pass http://yuming;
    proxy_redirect off; //关闭
  }

  # 如果有css 图片 等 需要设置下
  location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|js|pdf|txt){
    root /www/boyi_api/pro/current/public;
  }
}

进入 etc/nginx/ 找到 vim nginx.conf 这个配置文件查看以下两个配置是否打开

# 加载conf.d下面的所有.conf文件
include /etc/nginx/conf.d/*.conf;

# 加载sites-enabled下面的所有文件
include /etc/nginx/sites-enabled/*

查看上面写的配置文件是否正确 sudo nginx -t

重启nginx sudo nginx -s reload

在浏览器中会显示我们的nginx服务器版本信息 如果不想显示 进入 etc/nginx/nginx.confserver_tokens off 注释打开

mongodb

mongodb安装

打开mongodb官网,可以根据自己的系统环境安装,此处介绍ubuntu安装步骤

导入key sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6

为mongodb的配置文件创建一个列表 echo "deb [ arch=amd64 ] http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.4.list

更新本地包 sudo apt-get update

安装mongodb sudo apt-get install -y mongodb-org

因为mongodb的源在国外,可能会很慢,可以按下ctrl+c中断操作来修改源,进入目录 cd /etc/apt/sources.list.d 编辑文件 sudo vim mongodb-org-3.4.list

# 将现有的源 http://repo.mongodb.org 改为 阿里云的 http://mirrors.aliyun.com/mongodb

修改完成之后更新下源 sudo apt-get update

在重新安装,这时会从阿里云镜像来安装,将会快很多 sudo apt-get install -y mongodb-org

开启服务 sudo service mongod start

重启服务 sudo service mongod restart

防火墙中加入mongodb端口号

如果设置了防火墙 打开配置文件加入27017mongodb这个端口号 sudo vim /etc/iptables.up.rules

-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

通过mongo连接实例 看是否成功 mongo

更改MongoDB默认端口号

目前安装已经成功,但是全世界的人都知道mongodb的默认端口跑在27017端口,出于最基本的考虑,改掉这个端口号,编辑此文件 sudo vim /etc/mongod.conf

#找到port 修改为29999
net:
 port: 29999

注意:修改mongodb默认端口号之后 还要更新下防火墙中设置的端口号

开启MongoDB服务

重启mongodb ``` sudo service mongod restart ```` 通过mongo链接 mongo --port 29999

演示如何向线上的数据库导入初识数据

//todo:

本地代码同步第三方仓库进行生产部署

选择代码托管仓库

使用git仓库托管代码,可以选择github或者码云等等都可以,注册一个账号,创建一个项目,与本地的项目进行一个关联

进入本地电脑的.ssh 目录 找到id_rsa.pub文件,拷贝内容,进入码云个人中心里面找到ssh公钥,粘贴本地电脑拷贝的id_rsa内容。

进入本地的项目文件夹,如果是一个干净的项目,执行以下Git命令:

git init
git add .
git remote add origin # 远程仓库地址
git push

到此已经实现了本地项目与第三方仓库的关联。

实现服务器与第三方仓库的关联

同样需要做的是,在服务上如果生成过.ssh 将 id_rsa.pub 公钥放到码云的后台

现在建立project文件夹 mkdir project

进入project 目录 ,拉取远程仓库代码到服务器

git clone 远程仓库地址

PM2部署代码到服务器

通过上面这些操作实现了本地代码推送到私有仓库,服务器也可下载私有仓库的内容,下面开始用pm2管理工具,来管理我们的代码同步更新,服务重启,可参考pm2的文档里面很详细的讲解了从部署到每个参数的设置 pm2

下面简单介绍使用 pm2 部署代码到服务器之上

首先建立一个 ecosystem.json 文件

"apps" : [{
"name"      : "Website", //站点名称
"script"    : "app.js", //启动脚本,就是入口文件
"env": { //启动时候需要传入的变量
    "COMMON_VARIABLE": "true"
},
//生产环境的变量
"env_production" : {
    "NODE_ENV": "pro"
}
}],
//设置部署
"deploy" : {
"production" : {
    // 服务器上我们用户发布部署的user
    "user" : "root",
    // 服务器,如果有多台主机可以数组形式来写
    "host" : ["212.83.163.1", "212.83.163.2", "212.83.163.3"],
    // 端口
    "port" : 22,
    // 分支
    "ref"  : "origin/master",
    // 仓库地址
    "repo" : "git@github.com:repo.git",
    // 项目部署到服务器哪个目录下面的地址
    "path" : "/var/www/website",
    // key校验给取消掉
    "ssh_options": "StrictHostKeyChecking=no",
    // 设置环境
    "env"  : {
    "NODE_ENV": "pro"
    }
}

在发布前需要在服务器创建website文件,且给予可写的权限

mkdir /var/www/website

sudo chmod 777 website

如果是第一次发布,执行以下命令,让pm2连上我们的服务器,从服务器里面来创建我们发布项目所需要的文件夹

pm2 deploy ecosystem.json pro setup

之后每次修改后将不需要setup 使用命令 pm2 deploy ecosystem.json pro 就可以发布啦,到此一个简单的项目发布就已经完成了,有问题可以提issues.

pm2发布遇到的一些问题

  • bash: pm2: command not found
$ pm2 deploy ecosystem.json pro
--> Deploying to pro environment
--> on host 116.62.222.30
  ○ deploying origin/master
  ○ executing pre-deploy-local
  ○ hook pre-deploy
  ○ fetching updates
Fetching origin
  ○ resetting HEAD to origin/master
HEAD is now at 4092462 modify ecosystem.json
  ○ executing post-deploy `pm2 startOrRestart ecosystem.json --env pro`
bash: pm2: command not found

  post-deploy hook failed

Deploy failed

会发现在服务器上无法找到pm2命令,但是确实已经安装了呢,原因在于pm2在服务器上使用的是一个非交互式的ssh链接方式,回到服务器的用户根目录下编辑文件.bashrc vim ~/.bashrc

# 找到以下命令加以注释,不让其提前返回

# [ -z "$PS1" ] && return

执行命令 重新加载 source ~/.bashrc

  • bash: npm: command not found

和上面问题一样编辑.bashrc文件

# 注释掉下面四行
# If not running interactively, don't do anything
# case $- in
#    *i*) ;;
#      *) return;;
# esac

执行命令 重新加载 source ~/.bashrc

补充:df -h 查看硬盘使用情况

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

results matching ""

    No results matching ""