阿里雲ECS服務器前後端項目部署

最近自己寫了一個小項目,想把它部署在服務器上以便實時查看,在此記錄一下自己的部署過程以及在部署過程中遇到的問題,方便日後查看。

參考:www.kovli.com/2017/09/19/…
作者:Kovli

一、購買雲服務器

目前國內佔有率比較高的就是騰訊雲阿里雲,這裏本人選擇的是阿里雲的ECS雲服務器。(吐槽一下,普通價格真的比學生價貴太多了) 如果在購買時沒有設置ssh密碼,可以進入ECS控制檯-示例列表-重置密碼中設置密碼。把IP地址中的公網IP記錄下來,後續會用到。

二、登錄服務器

選擇一款SSH工具登錄遠程服務器。常見的SSH工具有putty、xshell、xftp、SecureCRT等。這裏我選擇了putty,因爲它簡單易用,且不需要安裝。 下載好putty之後打開putty.exe,登錄界面如下: 在圖中所示Host Name的位置輸入之前記錄的公網IP,在Saved Sessions方框內輸入會話名,並點擊Save即可保存當前設置,以方便下次登錄。 點擊Open,進入命令行界面。在這之前,可能會有以下提示: 點擊“是”生成一個Key即可。
然後Putty即可連接到你的遠程服務器(一般Linux)。
輸入用戶名和密碼,即可遠程登錄。忘記密碼的可以到管理平臺中重置密碼。
驗證成功之後,即可進入以下界面: 接下來的操作就和在服務器本身上操作一樣了。


三、安裝Nodejs

Ubuntu中的包管理工具就是apt。

當使用Ubuntu軟件中心或者從終端命令輸入apt(或者apt-get)安裝軟件包時,軟件包被從一個或者多個軟件源下載下來。一個APT軟件源是一個網絡服務器或者一個本地目錄,它包含deb軟件包和可以被APT工具讀取的源文件。

1、首先更新Ubuntu軟件源

sudo apt-get update
sudo apt-get install -y python-software-properties software-properties-common
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
複製代碼

2、安裝Nodejs

sudo apt-get install nodejs
sudo apt install nodejs-legacy
sudo apt install npm
複製代碼

3、更新npm的包鏡像源

sudo npm config set registry https://registry.npm.taobao.org
複製代碼

4、全局安裝n管理器(用於管理nodejs版本)

sudo npm install n -g
複製代碼

5、安裝最新版n管理器

sudo n latest
複製代碼

6、提示設置PATH

PATH="$PATH"
複製代碼

最後執行node -v,發現Node和npm已經是最新版本了。

四、安裝Nginx

Nginx是一個高性能的HTTP服務器,佔有內存少,併發能力強,常用來做靜態頁面的服務器、反向代理、負載均衡等。

1、安裝Nginx

這裏我用的是apt安裝。

sudo apt-get install nginx
複製代碼

Ubuntn安裝之後文件結構大致爲:

  • 所有配置文件都在/etc/nginx下,並且每個虛擬主機已經安排在了/etc/nginx/sites-available下
  • 程序文件在/usr/sbin/nginx中(這裏是usr,Unix System Resource的縮寫而不是user
  • 日誌在/var/log/nginx中
  • 啓動腳本在/etc/init.d中
  • 默認的虛擬主機的目錄設置在了/var/www/nginx-default (有的版本 默認的虛擬主機的目錄設置在了/var/www, 請參考/etc/nginx/sites-available裏的配置)

然後啓動Nginx。 sudo /etc/init.d/nginx start 直接執行nginx也可以。

Nginx常用命令:

  • nginx:啓動Nginx

  • nginx -s reload:修改配置後重新加載生效

  • nginx -s stop:快速停止nginx

  • nginx -s quit:完整有序的停止nginx

到這裏會發現在瀏覽器中輸入阿里雲公網IP時沒有出現我們想要的Welcome to nginx,這是因爲阿里雲關閉的端口映射,需要手動開啓。

  1. 找到雲服務器ECS -> 網絡與安全 -> 安全組,點擊進入

  1. 點擊配置規則

  1. 點擊快速添加,然後在彈窗中勾選HTTP(80)(nginx默認監聽80端口),點擊確定

完成之後再次訪問你的公網IP就成功了!

2、Nginx配置

摘錄自菜鳥教程

########### 每個指令必須有分號結束。#################
#user administrator administrators;  #配置用戶或者組,默認爲nobody nobody。
#worker_processes 2;  #允許生成的進程數,默認爲1
#pid /nginx/pid/nginx.pid;   #指定nginx進程運行文件存放地址
error_log log/error.log debug;  #制定日誌路徑,級別。這個設置可以放入全局塊,http塊,server塊,級別以此爲:debug|info|notice|warn|error|crit|alert|emerg
events {
    accept_mutex on;   #設置網路連接序列化,防止驚羣現象發生,默認爲on
    multi_accept on;  #設置一個進程是否同時接受多個網絡連接,默認爲off
    #use epoll;      #事件驅動模型,select|poll|kqueue|epoll|resig|/dev/poll|eventport
    worker_connections  1024;    #最大連接數,默認爲512
}
http {
    include       mime.types;   #文件擴展名與文件類型映射表
    default_type  application/octet-stream; #默認文件類型,默認爲text/plain
    #access_log off; #取消服務日誌    
    log_format myFormat '$remote_addr–$remote_user [$time_local] $request $status $body_bytes_sent $http_referer $http_user_agent $http_x_forwarded_for'; #自定義格式
    access_log log/access.log myFormat;  #combined爲日誌格式的默認值
    sendfile on;   #允許sendfile方式傳輸文件,默認爲off,可以在http塊,server塊,location塊。
    sendfile_max_chunk 100k;  #每個進程每次調用傳輸數量不能大於設定的值,默認爲0,即不設上限。
    keepalive_timeout 65;  #連接超時時間,默認爲75s,可以在http,server,location塊。

    upstream mysvr {   
      server 127.0.0.1:7878;
      server 192.168.10.121:3333 backup;  #熱備
    }
    error_page 404 https://www.baidu.com; #錯誤頁
    server {
        keepalive_requests 120; #單連接請求上限次數。
        listen       4545;   #監聽端口
        server_name  127.0.0.1;   #監聽地址       
        location  ~*^.+$ {       #請求的url過濾,正則匹配,~爲區分大小寫,~*爲不區分大小寫。
           #root path;  #根目錄
           #index vv.txt;  #設置默認頁
           proxy_pass  http://mysvr;  #請求轉向mysvr 定義的服務器列表
           deny 127.0.0.1;  #拒絕的ip
           allow 172.18.5.54; #允許的ip           
        } 
    }
}
複製代碼

Nginx的默認配置在/etc/nginx/nginx.conf中。初始配置如下:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

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

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        include /etc/nginx/conf.d/*.conf;
        include /etc/nginx/sites-enabled/*;
}


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

複製代碼

配置文件中引入了下面兩個文件夾的內容,都是Nginx的默認配置。

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
複製代碼

因爲我的項目比較簡單,所以選擇註釋掉這兩行,把所有配置寫在一個文件裏。

關於編輯文件的操作可以參考vim(沒有安裝vim的需要自己安裝,或者使用vi)的操作。

在覆蓋默認配置的同學,我將root做了修改,指向了之後放置前端項目的目錄/home/mufeng-fromt,並在前端項目的目錄下新建了一個index.html用來測試。修改後配置如下:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
        worker_connections 768;
        # multi_accept on;
}

http {

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

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

        ##
        # SSL Settings
        ##

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
        ssl_prefer_server_ciphers on;

        ##
        # Logging Settings
        ##

        access_log /var/log/nginx/access.log;
        error_log /var/log/nginx/error.log;

        ##
        # Gzip Settings
        ##

        gzip on;
        gzip_disable "msie6";

        # gzip_vary on;
        # gzip_proxied any;
        # gzip_comp_level 6;
        # gzip_buffers 16 8k;
        # gzip_http_version 1.1;
        # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

        ##
        # Virtual Host Configs
        ##

        #include /etc/nginx/conf.d/*.conf;
        #include /etc/nginx/sites-enabled/*;
        server {
                listen 80 default_server;
                listen [::]:80 default_server;

                # SSL configuration
                #
                # listen 443 ssl default_server;
                # listen [::]:443 ssl default_server;
                #
                # Note: You should disable gzip for SSL traffic.
                # See: https://bugs.debian.org/773332
                #
                # Read up on ssl_ciphers to ensure a secure configuration.
                # See: https://bugs.debian.org/765782
                #
                # Self signed certs generated by the ssl-cert package
                # Don't use them in a production server!
                #
                # include snippets/snakeoil.conf;

                root /home/mufeng-front;

                # Add index.php to the list if you are using PHP
                index index.html index.htm index.nginx-debian.html;

                server_name _;

                location / {
                        # First attempt to serve request as file, then
                        # as directory, then fall back to displaying a 404.
                        try_files $uri $uri/ =404;
                }

                # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
                #
                #location ~ \.php$ {
                #       include snippets/fastcgi-php.conf;
                #
                #       # With php7.0-cgi alone:
                #       fastcgi_pass 127.0.0.1:9000;
                #       # With php7.0-fpm:
                #       fastcgi_pass unix:/run/php/php7.0-fpm.sock;
                #}

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


#mail {
#       # See sample authentication script at:
#       # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
#
#       # auth_http localhost/auth.php;
#       # pop3_capabilities "TOP" "USER";
#       # imap_capabilities "IMAP4rev1" "UIDPLUS";
#
#       server {
#               listen     localhost:110;
#               protocol   pop3;
#               proxy      on;
#       }
#
#       server {
#               listen     localhost:143;
#               protocol   imap;
#               proxy      on;
#       }
#}

複製代碼

重啓Nginx,刷新瀏覽器,設置成功!

五、部署前端項目

在服務器上部署前端項目,無非是首先獲取項目代碼,然後進行構建,然後將最後生成的dist目錄放到服務器的指定目錄中去。看了不少文章,綜合需求與實現成本,最後決定採用Github的Actions來實現前端項目的自動化部署。

此部分內容參考阮一峯老師的GitHub Actions 入門教程以及譚光志同學的前端項目自動化部署,對Github Actions不熟悉的也可以學習一下阮一峯老師的這篇文章。

1、創建一個靜態服務器

連接到遠程服務器之後,選擇合適的文件夾,我選擇的是/home目錄

mkdir Mufeng-Deploy // 創建文件夾
cd Mufeng-Deploy // 進入文件夾
npm init -y // 初始化項目
npm i express // 安裝express
touch front-deploy-server.js // 創建js文件
vim front-deploy-server.js // 編輯文件
複製代碼

front-deploy-server.js內容爲

const express = require('express')
const app = express()
const port = 300X // 填入自己的阿里雲映射端口,在網絡安全組配置。

app.use(express.static('dist')) // 使dist目錄下的靜態文件對外開放訪問

// 0.0.0.0表示所有的IP地址。比如一個tomcat配置文件中,如果監聽的IP地址設置了0.0.0.0就表示你的這個tomcat服務器監聽在本機的所有IP地址上,通過任何一個IP地址都可以訪問到。
app.listen(port, '0.0.0.0', () => {
    console.log(`front deploy`)
})
複製代碼

阿里雲映射端口配置可以參照之前安裝Nginx時添加80端口的步驟進行配置。

2、創建阿里雲祕鑰對

請參考創建SSH密鑰對綁定SSH密鑰對 ,將你的 ECS 服務器實例和密鑰綁定,然後將私鑰保存到你的電腦(例如保存在 ecs.pem 文件)。

注意:一定要按照阿里雲的文檔進行操作,妥善保管私鑰文件!!!

綁定完祕鑰之後,可以重新設置一下登錄密碼,重啓實例後生效。

3、阿里雲祕鑰綁定要部署的項目

打開要部署的Github項目,點擊setting->secrets。

點擊New repository secret按鈕,在Name中填入SERVER_SSH_KEY,用別的也可以,但是要與後面的SSH_PRIVATE_KEY: ${ { secrets.SERVER_SSH_KEY }}字段名保持統一。在Value中填入本地的阿里雲私鑰。

點擊Add secret完成。

4、在項目下創建.github/workflows/ci.yml文件

內容如下:

name: Build mufeng-front and deploy to aliyun
on:
  #監聽push操作
  push:
    branches:
      # master分支,你也可以改成其他分支
      - master
jobs:
  build:

    runs-on: ubuntu-16.04

    steps:
    - uses: actions/checkout@master
    - name: Install npm dependencies
      run: npm install
    - name: Run build task
      run: npm run build
    - name: Deploy to Server
      uses: easingthemes/ssh-deploy@master
      env:
          SSH_PRIVATE_KEY: ${
  
  { secrets.SERVER_SSH_KEY }}
          ARGS: '-rltgoDzvO --delete' # easingthemes/ssh-deploy使用的參數
          SOURCE: dist # 這是要複製到阿里雲靜態服務器的文件夾名稱,此例中指的是npm run build之後生成的dist目錄
          REMOTE_HOST: '47.99.111.167' # 你的阿里雲公網地址
          REMOTE_USER: root # 阿里雲登錄後默認爲 root 用戶
          TARGET: /home/mufeng-front # 打包後的 dist 文件夾將放在 /home/mufeng-front
複製代碼

有些地方需要根據自己的實際情況進行修改,可以參考官方文檔

完成之後推送到github上。

上面這個workflow文件的要點如下:

  1. 整個流程在master分支發生push事件時觸發。
  2. 只有一個job,運行在虛擬機環境ubuntu-16.04。
  3. 第一步是獲取源碼,使用的action是actions/checkout。
  4. 第二步是構建和部署,使用的action是easingthemes/ssh-deploy。
  5. 這一步需要幾個環境變量,根據你使用的action的不同也會發生改變,可以到具體的文檔中查看。

回到遠程服務器中執行node front-deploy-server.js,開始監聽,之後只要項目執行git push(將項目推送到master分支),就會自動執行ci.yml,將打包文件放到你的阿里雲靜態服務器上。

提交後,可以在項目的Actions中查看CI的歷史記錄。

之前Nginx中的這一行需要改一下:

root /home/mufeng-front;
改爲:
root /home/mufeng-front/dist;
複製代碼

改完之後重啓Nginx,大功告成!

六、安裝MySQL

要做一個完整的後端項目,數據庫肯定是必不可少的,我選擇的是MySQL。

1、安裝MySQL

sudo apt-get install mysql-server
sudo apt-get install mysql-client
sudo apt-get install libmysqlclient-dev // 找了好久也沒搞清楚這個包是做什麼的,乾脆就直接裝上了。
複製代碼

安裝過程中可能會提示設置root密碼,按提示來就好了。

安裝好之後,使用以下命令測試是否安裝成功: sudo netstat -tap | grep mysql

如果出現下圖所示就是安裝成功了。

2、登錄

mysql -uroot -proot對應的密碼
或者mysql -uroot -p 回車後再輸入密碼
複製代碼

3、設置MySQL允許遠程訪問。

  • 編輯mysql.conf文件

打開mysqld.cnf文件,我的路徑爲/etc/mysql/mysql.conf.d/mysqld.cnf 找到bind-address = 127.0.0.1這一行並把它註釋掉。保存退出。

  • 進入mysql服務,執行授權命令
grant all on *.* to root@'%' identified by '你的密碼' with grant option;
flush privileges;
複製代碼
  • 然後執行quit退出mysql服務,重啓mysql
sudo service mysql restart
複製代碼

現在在windows下可以使用Navicat遠程連接ubuntu下的mysql服務。 連接之前記得到阿里雲打開端口映射!

4、複製本地數據庫到遠程服務器

之前我本地已經新建了一個數據庫,所以我藉助Navicat的功能直接拷貝到遠程服務器。

  • 先連接本地數據庫、遠程數據庫

  • 在服務器創建一個和你要複製的本地數據庫名稱一樣的數據庫

  • 使用Navicat的數據轉移工具

點擊Tools -> Data Transfer,然後在彈窗中填入源數據庫和目標數據庫信息,點擊Next。

結束之後,刷新遠程數據庫,就可以看到本地的數據庫已經被拷貝到了遠程服務器!

七、部署後端項目

本着能用js解決就用js解決的原則,我後端項目選擇了Nodejs+Express,和之前部署前端Vue項目的步驟就很相似了。

1、遠程服務器添加監聽server

在之前部署前端項目時新建的項目中添加back-deploy-server.js文件。

cd Mufeng-Deploy // 進入文件夾
touch back-deploy-server.js // 創建js文件
vim back-deploy-server.js // 編輯文件
複製代碼

back-deploy-server.js內容爲

const express = require('express')
const app = express()
const port = 300X // 填入自己的阿里雲映射端口,在網絡安全組配置。這裏我使用了和前端項目不同的端口

// 0.0.0.0表示所有的IP地址。比如一個tomcat配置文件中,如果監聽的IP地址設置了0.0.0.0就表示你的這個tomcat服務器監聽在本機的所有IP地址上,通過任何一個IP地址都可以訪問到。
app.listen(port, '0.0.0.0', () => {
    console.log(`back deploy`)
})
複製代碼

沒有配置阿里雲映射端口配置的記得先配置。

2、創建阿里雲祕鑰對

使用之前的就可以。

3、阿里雲祕鑰綁定要部署的項目

與前端項目相同。

4、創建在項目下創建.github/workflows/ci.yml文件

內容如下:

name: Build mufeng-back and deploy to aliyun
on:
  #監聽push操作
  push:
    branches:
      # master分支,你也可以改成其他分支
      - master
jobs:
  build:

    runs-on: ubuntu-16.04

    steps:
    - uses: actions/checkout@master
    - name: Install npm dependencies
      run: npm install
    - name: Deploy to Server
      uses: easingthemes/ssh-deploy@master
      env:
          SSH_PRIVATE_KEY: ${
  
  { secrets.SERVER_SSH_KEY }}
          ARGS: '-rltgoDzvO --delete' # easingthemes/ssh-deploy使用的參數
          # SOURCE: dist # 這是要複製到阿里雲靜態服務器的文件夾名稱,後端不需要構建,直接把整個文件拷過去
          REMOTE_HOST: '47.99.111.167' # 你的阿里雲公網地址
          REMOTE_USER: root # 阿里雲登錄後默認爲 root 用戶,並且所在文件夾爲 root
          TARGET: /home/mufeng-back # 打包後的 dist 文件夾將放在 /home/mufeng-back
複製代碼

有些地方需要根據自己的實際情況進行修改,可以參考官方文檔

完成之後推送到github上。

上面這個workflow文件的要點如下:

  1. 整個流程在master分支發生push事件時觸發。
  2. 只有一個job,運行在虛擬機環境ubuntu-16.04。
  3. 第一步是獲取源碼,使用的action是actions/checkout。
  4. 這一步需要幾個環境變量,根據你使用的action的不同也會發生改變,可以到具體的文檔中查看。

回到遠程服務器中執行node back-deploy-server.js,開始監聽,之後只要項目執行git push(將項目推送到master分支),就會自動執行ci.yml,將打包文件放到你的阿里雲靜態服務器上。

提交後,可以在項目的Actions中查看CI的歷史記錄。

目前後端項目我還是到遠程服務器啓動的,後面看使用Webhooks能否實現後端項目的自啓動。

部署完後端項目之後先用Postman做了測試,之後根據項目需要修改了package的一些配置,這裏就沒有列舉了。

八、配置域名

如果以後想要公開這個項目的話,一直用IP地址訪問肯定是不方便的,可以配置一個域名方便訪問。

1、購買域名

可以到騰訊雲或者阿里雲上購買自己喜歡的域名

2、配置(以阿里云爲例)

登錄阿里雲,打開雲解析DNS -> 域名解析,這個模塊不太好找,可以直接搜索。

點擊自己的域名或者解析設置,進入解析設置頁。

這裏有兩種配置方式:

  • 點擊添加記錄,自己進行配置

  • 點擊新手引導,只需要輸入IP地址即可完成配置,其他配置項默認。

我才用的是新手引導的方式:

配置完之後可能需要5-10分鐘才能生效。

.com/.net/.cn/.xin/.top/.xyz/.vip/.club/.shop/.wang/.ren等域名註冊成功後必須進行域名實名認證,否則會造成解析不生效,實名認證審覈通過後的1-2個工作日解析可恢復使用。

What's the fuck!!!再次訪問突然顯示這個!!!

根據阿里雲的提示做了備案,吐槽一下,審覈的整個流程很麻煩,而且需要的信息真的是把你扒的乾乾淨淨,心裏一萬個***,目前我的域名還在審覈中...


作者:木風同學
鏈接:https://juejin.cn/post/6908323868360835085
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章