前段時間在公司部署專案的時候,運維同學說了一堆關於伺服器的東西,頓時感覺不知所云,雲裡霧裡。。。
索性拿這個專案練習一下,簡單瞭解專案部署到伺服器的這個流程是怎麼處理的
預備知識
pm2
pm2 是啟動node程式管理工具
常用命令
···
pm2 start app.js : 啟動服務,入口檔案是app.js
pm2 list 檢視有哪些程式啟動
pm2 show xxx 檢視某一個服務的詳情
npm restart [name or id] : 重啟服務
pm2 monit : 對服務進行監控
···
一個專案的package.json 檔案
平時啟動服務我們可以使用 node run app.js
如果藉助pm2 來啟動服務 就可以輸入 pm2 start app.js
在命令列輸入 pm2 list 可以檢視正在執行的專案
pm2支援配置檔案啟動
- script 啟動指令碼路徑
- exec_mode 應用啟動模式,支援fork和cluster模式
- instances 應用啟動例項個數,僅在cluster模式有效,預設為fork
fork和cluster模式
fork為單程式 cluster可以啟動多個程式
在專案中新增一個pm2配置檔案 pm2.config.json
{
"name": "mxx-project",
"script": "./index.js",
"error_file": "./logs/err.log",
"out_file": "./logs/out.log",
"log_date_format": "YYYY-MM-DD HH:mm Z",
"instances": 3,
"merge_logs": true,
"exec_mode": "cluster",
"node_args": "",
"ignore_watch": ["node_modules"],
"env": {
"NODE_ENV": "development"
}
}
複製程式碼
在命令列輸入
pm2 start pm2.config.json
複製程式碼
則會有三個程式被建立
注: 如果你的伺服器是多核的 那麼很有可能在cluster 模式下 被建立多個程式
可以檢視一下自己的伺服器是幾核的
shipit
shipit 是自動化的伺服器部署工具
一個簡單的shipit配置檔案
module.exports = shipit => {
require('shipit-deploy')(shipit)
shipit.initConfig({
default: {
workspace: '/tmp/myapp',
deployTo: '/var/myapp',
repositoryUrl: '你的GitHub地址',
ignores: ['.git', 'node_modules'],
keepReleases: 2,
deleteOnRollback: false,
key: '/path/to/key',
shallowClone: true,
},
staging: {
servers: '你的伺服器地址',
},
})
}
複製程式碼
連線伺服器
購買伺服器之後 得到IP地址 可以嘗試登陸伺服器
一般自己的伺服器可以使用root身份登陸操作
ssh root@ipipip
複製程式碼
由於後面專案要部署到伺服器中 建議可以先做ssh-copy-id 建立信任 這樣就不用重複輸入密碼了
在伺服器上配置環境
一般來說 需要安裝 npm cnpm node pm2 git nginx
- 安裝npm
yum install npm
複製程式碼
- 安裝 cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org
複製程式碼
- 安裝pm2
npm i pm2
複製程式碼
- 安裝node
npm i n
複製程式碼
- 安裝git
yum install git
複製程式碼
- 安裝nvm
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
複製程式碼
需要調整 vim ~/.bashrc
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
複製程式碼
指定預設node版本
nvm alias defalut 8
複製程式碼
啟動一個簡易服務
我們來寫一個簡單的指令碼 在伺服器上, 我這裡是在 /home/work 目錄下新建了一個app.js (依次執行)
cd home
mkdir work
touch app.js
複製程式碼
在app.js中 寫一個最簡單的服務
const http = require('http')
const port = 3389
http.createServer((req, res) => {
res.end('Hello word!')
}).listen(port, () => {
console.log(port, 'port')
})
複製程式碼
啟動app.js
node app.js
複製程式碼
然後開啟瀏覽器,輸入IP+埠號,就能在頁面中看到hello word了
--補充--
1 這裡使用的埠號是 3389 是因為我的伺服器中 安全組中已經配置了 3389 這個埠號
如果你使用的是其餘埠 要注意去檢視有沒有配置安全組
2 關於啟動服務
如果使用的是node 那麼一旦退出伺服器,則無法再訪問此服務
可以換成使用pm2 來啟動 這樣一旦啟動 除非報錯,將會一直有此程式存在
準備部署
- 準備專案
專案是用koa1 + React
react的專案地址 點我檢視GitHub地址
啟動的埠號調整到3389
- 準備pm2啟動檔案
建立pm2資料夾 在其中寫一個 production.json 用於啟動pm2
- 在專案中建立一個 shipit.js 基本配置如下
module.exports = function (shipit) {
require('shipit-deploy')(shipit)
require('shipit-cnpm')(shipit)
require('shipit-pm')(shipit)
shipit.initConfig({
default: {
workspace: '/tmp/deploy/your-project',
deployTo: '/home/work/your-project',
repositoryUrl: 'https://github.com/youproject.git',
ignores: ['.git', 'node_modules'],
keepReleases: 2,
deleteOnRollback: false,
key: '/path/to/key',
shallowClone: true,
cnpm: {
flags: '--production',
local: false,
npm: 'cnpm',
remote: true
},
pm: {
production: {
path: '/home/work/your-project/current/pm2/production.json'
}
}
},
production: {
servers: ['root@你的IP地址']
}
})
}
複製程式碼
這裡 pm2 使用的配置檔案來啟動 所以配置了 pm 引數 會根據這個檔案路徑來啟動pm2
- 在專案的package.json中 新增兩個欄位
"deploy": "shipit production deploy",
"rollback": "shipit production rollback",
複製程式碼
- 將專案push到GitHub中
- 執行 npm run deploy
專案部署完畢後,去伺服器檢視下專案程式
pm2 list
複製程式碼
開啟頁面 看下效果
到目前為止,算是部署完畢了
部署過程出現的問題
- 報錯1
解決: 伺服器上忘記安裝git了
- 報錯2
這個就很明顯了,沒有安裝 cnpm
- 部署成功之後去伺服器檢視 專案並沒有啟動
原來部署完畢是
然後求助一位大神,發現是shipit配置檔案中 沒寫
require('shipit-pm')(shipit)
複製程式碼
[摔桌子!]
調整檔案後重新上線
會啟動三個程式
根據專案埠號配置阿里雲
如果你的專案啟動時候埠號並沒有在安全組中配置,需要在後臺中新增安全組
在訪問頁面的時候 還需要輸入埠號 3389。非常懶,不想輸入埠號
在安全組中新增預設埠80,將啟動檔案app.js中埠調整為80。這樣就不需要輸入埠號了
那如果不想修改app.js檔案怎麼辦,使用NGINX
配置NGINX
- 安裝 nginx
yum install nginx
檢視NGINX配置檔案
cat /etc/nginx/nginx.conf
複製程式碼
很簡單的配置
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
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 /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
複製程式碼
將專案入口檔案app.js中埠號調整為 9999
處理Nginx.conf.js
最後調整為 (比較重要的是server 這裡只展示server部分)
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://127.0.0.1:9999/;
}
}
複製程式碼
啟動Nginx
nginx -s reload
複製程式碼
Nginx配置出現的問題
- 重啟Nginx
在重啟Nginx的時候 一直報錯
查閱文章後處理
nginx -c /etc/nginx/nginx.conf
nginx -s reload
複製程式碼
搞定~
歡迎訪問 點我檢視專案