Heroku 小記

安裝:wget -qO- https://toolbelt.heroku.com/install-ubuntu.sh | sh

在現有的 web application project 目錄裡輸入 heroku create ,這會自動去遠端 (就 heroku) 開一個 app project,然後把 git repository 放到 git remote 裡。
git remote -v 裡會多出一個 heroku ,當你把 master branch push 到 heroku 時 (git push heroku master),就會自動佈署到 heroku 上。
這裡要注意的是 heroku 只認定 master,只有推 master 上去時,才會真正的進行佈署,如果是其他 branch 名稱,heroku 不鳥你。

多台機器開發,我是指一下在 A 機器開發,一下又在 B 機器開發的情況。那這時候怎麼處理 project ?

第1種情況是,直接從 heroku 取得專案:heroku git:clone -a your_heroku_app_name the_directory

第2種情況是,你已經先從你的 git repository 取得專案,那麼這時候就先切換到專案目錄下,再用 heroku git:remote -a your_heroku_app_name 這個指令來自動在 git remote 裡增加一個 heroku 的 remote repository。


安裝資料庫的 Addon

MySQL
Heroku 本身不提供 MySQL,只有合作廠商所提供的 ClearDB,但實質上 ClearDB 就是 MySQL。
ClearDB 有提供4個方案,Ignite 是免費的,雖然免費,但是安裝前,還是要先填信用卡資訊。
安裝方法:heroku addons:create cleardb:ignite
安裝以後,連線字串會放在 CLEARDB_DATABASE_URL 這個環境變數裡,程式只要存取這個環境變數就可以取得連線字串,用 heroku config:get CLEARDB_DATABASE_URL 則可以看到連接字串。
參考這篇文,就可以用本地端的 MySQL Query Browser (MySQL GUI 工具) 連上遠端的 ClearDB。
簡單說,就是從連線字串拆解出 username/password/host ,然後套進去用就可以了。

PostgreSQL
Heroku 預設提供的 database,不過還是要安裝。
安裝方法:heroku addons:add heroku-postgresql:dev
連線字串一樣是在環境變數裡:HEROKU_POSTGRESQL_BRONZE_URL 。

Prometheus

Prometheus 是一個 Monitor 的服務,要收集 host 資訊要搭配 node-exporter,要有 dashboard ,可以搭配 promdash。

而這三者,都有 docker container image 可以下載,但是要怎麼搭在一起,可就讓人傷腦筋了。花了一些時間把他們三個兜在一起,寫成 docker-compose.yml ,這樣就可以用 docker-compose up 直接啟動這三個 container。

過程裡遇到幾個難題:

  1. 沒辦法用自訂的 prometheus 設定:這部份查了老半天,反覆查看 prometheus 的 Dockerfile 以後,確定要 overwrite,所以在 docker-compose.yml 裡,加上了 entrypoint 與 command,其實就是原來的 prometheus Dockerfile 裡的 entrypoint 跟 command,只是 -config.file 這邊修改掉了。
    另外就加掛了自訂的 conf 目錄到容器裡的 /etc/custom 。
  2. prometheus 無法找到 node-exporter:這邊要利用 docker 的 link 在 /etc/hosts 裡插入的主機名稱,不能用 node-exporter 文件裡提到的 localhost ,所以我填入 docker-compose.yml 裡定義的 nodeexporter。

大概就這樣,目前執行結果看起來是沒問題,用一陣子看看吧。另外有在 https://hub.docker.com/u/prom/ 這裡看到不少 container image 可以拉下來組合的,以及 google 的 cAdvisor,有機會再來看看。

後記:實驗結果發現 node-exporter 不適合放在 docker container 裏面執行(跟 node-exporter 對應的,還有一個 container-exporter 專案,是專門收集 container 資訊的),因為會無法收集到關於 host 的資訊,所以 node-exporter 最好還是放在 host 執行,然後讓 prometheus 能存取到。另外,在找關於連結到 host 的部份時,看到有人提報一個 issue 給 docker,建議應該提供一個 –link-host 的功能,讓 container 裏面也能存取到 host,而不需要額外繞路取得。一般的繞路手法是透過 route 取得 gateway 位址,在某些情況下是還蠻麻煩的。

Laravel 5 測試用的資料庫設定

參考這篇來做:How to specify a testing database in Laravel 5?

有打勾的 Best answer 就是了,主要修改部份有兩個,第一個是在 config/database.php 裡,這裡添加給測試環境用的資料庫設定;第二個是在基礎的 TestCase 類別裡,去放置給測試環境用的環境變數。

原理是這樣的,因為 Laravel 應用程式在啟動時,會根據環境變數或是 .env 來決定要啟用哪組資料庫設定,這部份可以在 .env 與 config/database.php 裡看到。所以就可以這樣動手腳來切換,避免 production 與 testing 的資料庫混用。

文章裡有一點是比較不建議的作法,這是我在 Two scoops of Django 這本書上看到的,就是 testing 與 production 的資料庫要一致,不要 production 用 mysql,testing 又用 sqlite 這樣子。畢竟在實際應用時,資料庫的不同仍有可能造成測試結果的不同,那就會導致測試時都沒問題,正式上線時卻出包的情況。

我這邊照著改的時候,有失敗的情況,仔細檢查以後,發現文章裡是用 DB_DEFAULT,而用 Laravel 產生出來的專案框架裡是用 DB_CONNECTION,這邊調整一下就沒有問題了,我猜想可能是 Laravel 版本的關係。

consul server 的啟動方式

要使用 consul 這個軟體必須要有 server,server 啟動的方式有三種:

  1. 先有 bootstrap server,然後其他 server 再加入,這同時也是 0.4 版以前的作法。所以在啟動 consul 時,必須要指定 -bootstrap 與 -server 參數,或是在設定檔裡指定 {“bootstrap”: true, “server”: true };接著在每個 server 的設定檔裡指定 {“server”: true, “start_join”: [“your_bootstrap_server_ip”] }
  2. 先啟動數個 server,然後手動用 consul join 加入,這是 0.4 版以後提供的方式。官方是建議最好使用 3~5 台的 server,這幾台 server 會在 join 之後,自行投票選出誰當 leader 。啟動 consul 時,要指定 -bootstrap-expect expected_server_number 與 -server,或是在設定檔裡指定 {“bootstrap_expect”: expected_server_number, “server”: true },等到啟動之後,再用 consul join server_1_ip server_2_ip server_3_ip 來加入 cluster。
  3. 用 Hashicorp 提供的 atlas 服務,啟動 server 以後,會透過 atlas 服務,自動做 join 的動作。要使用 atlas,必須先到 atlas 註冊,取得 token。啟動 consul 時,要指定 -server, -atlas, -atlas-token 與 -atlas-join ,或是在設定檔裡指定 {“server”: true, “atlas_infrastructure”: “xxx/yyy”, “atlas_join”: true, “atlas_token”: “your_atlas_token” }

這裏面當然是用 atlas 最方便,除了有提供 Web UI 可以做監控之外,還可以使用 vagrantup 跟 terraform 等來做管理,只是使用這項服務是有代價的,超過 10 個 node 每個月收費 40 美金。

參考資料:

Golang and GVM

Ubuntu 14.04 預載了 Golang 1.2 ,如果想要其他版本的呢?到官方網站去找,會發現根本找不到下載連結。用 ppa 去找,是可以找到這個 golang 1.4 : Jay R. Wren

為了安全起見,還是用 Version manager 好了,Golang 的 Version manager 在網路上可以找到兩個:govm 跟 GVM,目前看起來比較常見的是 GVM。GVM 的安裝可以參考這篇:7 Easy Steps to Install Go (Golang) on Ubuntu

摘錄安裝步驟如下:

  1. bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
  2. 在 .bashrc 或 .zshrc 裡加入 [[ -s “$HOME/.gvm/scripts/gvm” ]] && source “$HOME/.gvm/scripts/gvm”
  3. 新開或重開終端機

使用方法:

  • 看能下載的版本:gvm listall
  • 列出目前有的版本:gvm list
  • 安裝指定版本:gvm install desired_version
  • 使用指定版本:gvm use go1.4.2
  • 其他指令說明,執行:gvm

 

OpsWork / Terraform / Vagrant 小感

Vagrant 其實不太能拿來跟 OpsWork 或 Terraform 相比,不過有了 push 之後,算是有個堪用的 deploy 方法…

前一陣子看到 Terraform ,只要寫好腳本(或者該說是計劃),這工具就會自動幫你把環境佈署到雲端,比如說,你有 Web application、Web Server、Database、HAProxy … 等等,在腳本描述好關係之後,Terraform 可以自動幫你佈署到 AWS 、DigitalOcean、CloudStack、Docker、Google cloud 、OpenStack、Heroku … 等地方,非常的方便。但如果要用在內部的環境,可能就沒辦法 (除非內部自架了 CloudStack 或 OpenStack)。

OpsWorks 是在 DevOps gitter 裡看到的,Google 了一下,這是 Amazon 提供的服務,做的事情其實跟 Terraform 蠻相近的,跟 Amazon 的服務整合度更高。我是還沒試用過,不知道好不好用。

Vagrant 本身是操作虛擬機器的好幫手,在 Google Altas 時,看到 Vagrant 有提供 push 這子指令,這可以用來做 deploy 。比如說,你在 Vagrantfile 裡描述了 Web application server、Web Server、Database server … 等等,在本地端可以用 vagrant up  啟動,進行驗證,那要實際佈署到遠端時,就可以用 push 來做。push 的對象(或者該說是方式?)可以是 Altas、FTP/SFTP、Heroku 或執行自訂的腳本,所以看起來或許適合我現在的情境。

順便記一些連結:

golang 起手

環境是 Ubuntu 14.04 trusy,14.04 預載的 go 版本是 1.2.1 。

先安裝 golang :sudo apt-get install golang golang-go golang-go.tools ,然後設定環境變數,看是用 bash 或 zsh,bash 就是改 $HOME/.bashrc,zsh 就是改 $HOME/.zshrc,加入:

export GOROOT=$(go env GOROOT)
export GOPATH=$HOME/.go
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin

然後 mkdir -p $HOME/.go ,$GOPATH 這路徑裡,放的是 go get 所取得的原始碼。

接著就可以照 golang 环境配置建议 裏面的建議來安裝工具,裏面的 oracle 可以跳過,這已經包在 golang-go.tools 裡。另外這篇裡的編輯器是介紹用 Github 的 ATOM,所以該找時間來找一下 vim 的好用 plugin 來用。

要安裝比較新版本的 golang ,除了可以找 ppa 之外,也可以用 govm 或 gvm 來安裝:

govm 看起來顯然是小很多,gvm 在網路上的介紹文比較多,自己目前是還沒試過。

Packer

是 HashiCorp 釋出的一個工具,它可以依照寫好的設定檔,打包各種格式的 image,像 Amazon Machine Image (給 EC2 用)、Virtualbox iso/ovf、digital ocean、docker、openstack、vmware iso/vmx、Vagrant box …. 等等。安裝很簡單,就下載 zip ,解壓縮 (Linux 下要改權限) 放到路徑裡就可以使用了。

第一次撰寫可以參考 https://github.com/shiguredo/packer-templates 這裡的設定檔範例。指令的使用也蠻簡單,例如:只要做 virtualbox 用的 ovf ,packer build -only=virtualbox-iso template.json

一口氣 build 不同格式的 image:packer build -parallel=true template.json

在 provision 的部份,可以用 shell、chef、puppet… 等,也可以用 ansible https://www.packer.io/docs/provisioners/ansible-local.html

打包好的 image ,會自動放在或推到對應的地方,例如 AMI 就會放到 Amazon 那邊,docker image 可以推送到 docker registry,digital ocean 就是 droplet 或者是推送到 vagrant 等等。

git clone fail

遇到下面這錯誤~

$ git clone http://your_host/your_group/your_project.git
Cloning into 'your_project'...
remote: Counting objects: 426, done.
remote: Compressing objects: 100% (375/375), done.
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed

過程大致就如 gitlab – error: git-upload-pack died of signal 13 – Stack Overflow

所以我試過 git config –global http.postBuffer 524288000 ,也試著加過 GIT_CURL_VERBOSE ,但都看不出什麼端倪,伺服器上的 log 也沒看到,最後就如 gitlab – error: git-upload-pack died of signal 13 – Stack Overflow 的解答所說,是 permission 問題。我猜可能是我有調整 nginx user 的關係,導致錯誤。後來就是依據 log 裡的提示,調整 /var/run/nginx/proxy 下資料夾的 owner 就解決問題了。

Use NFS as synced folder in Vagrant

Just note during I use NFS as synced folder in Vagrant.

  1. In your host, you have to install nfs-kernel-server:
    sudo apt-get install nfs-kernel-server
  2. In your Vagrantfile, you have to specify private_network even you want to use public_network.  If you don’t specify private_network, vagrant up will fail.  Then specify synced_folder.
    config.vm.network "private_network", ip: "192.168.33.10"
    config.vm.network "public_network", ip: "192.168.11.2", bridge: "eth0"
    config.vm.synced_folder ".", "/vagrant", type: "nfs"

Reference: