Deployment and Setup CI

摘要

整個流程分成兩個階段:

  1. Deploy: 手動將 GitHub 專案部署到 AWS 伺服器
  2. CI Setup: 設定 Jenkins ,讓 Jenkin 偵測得到我們每次的 push ,並在 push 時自動將專案部署到伺服器上

Deploy

註冊虛擬主機

在這裡使用 AWS EC2 服務, EC2 服務是 AWS 提供的虛擬主機,使用者可以進行遠端存取並安裝、執行程式。
流程大致如下:

Launch Instance

在虛擬機器中開啟一個執行的個體。

設定 Instance 的環境

例如 Linux 、 Windows …

利用本機連結 Instance

在 AWS 上設定好一台虛擬主機後,這步是從本機端取得該主機的操作權限。
為此會需要建立 AWS 提供的金鑰對。

AWS 的金鑰對

私鑰放在我們本機,公鑰放在我們建立的 AWS 的虛擬主機, 當我們利用本機要求對 AWS 虛擬主機做遠端操作時, AWS 會確認我們私鑰是否吻合,才會提供存取權限。

通常我們會把私鑰下載下來(是個 pem 檔),然後存到 ~/.ssh 這個路徑。

最好設定私鑰的讀取權限為 400 ,避免被隨意更動。

1
2
$ chmod 400 ~/.ssh/<private key file>.pem # 設定私鑰存取權限
ls -al # 檢查存取權限是否有設定成功

Public IP

虛擬機器開始執行後,我們可以拿到連到該虛擬機器的 Public IP
想從本地端用 SSH 連進虛擬機器,輸入:

1
2
3
4
$ ssh -i ~/.ssh/<private key file>.pem <user name>@<EC2 IP address>
# <private key file>.pem 就是私鑰檔案
# <user name> 系統默認 ec2-user 或 root 兩種
# <EC2 IP address> 為虛擬主機的 IP

有連進去代表已經可以順利使用了。

終止不需要的 EC

終止 EC2 就可以避免無形中被扣款。
在 EC2 Instance Console 選擇 ACTION -> Terminate 就好

在虛擬主機中安裝伺服器

視不同的主機環境會有不同預裝的自動安裝工具可以執行,若是 Linux 會提供 YUM(Yellowdog Updater Modified)。

1
2
3
4
5
6
7
8
9
10
11
12
13
# 因為這裡用 ec2-user 登入的關係,很多指令都要 sudo 才能執行
# 直接用 root 就沒有這種困擾

# 先 update 一輪
$ sudo yum update -y
# 再安裝 Apache 伺服器
$ sudo yum install -y httpd24
# 讓伺服器跑起來
$ sudo service httpd start
# 設定運行級別(定義系統在哪些運行條件下會開啟此服務)
$ sudo chkconfig httpd on
# 確認目前服務的運行級別
$ chkconfig --list httpd

各個運行級別的定義如下:(一般會讓伺服器的 235 ON)

0 Halt
1 Single-User mode
2 Multi-user mode console logins only (without networking)
3 Multi-User mode, console logins only
4 Not used/User-definable
5 Multi-User mode, with display manager as well as console logins (X11)
6 Reboot

開 Port

AWS 對連接口要求設置 Security Rule 才會讓我們開啟,預設被打開的只有 SSH 這條通道,若要讓別人能夠透過瀏覽器連到我們伺服器,必須自己設定一個 PORT 。

要到 AWS Console 去設置。
Instance -> Security Groups -> view Inbound rules 會顯示目前該主機已設置 rule 的通道。

左列目錄 Security Groups -> Instance -> Inbound -> Edit -> Add Rules 輸入:

  • Type: HTTP
  • Protocol: TCP
  • Port Range: 80
  • Source: Custom

儲存後,就可以使用瀏覽器連入。

手動將 Github 專案部署到伺服器

其實大概流程就是:

  1. 從本機端 push 專案到 Github
  2. 用本機 SSH 存取 AWS 主機
  3. 從主機把 Github 上的專案 pull 到伺服器根目錄

前兩個大家都知道,但第三項要先做一些設定。

在伺服器安裝 Git

利用 yum

1
$ sudo yum install git

移動到伺服器根目錄

Apache 伺服器網站根目錄一般位於 /var/www/html/ 下。

1
$ cd /var/www/html

對根目錄做 Git 初始化

1
$ git init

設定 AWS 主機的 SSH

這是為了讓 Github 可以透過 SSH 和遠端主機連線,因為目前這個遠端主機只有兩個接口,一個是預設的 SSH port,一個是剛剛我們開啟的 Port 80。

先產生一把鑰匙:

1
$ ssh-keygen

透過該指令產生的 SSH 鑰匙對會放在家目錄下的資料夾 .ssh 中。移動過去:

1
2
$ cd ~/.ssh
$ ls # 應該會看到這些 authorized_keys id_rsa id_rsa.pub

裡面裝著 id_rsa 就是私鑰、 id_rsa.pub 就是公鑰。

1
$ cat id_rsa.pub # 顯示公鑰內容

在 Github 專案設置 Deploy Key

Deploy Key 讓握有 SSH Key 的系統可以讀到專案的內容,(預設不能更改,但這可以自己設定)。如此一來, 我們部署在 AWS 主機的伺服器就有權限以 SSH 連接的方式 pull 該內容。

進入 Github 專案 -> Deploy Key -> Add deploy key -> 貼上剛剛取得的公鑰 -> Add key

設置 remote

回 AWS 根目錄設定好 remote 就可以 pull 了。

1
2
3
$ cd /var/www/html
$ git remote add <remote name> <remote repo url>
$ git pull <remote branch> <branch>

CI Setup

CI 是為了解決一次執行大量整合時,解衝突解到崩潰所出現的方案。為了避免一次性的大量整合,因此將整合拆解成無數的小整合;但是管理無數的小整合又會衍生其他麻煩,因此有了自動化的 CI 。 CI 除了自動整合外,還可以在每次整合上附加測試。

這份筆記只包含設定 CI 環境到可以成功執行。這裡使用 Jenkins 做為 CI 工具。

安裝 Jenkins

按照官網說明找個地方安裝。

使用 Jenkins

設定使用者

要讓 Jenkins 代替我們與 AWS 主機互動,我們也得給予它 AWS 私鑰。
在 Manage Jenkins -> Configuration -> Publish over SSH -> SSH Servers 可以設定:

Name: 自由取名
Hostname: AWS 主機的 IP
Username: root / ec2-user

接著進入「進階」選項:

key: AWS 私鑰
就可以儲存了。

新增作業

點選 New Item

name: 自由取名
點選 Freestyle project
建立完成

接著設定該作業
在進入該作業後,點選左列的 Configurations 可以設定作業的內容。
為了測試 Jenkins 是否如我們設定,擁有存取 AWS 主機的權限,我們可以先設定一個簡單的建置任務:

Build -> Send files or execute commands over SSH

SSH Publishers: 選擇剛剛建好的 SSH Server
Transfers -> Exec Command:

1
2
3
4
# 在這裡輸入的指令, Jenkins 會在建置時代替我們用 AWS 主機執行
# 輸入以下指令
cd /var/www/html
sudo touch hello.txt

點選 Add Transfer Set 。

上述動作會讓 Jenkins 在發動建置時,在伺服器根目錄新增一個 hello.txt 的檔案。

點選專案右列的 Build Now 會馬上啟動建置。 Jenkins 會在左邊顯示建置進度。等完成後,開啟 AWS 伺服器確認是否多了一個 hello.txt 檔案就能夠確定建置是否成功。

連接 Jenkins 和 GitHub

我們利用的是 GitHub 提供的 Webhooks ,Webhooks 可以讓 Github 在觸發某些事件(例如 push)時,以 POST 請求的方式傳送資訊到第三方的 URL(這裡為 Jenkins API)。

因此,我們可以設定 Webhooks 在每次 push 時傳送資訊給 Jenkins ,在透過 Jenkins 設定接收到這些資訊時,操控 AWS 主機從 Git 把專案 pull 下來,就可以達到自動 deploy。

在設定作業的 Build Triggers:
勾選 Remote
下面會冒出 Access Token 選項,並且會提供一串 URL ,該 URL 就是 Jenkins 提供的 API ,只要 GitHub 的Webhooks 連接到該 API ,若比對 token 一致,就會觸發 Jenkins 的建置程序。
這裡可以自行輸入 token 。

設定 Webhooks:
連到 GitHub 的專案 Repository -> Settings -> Webhooks -> Add Webhooks

Payload URL: <Jenkins所在的URL>/job/<作業名稱>/build?token=<token名稱>
Content type: 預設
Which events would you like to trigger this webhook?: Just the push event
Active: 勾選

Add 完畢後,從本機端發動 push ,並查看伺服器網頁是否自動同步,若有就是成功了!

Reference

  1. AWS EC2 服務的申請流程
  2. 在 AWS AMI 環境安裝 Apache 伺服器
  3. 開 Port
  4. 用 SSH 和 Github 連結
  5. Github Deploy Key