写在最前
这是根据 imooc 上 Scott 老师的课程整理的,主要是方便自己查找,因为真的记不住…
附上链接:Node.js项目线上服务器部署与发布 静态网站,需要数据库的电影网站、公众号,小程序,app 五种项目的部署。
这里只写最简单的静态网站的部署
部署思路
1、完成项目
2、购买域名,备案,解析一些二级域名出来备用
3、购买服务器
4、ssh 远程登录服务器 并进行一些安全配置
5、服务端搭建 node 环境
6、Nginx 反向代理。持有80端口,负责端口转发
7、配置 数据库 mongodb… 安装教程
8、部署上线。本地和服务器上都安装git、pm2(pm2 负责把git的项目更新到服务器)
远程登录服务器
1、第一次 ssh 远程登录
- 腾讯的超级管理员账户是
ubuntu
,阿里的是root
ssh root@公网ip
2、委派一个钦差大臣Jerry,避免用超级管理员账号进行直接操作
- 添加用户 Jerry
sudo adduser Jerry
- 给 Jerry 升官。
sudo visudo
打开 GUN nano 配置文件, 在User privilege specification
下添加Jerry ALL=(ALL:ALL) ALL
对所有sudo生效;Jerry 可以以任何命令来执行操作;Jerry 可以以任何组来执行操作;这个规则适用于所有命令 - 重启 ssh 服务:
service ssh restart
。 然后就可以用 Jerry 登录啦(新开一个命令行,以免登录失败无后路可退):ssh Jerry@外网IP
3、ssh 免密登录
- 本地生成公钥、私钥
密钥存放在本地
.ssh
文件下, 如果没有先创建一下mkdir .ssh
。如果文件夹和密钥都已经存在,可以先备份一下已存在的密钥mv id_rsa id_rsa_backup
。
在 .ssh 目录下做如下操作 : 注册ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
,开启代理eval "$(ssh-agent -s)"
, 加入代理ssh-add ~/.ssh/id_rsa
- 服务端生成 并把本地的公钥放在服务端的
authorized_keys
中
使用Jerry
登录服务端,在/home/Jerry/.ssh
目录下也进行如上操作生成密钥。接着创建授权文件vi authorized_keys
, vi 是 vim 的缩写,把想要免密登录服务器的电脑的公钥ip_rsa.pub
复制过来 - 服务端授权
chmod 600 authorized_keys
并重启ssh 服务service ssh restart
。 这样就可以通过 Jerry 免密登录了, 通过 root 依然需要密码
一个报错
Host key verification failed
原因:
本地 .ssh 文件夹下存在另一个文件
known_hosts
, 这里记录的是所有访问过的计算机(服务器是台远程计算机)的公钥,报错的公钥有问题解决办法:
清除对应的公钥信息。 最粗暴的办法是直接删除文件
rm -rf known_hosts
, 正确的公钥也会被删掉。含蓄一点就是打开文件找到公钥删掉它。 还有一种办法
ssh-keygen -r 公网IP
,可惜报错了 no keys found
提升安全等级
1、修改服务器默认登录端口号
- 打开配置文件
sudo vi /etc/ssh/sshd_config
,服务器默认端口是 22 ,修改Port 22
。0-1024 不用,被系统程序占用,且必须 root 启用,1024-65536
可用。 - 文件末行添加
AllowUsers Jerry
。 顺便确认一下UseDNS no
- 重启 ssh 服务
sudo service ssh restart
- 新开一个命令行登录试试
ssh -p 39999 Jerry@外网IP
2、关闭 root 密码登录
sudo vi /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PrimitEmptyPasswords no (确认一下,默认也是no)
3、配置iptables 和 Fail2Ban 增强安全防护
-
iptables
防火墙 -
Fail2Ban
防御性的动作库 监控系统的日志中的行为给相应的操作。可疑行为IP锁定…
搭建 node 生产环境
1、搭建 node 环境
- 更新系统
sudo apt-get update
- 一口气安装
sudo apt-get install vim openssl build-essential libssl-dev wget curl git
- 安装 nvm。 在git上搜索 nvm ,
install script
下有安装办法curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
或者wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
- 安装某版本的 node
nvm install v6.9.5
或者安装最新的nvm install node
- 安装一些全局工具包
npm i pm2 webpack gulp grunt-cli -g
..
2、借助 pm2 让服务器常驻
可以配置一个taobao镜像,直接 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 npm --registry=https://registry.npm.taobao.org install -g cnpm
- 安装 pm2
cnpm i pm2 -g
ornpm i pm2 -g
ornpm --registry=https://registry.npm.taobao.org install -g pm2
Nginx 反向代理
- Nginx 持有 80 端口,负责端口转发
- 更新
sudo apt-get update
- 安装 nginx
sudo apt-get install nginx
- 解析一个二级域名(A记录)出来
test.segmentfault.com
配置 nginx
cd /etc/nginx/conf.d
目录下新增一个配置文件sudo vi test-3000.conf
。检测配置sudo nginx -t
, 重启nginxsudo nginx -s reload
upstream test { server 127.0.0.1:3000; } server { listen 80; server_name test.segmentfault.com; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; proxy_set_header HOST $http_host; proxy_set_header X-Nginx-Proxy true; proxy_pass http://test; proxy_redirect off; } }
- 隐藏浏览器 Header 信息中 Nginx 的版本号。 配置
/etc/nginx
下的nginx.conf
,把Basic Setting
下server_token off
的注释拿掉。检测配置sudo nginx -t
, 重新加载配置sudo server nginx reload
静态网站部署
1、项目上传至 git 仓库
- 把本地和服务端的
id-rsa.pub
添加至 git - 本地安装 git ,创建并上传项目到 git
- 服务端安装 git
sudo apt-get install git
- 服务端测试一下 clone 项目
git clone git@github.com:DoFind/test.git
2、配置 pm2 一键部署项目
- 在本地项目下新增配置文件
ecosystem.json
并配置 - 在服务端新建发布项目的文件夹
/www/test
,粗暴给操作 test 的权限sudo chmod 777 test
vi .bashrc
注释一些代码source .bashrc
找到以下这几行代码注释掉:
# If not running interactively, don't do anything # case $- in # *i*);; # *)return;; # esac
- 接送一下项目(从 git 到 服务器)
pm2 deploy ecosystem.json production setup
- 之后的项目更新重启服务
pm2 deploy ecosystem.json production
// ecosystem.json 内容如下:
{
"apps": [
{
"name": "test",
"script": "app.js",
"env": {
"COMMON_VARIABLE": "true"
},
"env_production": {
"NODE_ENV": "production"
}
}
],
"deploy": {
"production": {
"user": "Jerry",
"host": ["公网IP"],
"port": "39999",
"ref": "origin/master",
"repo": "git@github.com:DoFind/test.git",
"path": "/www/test/production",
"ssh_options": "StrictHostKeyChecking=no",
"post-deploy": "npm install --registry=https://registry.npm.taobao.org && pm2 startOrRestart ecosystem.json --env production",
"env": {
"NODE_ENV": "production"
}
}
}
}
我自己遇到的一个问题,无法访问部署在
阿里云
上的站点:
ERR_CONNECTION_TIMED_OUT
。 网络诊断的结果是 服务器 不接受
80
端口上的连接解决:
ECS
实例的安全组规则中添加
HTTP(80)
,顺便把
HTTPS(443)
也加进来