這標題超級長的說(崩潰
最近因為有實習生要來,所以把老爸公司設定好 GitLab 和 Gitlba-CI 來作為內部的版本本控制和自動化測試環境。 不過原本規劃的 Staging 環境也是在這檯主機上(當初就很淡定把記憶體和處理器加高,因為我會狂開 VM XD)但是會有 SSH 權限上的問題,原本想利用 Git 的 Hook 之類的來處理,但是感覺似乎不太好。
剛好這次看到 GitLab / GitLab CI 的介紹文,我又再次嘗試安裝,過程上順利、簡單很多。 不過上次不順利肯定是我把整個環境裝在 NAS 裡面的關係 XDD
從我建好 GitLab / GitLab CI 到設定 Capistrano 到自動部署,其實花費不少時間,而且有很多「差點忘記」的部分,因此決定來寫一篇文章做筆記!
以下是我的環境配置(只有一台電腦)
- Host 主機
GitLab Server / GitLab CI Server- GitLab Runner VM (一台)
- Staging VM (一台)
Runner 因為可能會跑 PHP / Ruby 等其他程式語言,避免污染 Host 主機的環境,所以改為開設 VM 運行。 (Host 主機使用 Ubuntu 13.04 Server 僅安裝 Nginx 和 GitLab / GitLab CI 與所需環境)
以下所有 VM 都是設定 Private 並且以 10.0.100.100/255.255.255.0
的規則設定,起始 IP 為 100。
安裝 GitLab
安裝 GitLab CI
上述這兩者安裝都非常簡單,按照官方的文件 Step by Step 即可。
比較特別的部分是因為 GitLab / GitLab CI 都安裝在同一台主機,要另外修改一下 Nginx 設定檔。
把 GitLab CI 的 Niginx 設定檔中 listen 80 default_server
的 default_server
刪除,這樣才不會發生錯誤(那是設定預設開啟哪個網站的設定,只能有一個)
安裝 GitLab CI Runner
基本上也是按照官方的教學處理即可,不過因為是在 VM 所以要先做以下步驟找出 Host 主機的 IP Address 來設定。
1# Ubuntu 新版改用 ip addr show,而非 ifconfig 指令
2ip addr show
找到之後修改 /etc/hosts
來追加對應的 hostname 給 VM 辨識(測試過大部分 Vagrant 的 Plugin 都無法自動設定)
127.0.0.1 localhost
# 我的 Host IP 是 10.0.100.1 而 gitlab 和 gitlab-ci 的 nginx 設定的 server_name 如下
10.0.100.1 gitlab.vm ci.gitlab.vm
確定完成後就運行 bundle exec ./bin/setup
指令設定 Runner 註冊到 CI Server 裡面。
到目前為止,所有設定都是 GitLab 會設定好的。
安裝 Staging VM
1
2Vagrant init
3# 修改設定(private_network, hostname 等)
4vim Vagrantfile
5Vagrant up
6Vagrant ssh
1
2# 修改 Mirror (我是習慣改為 mirror://mirrors.ubuntu.com/mirrors.txt 自動抓取)
3sudo vim /etc/apt/sources.list
4# 更新
5sudo apt-get update
6sudo apt-get upgrade
7# 安裝 RVM / Ruby
8\curl -L https://get.rvm.io | bash -s stable
9# exit / Vagrant ssh (重新連線,讓 rvm 在 login 時就可用)
10#安裝相依
11rvm requirements
12# 安裝所需的 Ruby 版本 / 設定為預設
13rvm install 2.0.0
14rvm use 2.0.0 --default
15# 安裝 JavaScript Runtime (NodeJS)
16# 版本太就可以自己編譯,不要用 nvm 會找不到
17sudo apt-get install nodejs
18# 安裝 Bundler
19gem install bundler
20# 更新 Rake 到最新版本 or 指定版本
21# Capistrano 跑 Rails Migration 的時候不會加上 bundle exec 會讓你的 deploy 被中斷
22gem update rake
23# 安裝其他運行伺服器所需的套件
接下來要設定 Staging VM 可以 Clone 要 Deploy 的網站。
127.0.0.1 localhost
# 和前面設定 Runner 一樣,讓 VM 認出 Host 上面的 GitLab
10.0.100.1 gitlab.vm ci.gitlab.vm
接著產生一組 SSH Key 給 GitLab 辨識(如果是 Public Project 基本上不需要)
ssh-keygen -t rsa
# 複製 id_rsa.pub 的內容貼到 GitLab 的 Deploy Key 裡面
cat ~/.ssh/id_rsa.pub
然後切回 Runner 把他的 Public Key 也複製起來,切到 Staging VM 加入 Authorized Keys 裡面讓 Runner 可以直接 SSH 連到 Staging VM 裡面。
1cat ~/.ssh/id_rsa.pub
1echo "ssh-rsa ......" > ~/.ssh/authorized_keys
記得測試 Runner 是可以正常連上 Staging VM 的狀態~
設定 Capistrano
先在 Gemfile 加入所需的檔案(有使用 rvm 就得加入 rvm 這個項目)
1group :development do
2 gem 'capistrano'
3 gem 'capistrano-Rails'
4 gem 'capistrano-rvm'
5 gem 'capistrano-bundler'
6end
# 安裝 capistrano 套件
bundle install
# 產生設定檔
cap install
先修改 Capfile 來把所需的 bundler / rvm 等都 require 進來。 (目前的版本會都幫你列好,只要 Gemfile 有確定加好,解除註解就會正常了~)
1# Load DSL and Setup Up Stages
2require 'capistrano/setup'
3
4# Includes default deployment tasks
5require 'capistrano/deploy'
6
7# Includes tasks from other gems included in your Gemfile
8#
9# For documentation on these, see for example:
10#
11# https://Github.com/capistrano/rvm
12# https://Github.com/capistrano/rbenv
13# https://Github.com/capistrano/chRuby
14# https://Github.com/capistrano/bundler
15# https://Github.com/capistrano/Rails/tree/master/assets
16# https://Github.com/capistrano/Rails/tree/master/migrations
17#
18require 'capistrano/rvm'
19# require 'capistrano/rbenv'
20# require 'capistrano/chRuby'
21require 'capistrano/bundler'
22# require 'capistrano/Rails/assets'
23require 'capistrano/Rails/migrations'
24
25# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
26Dir.glob('lib/capistrano/tasks/*.cap').each { |r| import r }
然後修改 config/deploy/staging.rb
設定 SSH 連線資訊
1server '10.0.100.102', user: 'Vagrant', roles: %w{web app}
2
3set :ssh_options, {
4 keys: %w(/home/Vagrant/.ssh/id_rsa),
5 forward_agent: false,
6 auth_methods: %w(publickey)
7}
我這邊是直接設定 IP Address 如果你有在 /etc/hosts
加入對應的 Hostname 可以改用 Hostname 比較漂亮。
(Roles 部分我還沒搞懂,有高人請指點一下。基本上我也是把 example.com 一起換成 IP 就是了⋯⋯)
然後修改一下 config/deploy.rb
的設定(依照你的情況)
1# 設定 Branch 為這次 Push 的 Branch / Commit
2branch = 'staging'
3branch = ENV['CI_BUILD_REF'] if ENV['CI_BUILD_REF']
4
5set :branch, branch
這邊用的 CI_BUILD_REF 是 GitLab CI 提供的環境變數,可以用輔助來決定是 Deploy 最新的 Commit 還是某個 Branch 上的最新 Commit (CI_BUILD_REF_NAME + CI_BUILD_REF)這部分可以研究 GitLab CI 的文件來調整。
完成之後就是開 Repoistory 然後設定好 GitLab / GitLab CI 的 Server 設定,接著修改 GitLab CI 要跑的 Script 就完成了!
參考用的 Script 語法
1bundle install
2bundle exec rake db:create RAILS_ENV=test
3bundle exec rake db:migrate RAILS_ENV=test
4bundle exec rake spec RAILS_ENV=test
5cap staging deploy
假設 Rspec 測試沒過,就不會 Deploy 還算不錯,有興趣的可以另外寫成 Shell Script 或者其他東西做更加智慧的判斷 XDD