由於過去這幾年每次 deploy 到 Heroku 都吃了大虧,所以我決定趁這次一次把話講清楚,把所有會遇到的雷都一次記起來 = =
第一步驟:永遠記得先開 git 才開 heroku
第一步當然是先開 rails app 啦,這個沒爭議齁
rails new my_project
重點來啦!再跑 heroku create
之前一定千萬記得要先跑完 git
的相關指令,尤其第一次跑別忘了 git init
:
git init
git add .
git commit -m "init"
等到上面四個都跑完了,才可以開你的 heroku ,也就是
heroku create my-project
如果你先創 Heroku 才跑 git
,那麼等到跑上面那一行的時候就會GG。 萬一這件事情真的發生了,其實也沒關係,就是要打開 Heroku 的官方網頁,登進去把你之前創的那個 app 刪掉,重新來過。
my-project
是我在這邊取的 app 名稱啦,請自行換成你的名字;為了區別,所以 rails 的 app 名稱我取叫 my_project
但是 Heroku 上面的 app 名字我取叫做 my-project
。
每次要deploy Rails 專案到 heroku 都會遇到一樣惱人的問題: 要用 PostgreSQL,每次光想到這點就很崩潰。
為了可以兼顧 heroku 但是又可以簡化開發程序,所以我在自己的電腦上還是用 sqlite3
XD,所以我的 Gemfile
是這樣寫的:
gem 'pg', :group => :production
gem 'sqlite3', :group => [:development, :test]
但是如果這樣改完你就直接去跑 bundle install
一定會有問題,他會跟你抱怨
An error occurred while installing pg (0.17.0), and Bundler cannot continue.
Make sure that `gem install pg -v '0.17.0'` succeeds before bundling.
想單然爾你實際上去跑 gem install pq -v=0.17.0
一定也是失敗收場,不會成功了。值得一提的是因為我是用 RVM 所以 gem install
前面並不需要加 sudo
喔。
就像 mySQL 一樣,其實要安裝 pq
需要電腦上先有 PostgreSQL 的相關 lib ,但是我們又要怎麼裝起來呢?經過多次嘗試之後,我覺得毫無疑問最無痛的方法就是透過 brew
去裝,關於 brew 的安裝方式這邊就不解釋了。
你唯一需要做的就是
brew install PostgreSQL
接著當你再次執行
gem install pq
你會發現你成功了。超爽der。
然後你就可以跑 bundle install
惹。
我真的是視送app上heroku為畏途...... 儘管開發 rails 再怎麼愉快,每次光想到要送app上heroku就先軟一半。後來我逐漸掌握到一些訣竅:
- 學會搞定 pq
- 永遠用最新版的 rails
基本上掌握這兩點就八九不離十了。
這一次我還用了 xdite 的團隊開發的 gem boostrappers
,想不到卻因此遭受到前所未有的鬼打牆局面。一開始是push
完到最後會抱怨 precompile 失敗,解決之道是app/assets/javascripts/README
把它改成README.txt
,然後先在自己的電腦上先跑
rake assets:precompile
嗯,總之先在自己電腦上跑 precombile 就對了, somehow it works。至於為什麼我直覺就想到要把README
加上附檔名這是因為 rails 4.0 剛出不久就在 xdite 大大的文章裡面看到這件事情了XD。
另外一件事情鬼打牆比較久,push
成功之後,還是打不開網站。查看 heroku logs
之後好不容易找到這一段:
2013-11-18T19:28:42.063321+00:00 heroku[web.1]: Starting process with command `bin/rails server -p 4734 -e $RAILS_ENV`
2013-11-18T19:28:49.787036+00:00 app[web.1]: from /app/vendor/bundle/ruby/2.0.0/gems/settingslogic-2.0.9/lib/settingslogic.rb:102:in `initialize'
2013-11-18T19:28:49.787036+00:00 app[web.1]: /app/vendor/ruby-2.0.0/lib/ruby/2.0.0/open-uri.rb:36:in `initialize': No such file or directory - /app/config/config.yml (Errno::ENOENT)
咦,奇~~~~~~~怪了,明明config/config.yml
就好好地蹲在那邊啊,為什麼會找不到咧?弄到半夜三點實在找不出來,只好去怒睡,結果隔天一早醒來就想到了,原來在根目錄下面有一個 .gitignore
...... 好樣地,最下面居然有寫
# Ignore all logfiles and tempfiles.
/log/*.log
/tmp
*.DS_Store
*.swp
.env
public/uploads
vendor/bundler_gems
config/database.yml
config/config.yml
真的是只能大罵靠北啊啊啊啊啊,好吧,那就把 config/config.yml
那行先 comment 掉吧,然後就push成功惹。
啊啊啊啊,再寫下去都可以寫一個 幹譙 heroku 專欄惹。
總之昨天最新遇到的困境是可以跑 heroku run rake db:migrate
,但是不能跑heroku run rake db:reset
或者heroku run rake db:drop
,這根本超級崩潰啊啊啊啊,教練我想刪檔啊QQ
查看 heroku logs
之後,發現做這兩個動作,PostgreSQL會回傳 permission denied,哪招!
後來我自己找到的解法是
heroku pg:reset DATABASE
果然是解鈴仍需繫鈴人,用 pg
的指令就解決了。
另外做個筆記,如果用 heroku 的話, database.yml
不需要寫 username
,然後密碼留白就好,例如
production:
adapter: postgresql
encoding: unicode
database: myapp_production
pool: 5
password:
這招是之前在電機系當網管助教的時候跟學長學的,因為電機系的學生與教授帳號都是基於工作站系統,但是我們寫 web 網頁的主機並沒有直接的管道跟工作站主機溝通,所以其中一個驗證登入身份的方法式利用 telnet
連接 POP3 主機,確認是否可以登入。
這次會實際用到是為了清大校長模擬選舉網站,我們作為一個非官方的網站,但是要能驗證投票者是否為清大學生或者校友,因此最佳的實作方法就是請投票者提供學校計中的信箱帳號和密碼,我們嘗試登入 POP3 主機,便可以快速證明該使用者是否為信箱擁有者。
Ruby 對 telnet 的支援
在寫入 Ruby on rails 之前我先在自己電腦上寫 Ruby 沙盤推演,先確定了 POP3 主機可以用 telnet
溝通而且走 port 110 [1] ,並且很快找到了兩個參考資料,一篇是中文的實作[2] 一篇是 Net::Telnet
的 doc
,看了這兩篇之後才發現 Ruby 的 telnet 支援遠比我想像中還要強大,因此不到半小時就把流程用 Ruby 寫出來了。