阿里雲伺服器部署 nodejs + mongodb + nginx 反向代理 + https配置 ssl證書

大桔子發表於2019-01-19

感謝 Scott 老師,Scott老師的慕課網教程 https://coding.imooc.com/clas…

1. 購買阿里雲伺服器及域名

2. 終端連線阿里雲伺服器(mac環境)

  1. ssh root@39...* 輸入密碼(購買時的密碼)

    • 如果出現這個問題的解決方案:root@39.106.220*.*: Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
    • 解決方法: https://blog.csdn.net/gigijin…
  2. 檢視硬碟掛在情況:fdisk -l (如果有資料盤的情況下)
  3. 檢視硬碟使用情況 df -h
  4. 通過zsh設定快捷登入 alias ssh_orange="ssh root@39.106.22*.*"
  5. root 許可權,可以增加幾個擁有root許可權的使用者

    • https://www.cnblogs.com/wang3…
    • adduser [name]
    • Linux下 ssh 檢視使用者列表
    • 複雜:cat /etc/passwd
    • 簡化:cat /etc/passwd|grep -v nologin|grep -v halt|grep -v shutdown|awk -F":" `{ print $1"|"$3"|"$4 }`|more
    • 刪除使用者: userdel orange001 直接刪除就好
    • 給新使用者 orange01 設定密碼 passwd orange01 根據提示填寫兩次密碼
    • 給新使用者升級許可權 gpasswd -a orange001 sudo
    • (centos 環境)

      配置使用者許可權:
      修改 /etc/sudoers 檔案,找到下面一行,在root下面新增一行,如下所示:
      ## Allow root to run any commands anywhere
      root    ALL=(ALL)     ALL
      orange01   ALL=(ALL)     ALL
      修改完畢,現在可以用 orange01 帳號登入,然後用命令 su -  ,即可獲得root許可權進行操作。
              :wq!  儲存退出
  6. 重啟ssh 烏班圖上 srevice ssh restart centos7 命令:systemctl restart sshd.serviceservice sshd restart
  7. ssh 實現無密碼登入

     本地操作:
     本地生成 ssh key: ssh-keygen -t rsa -b 4096 -C "326242499.@qq.com"  同 git 操作一樣
     開啟 ssh 代理   eval "$(ssh-agent -s)"
     把ssh key 假如到代理中     ssh-add ~/.ssh/id_rsa  (在 .ssh 目錄下執行這一操作)
     
     遠端主機操作:
     再把上面本地操作的步驟重複一遍
    
     然後生成 authorized_keys 檔案:         
     vi .ssh/authorized_keys
     然後將本地的公鑰的內容 (~/.ssh/id_rsa.pub)  拷貝到遠端主機的 authorized_keys 檔案內
     
     授權 chmod 600 authorized_keys 
     重啟遠端主機 
     sudo service ssh restart(烏班圖) 
     systemctl restart sshd.service 或  service sshd restart (centos7)
    
     做完這些步驟就可以ssh免密登入遠端主機了
  8. 埠安全性

    • ssh 預設登入埠 22
    • 在 root 賬戶下修改預設登入埠號
    • centos7 修改預設22埠 https://www.cnblogs.com/zhuzi8849/p/6254498.html
    • 不知道為什麼我修改完之後 ssh -p 3600 root@39.**.**.* 登入連線超時 (未設定成功)
  9. 配置安全項、防火牆(iptables) — 未做

3. 搭建nodejs環境

  1. 更新:sudo yum update 或者 sudo yum upgrade (這個會報錯)
  2. 安裝: sudo yum install vim openssl build-essential libssl-dev wget curl git
  3. 安裝:nvm wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
  4. 安裝完之後 nvm –version 檢查下是否安裝成功 安裝 node: nvm install v8.11.3

    • 好像下面兩步都不用做了 ,自動做好了
    • nvm use v8.10.0 nvm 指定使用的 node 的版本
    • nvm alias default v8.10.0 設定 node 預設使用版本
  5. 設定淘寶映象 npm --registry=https://registry.npm.taobao.org install -g npm

    • 配置 cnpm npm --registry=https://registry.npm.taobao.org install -g cnpm
    • cnpm sync koa 同步 npm 上的模組
  6. 增加系統檔案監控數目 echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p (不知道是做什麼)
  7. 全域性安裝 pm2 npm install -g pm2
  8. 開啟一個靜態站點

    • pm2 是一個 node.js 部署和程式管理工具,通過它可以實現 node.js 後臺執行(不是向上邊那樣關閉命令列服務就沒了)和出錯自動重啟
    • pm2 運維 node 服務本身
    • 執行 pm2 start app.js 即可執行 node 服務
    • pm2 list 列出當前執行的 pm2-node 服務
    • pm2 show [App name|id] 檢視詳細資訊
    • pm2 log app 檢視實時日誌
    • 退出 log ctrl + c
    • 出現的問題: 無法使用 80 埠以外的埠開啟服務(會不會centos預設只對外暴露 80 埠)

4. nginx 實現反向代理

通過對80埠的監聽,將80埠的流量轉發到其他埠
讓web通過 80 埠被外網訪問
只有 root 許可權的使用者才能使用 80 埠
伺服器有多個網站 可以通過 nginx 代理 80埠,轉發給 特定的埠,實現負載均衡

  1. 刪除自帶的 阿帕奇服務,我的阿里雲輕量伺服器上好像並沒有找到 httpd
  2. 安裝 nginx下載好就行,不要再往下進行
  3. 進入 /etc/nginx/conf.d 目錄下,然後建立配置檔案
  4. 配置檔案:一個服務一個配置檔案microblog-yao-3002.conf 命名規則:域名 + 埠

    # 考慮負載均衡策略
        upstream microblog {
            server 127.0.0.1:3002; // 本地node服務
        }
    
        server {
            listen 80;
            server_name code-sky.cn; // 域名
    
            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://microblog; // 把域名代理到應用上
                proxy_redirect off;
            }
        }
    
        檢查 nginx/nginx.conf 配置檔案 去掉 include 註釋 
        include /etc/nginx/conf.d/*.conf;  這句在 nginx.conf 必須要在 http 裡面 server 外面
        sudo nginx -t 檢查 nginx 配置檔案是否正確
        nginx 重啟  sudo nginx -s reload
        隱藏 nginx 版本  nginx.conf   http  設定  server_tokens off;
  5. nginx 對 css,js 靜態資源的處理(可讓瀏覽器快取靜態資源)

    # 在單獨應用的nginx配置裡,放在server裡面同 location同級
    # 對靜態資源的處理
    location ~* ^.+.(jpg|jpeg|gif|png|ico|css|js|pdf|txt) {
        root /www/blog/production/current/admin/dist/;
    }
    
    # 開啟gizp壓縮
    # new config lines for gzip
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 8k;
    gzip_http_version 1.1;
    gzip_types text/plain application/javascript application/x-javascript text/javascript text/css;
  6. nginx 轉發配置(用 80埠代理,然後分發到不同的服務上)學習連線

5. 域名備案與DNS解析

  • 一個域名只能指向一個 ip 地址,一個 ip地址可以被多個域名指向
  • 域名記錄:A記錄 將一個域名指向到一個伺服器的 ip地址
  • CNAME 將一個域名指向另一個域名
  • 解析域名:阿里雲域名控制檯-雲解析DNS-新增記錄 根據提示設定域名及二級域名

6. 安裝 mongoDB 資料庫

在伺服器上搭建 MongoDB資料庫(一般情況下,資料應該與應用分開,自己學習就無所謂了)

homebrew 本地安裝 MongoDB資料庫

  • 安裝 homebrew
  • brew 安裝本地mongoDB資料庫 brew install mongodb brew安裝MongoDB
  • 啟動mongodb服務:終端執行: brew services start mongodb
  • 使用brew 預設下載地址為 /usr/local/Cellar/ 下的 mongodb資料夾。

To have launchd start mongodb now and restart at login:
brew services start mongodb
Or, if you don`t want/need a background service you can just run:
mongod –config /usr/local/etc/mongod.conf

伺服器安裝 MongoDB資料庫(centos環境)

  1. 安裝mongodb-1
  2. 安裝mongodb-2
  3. mongoDB操作

    啟動報錯處理       mongod -repair
    
    啟動mongodb 
    systemctl start mongod.service  or  
    service mongod start
    
    重啟mongodb     
    systemctl restart mongod.service   or     
    service mongod restart
    
    停止mongodb     
    systemctl stop mongod.service       or      
    service mongod stop
    
    檢視mongodb狀態 systemctl status mongod.service
    
    登入         mongo
    檢視資料庫    show dbs
  4. 修改 mongodb 預設連線埠號

    sudo vi /etc/mongod.conf
    # port: 27017
    # 將埠號修改為 19999
    port: 19999
    bindIp: 127.0.0.1  # Listen to local interface only, comment to listen on all interfaces.
    修改完埠   重啟mongodb  sudo service mongod  restart
    
    指定埠連線  指定埠連線 mongodb  mongo --port 19999
    注意:如果設定了防火牆,要將防火牆更新
備份本地MongoDB資料庫
  • mongodump -h 127.0.0.1:27017 -d test2 -o microblog
  • test2 資料庫名稱 microblog 備份資料夾名稱
將備份檔案scp上傳至伺服器
  • 打包 tar zcvf microblog.tar.gz microblog
  • 前面:打包後的檔名稱 後面:打包前的資料夾
  • 上傳 scp -p 80 ./microblog.tar.gz root@39.106.220.6:/root/dbmicroblog
  • -p 伺服器埠 本地tar包位置 伺服器地址 伺服器存放 tar 包的位置
  • 對伺服器上的 tar 包進行解壓縮 tar -xzvf microblog.tar.gz
  • tar 命令:
    壓縮檔案:tar -czvf test.tar.gz a.c    // 壓縮 a.c 檔案為 test.tar.gz
    解壓檔案:tar -xzvf test.tar.gz a.c    // 解壓 test.tar.gz 為 a.c
  • 將這個 test2 資料庫匯入到線上剛剛配置完埠的資料庫
  • mongorestore --host 127.0.0.1:19999 -d test2 ./test2
  • 前面test2 線上資料庫的名稱
  • 後面 ./ test2 線上備份資料庫儲存的位置

  • 檢視是否匯入成功

    mongo --port 19999
    show dbs    檢視資料庫
    use test2    進入test2資料庫
    show tables 檢視test2資料庫中的表
    db.user.find({})    檢視錶中的資料 
  • 匯入到線上已有的資料庫,匯入一張或多張單表

    本地匯出單表
    mongoexport -d immoc-movie -c users -q `{"name": {$ne: null}}` -o ./movie-users.json
    
    -d immoc-movie   資料庫名稱
    -c users 要匯出的表
    -q 可選  查詢條件
    -o 匯出檔案在本地存放的位置
    
    將該單表 scp 上傳到伺服器
    
    將該單表匯入到 線上資料庫 
    mongoimport --host 127.0.0.1:19999 -d immoc-movie -c users ./movie-users.json
    
    建議匯入初始化資料時在配置資料庫許可權之前,不然輸入的命令會麻煩很多,輸入各種命令
    
    刪掉資料庫 mongo --host 127.0.0.1:19999 immoc-movie --eval "db.dropDatabase()"
  • mongod 開啟mongoDB 服務
  • mongo 開啟 mongoDB客戶端
  • brew services start mongodb
為資料庫配置許可權
為資料庫設定使用者許可權
設定  新增mongoDB管理員

use admin 
db.createUser({user: `orange`, pwd: `yao1024`, roles: [{role: `userAdminAnyDatabase`, db: `admin`}]})

每次對不同資料庫建立管理員都需要到 admin 去認證
對使用者進行登入授權
use admin
db.auth(`orange`, `yao1024`)

切換到 test2
use test2

建立讀寫許可權使用者
db.createUser({user: `microblog`, pwd: `microblog`, roles: [{role: `readWrite`, db: `test2`}]})

建立備份角色
db.createUser({user: `wheel`, pwd: `wheel`, roles: [{role: `read`, db: `test2`}]})
 

修改配置檔案開啟mongoDB驗證模式
sudo vi /etc/mongod.conf

# security:  將 #去掉
authorization: `enable`  (兩個空格)

重啟 mongoDB 讓配置生效
sudo service mongod restart

重新登入 mongo --port 19999
show dbs  就會報錯

use admin
db.auth(`orange`, `yao1024`) 

直接登入某個資料庫
mongo 127.0.0.1:19999/test2 -u microblog -p microblog
資料庫名  使用者名稱  密碼
向線上執行的資料庫匯入資料表
遷移資料庫、遷移資料庫的一張單表

先將 庫或單表匯出到伺服器的某個目錄裡,然後 tar 打包
用 scp -P 80 root@xx.xx.xx:/root/db/microblog.tar.gz
然後再把這個包上傳到另一臺伺服器上

線上生產資料庫定時備份(上傳到雲平臺)

7. 程式碼部署

  • pm2,git倉庫 自動部署專案
  • 建立一個新專案第一次時: pm2 deploy ecosystem.json production setup
  • 接下來部署程式碼部署程式碼 pm2 deploy ecosystem.json production
  • pm2文件

    1. 伺服器安裝 git,(和本地安裝git一樣,配置 rsa_pub 等檔案,可以實現免密)
    2. 原生程式碼上傳到程式碼倉庫
    3. 伺服器拉取程式碼倉庫程式碼
    
    4. 在專案根目錄建立 pm2 自動部署檔案  ecosystem.json,編輯部署檔案內容
    
    5. 在伺服器根目錄上新建 /www   目錄,與 pm2 配置檔案對映起來
    
    6. 在本地執行  pm2 deploy ecosystem.json production setup  即可成功部署
    
    7.  可能部署失敗的原因:賬號許可權不夠,伺服器 www 檔案不存在  部署的 user 使用者必須要有建立資料夾的許可權
        原理:通過本地 pm2 登入遠端伺服器,通知遠端伺服器從程式碼倉庫拉取程式碼到部署目錄
    
    8. pm2 在伺服器上使用的是 非互動 ssh 連線方式,需要註釋 .bashec 檔案內容  (我的centos 沒找到那兩句,所以什麼也沒做)
    
    9. 將 程式碼倉庫更新,確保 ecosystem.json 存在於 /www/production/current 目錄裡
    
    10. 執行 pm2 deploy ecosystem.json production   部署成功,即釋出成功
    
    11. 修改 nginx 配置檔案  建立3000埠的 conf      
        問題:如何開啟兩個埠共存,防火牆允許3000埠訪問,還是申請個域名吧
    
    12. 程式碼更新 pm2 deploy 的 HEAD 指向不了最新的提交,還是指向上次的提交
        解決方法:需要在 pm2 配置檔案中多加一行配置
        "post-deploy": "git pull && npm install && pm2 startOrRestart ecosystem.json --env production",
    
    13. 如果資料庫設定了使用者許可權:程式碼裡連線資料庫要以
    
    14.  如果沒有域名,怎麼在 nginx 配置對映二級域名,有 二級 ip地址之說嗎? 不要搞了,還是備案域名吧

    8. 配置HTTPS 協議

    • 騰訊雲申請免費 SSL 證照(亞洲誠信DV SSL證照)
    • SSL證照管理頁面 -> 申請證照 -> 填入資訊 -> 手動DNS 驗證 -> 驗證成功之後會得到一條記錄包括(主機記錄 記錄型別(CNAME) 記錄值)-> 在阿里雲域名管理後臺新新增一條記錄(將剛才得到驗證記錄填寫進去)-> 填寫生效後,證照就頒發好了 參考連結
    • 將下載好的 SSL 證照上(Nginx目錄下)傳到 伺服器上 scp -p 80 ./admin.code-sky.cn/Nginx/2_admin.code-sky.cn.key root@39.106.220.6:/root scp -p 80 ./admin.code-sky.cn/Nginx/1_admin.code-sky.cn_bundle.crt root@39.106.220.6:/root
    • 將上傳好的檔案放到 一個名為 ssl 的資料夾,然後將 ssl 資料夾移動到 /www 目錄下
    • 修改 nginx 配置檔案

          upstream admin {
              server 127.0.0.1:3003;
          }
      
          server {
              listen 80;
              server_name admin.code-sky.cn;
              # rewrite ^(.*) https://$host$1 permanent;
              return 301 https://admin.code-sky.cn$request_uri;
          }
      
          server {
              listen 443;
              server_name admin.code-sky.cn; #填寫繫結證照的域名
              ssl on;
              ssl_certificate /www/ssl/1_admin.code-sky.cn_bundle.crt;
              ssl_certificate_key /www/ssl/2_admin.code-sky.cn.key;
              ssl_session_timeout 5m;
              ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照這個協議配置
              ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照這個套件配置
              ssl_prefer_server_ciphers on;
      
              if ($ssl_protocol = "") {
              rewrite ^(.*) https://$host$1 permanent;
              }
      
              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://admin;
                  proxy_redirect off;
              }
              location ~* ^.+.(jpg|jpeg|gif|png|ico|css|js|pdf|txt) {
                  root /www/blog/production/current/admin/dist/;
              }
      
              # new config lines for gzip
              gzip on;
              gzip_min_length 1k;
              gzip_buffers 4 8k;
              gzip_http_version 1.1;
              gzip_types text/plain application/javascript application/x-javascript text/javascript text/css;
          }
    • 檢查 nginx 檔案配置是否正確 sudo nginx -t
    • 重啟nginx sudo nginx -s reload 即完成 https 配置

相關文章