2018/1/7

第十九天:發布網站到 Heroku (續)

前情提要

昨天我們在發布網站的過程中遇到了錯誤:

remote:        In Gemfile:
remote:        sqlite3
remote:  !
remote:  !     Failed to install gems via Bundler.
remote:  !     Detected sqlite3 gem which is not supported on Heroku:
remote:  !     https://devcenter.heroku.com/articles/sqlite3

heroku:「ㄉㄅㄑ,我不會用 sqlite3。」

所以我們必須移除 sqlite3 這個套件才行。

認識 Gemfile

Gemfile 在專案的根目錄下:

第12行寫著:gem 'sqlite3' 表示這個專案會使用 sqlite3 這個套件。套件是一群佛心來的人寫好後公開給大家用的程式。如果你想要安裝套件,就會需要在這裡加一行程式,如果想要移除某個套件,就要刪掉那一行程式。

這裡有所有能裝的套件:https://rubygems.org/gems。如果你想要成佛也可以在這裡貢獻一下你的程式。

每當修改過 Gemfile 之後,你要在小黑框輸入 bundle install。 bundle 是一個管理套件的套件,他會幫你下載套件程式碼。

如果你輸入 bundle install 之後看到的是這樣:

D:\只要有心,人人都可以作卡米狗\ironman>bundle install
'bundle' 不是內部或外部命令、可執行的程式或批次檔。

表示你的電腦沒有裝過 bundler,需要在小黑框輸入 gem install bundler 來安裝。

D:\只要有心,人人都可以作卡米狗\ironman>gem install bundler
Fetching: bundler-1.16.1.gem (100%)
Successfully installed bundler-1.16.1
Parsing documentation for bundler-1.16.1
Installing ri documentation for bundler-1.16.1
Done installing documentation for bundler after 20 seconds
1 gem installed 

移除 rails 專案中所使用的 sqlite3 套件

我們開始進行 sqlite3 的移除工作吧。

前面提到 Gemfile 第12行寫著:gem 'sqlite3',我們可以在這行的最前面加一個 # 號把這行變成註解,像這樣:

當然你要直接刪掉那行也不是不行啦,弄好之後記得存檔,存完檔之後,在小黑框輸入 bundle install

D:\只要有心,人人都可以作卡米狗\ironman>bundle
Using rake 12.3.0
Using concurrent-ruby 1.0.5
Using i18n 0.9.1
Using minitest 5.10.3
Using thread_safe 0.3.6
Using tzinfo 1.2.4
Using activesupport 5.1.4
Using builder 3.2.3
Using erubi 1.7.0
Using mini_portile2 2.3.0
Using nokogiri 1.8.1 (x64-mingw32)
Using rails-dom-testing 2.0.3
Using crass 1.0.3
Using loofah 2.1.1
Using rails-html-sanitizer 1.0.3
Using actionview 5.1.4
Using rack 2.0.3
Using rack-test 0.8.2
Using actionpack 5.1.4
Using nio4r 2.2.0
Using websocket-extensions 0.1.3
Using websocket-driver 0.6.5
Using actioncable 5.1.4
Using globalid 0.4.1
Using activejob 5.1.4
Using mini_mime 1.0.0
Using mail 2.7.0
Using actionmailer 5.1.4
Using activemodel 5.1.4
Using arel 8.0.0
Using activerecord 5.1.4
Using public_suffix 3.0.1
Using addressable 2.5.2
Using bindex 0.5.0
Using bundler 1.16.1
Using byebug 9.1.0
Using xpath 2.1.0
Using capybara 2.16.1
Using ffi 1.9.18 (x64-mingw32)
Using childprocess 0.8.0
Using coffee-script-source 1.12.2
Using execjs 2.7.0
Using coffee-script 2.4.1
Using method_source 0.9.0
Using thor 0.20.0
Using railties 5.1.4
Using coffee-rails 4.2.2
Using multi_json 1.12.2
Using jbuilder 2.7.0
Using puma 3.11.0
Using sprockets 3.7.1
Using sprockets-rails 3.2.1
Using rails 5.1.4
Using rb-fsevent 0.10.2
Using rb-inotify 0.9.10
Using rubyzip 1.2.1
Using sass-listen 4.0.0
Using sass 3.5.4
Using tilt 2.0.8
Using sass-rails 5.0.7
Using selenium-webdriver 3.8.0
Using turbolinks-source 5.0.3
Using turbolinks 5.0.1
Using tzinfo-data 1.2017.3
Using uglifier 4.0.2
Using web-console 3.5.1
Bundle complete! 12 Gemfile dependencies, 66 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.

D:\只要有心,人人都可以作卡米狗\ironman>

你會看到目前專案正在使用的所有套件。

進行本機測試

開啟 rails server 看看是否一切正常:

D:\只要有心,人人都可以作卡米狗\ironman>rails s
=> Booting Puma
=> Rails 5.1.4 application starting in development
=> Run `rails server -h` for more startup options
*** SIGUSR2 not implemented, signal based restart unavailable!
*** SIGUSR1 not implemented, signal based restart unavailable!
*** SIGHUP not implemented, signal based logs reopening unavailable!
Puma starting in single mode...
* Version 3.11.0 (ruby 2.4.2-p198), codename: Love Song
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop

看似正常,開網頁 http://localhost:3000/ 看卻發現:

他說:「你的程式有用到 sqlite3,但是你沒有安裝 sqlite3,所以我又爆啦。」

我們在那裡用到了 sqlite3?

我們在 config/database.yml 中使用了 sqlite3

原來 sqlite3 是一個資料庫的套件,但是由於 heroku 不支援 sqlite3,所以我們必須找另一款 heroku 能支援的資料庫換上去,這裡我們要換的是 postgresql

改用 postgresql

我們需要把 config/database.yml 中第 8 行的 adapter: sqlite3 改為 adapter: postgresql

我們還需要安裝 postgresql 這個套件,這個套件叫 pg,所以修改 Gemfile 如下:

我在第 13 行寫 gem 'pg', '~> 0.21.0',其實要寫在第幾行都行。不過第 37 行有一個 group:

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development, :test do 這行的意思是,只有在開發和測試環境下才需要安裝的套件。因為我們的 heroku 的環境是 :production,所以我們如果把 gem 'pg', '~> 0.21.0' 寫在這個 group 裡的話,heroku 就還是壞的。

其中~> 0.21.0 表示版本號,一個套件會隨著時間不斷更新,就像 iOS 和 Android 也會一直系統更新一樣。我們可以指定想要安裝的版本。

改完 Gemfile 之後,先關閉網頁伺服器,然後在小黑框輸入 bundle install 安裝新套件完之後再打開網頁伺服器。

再次進行本機測試

打開網頁:http://localhost:3000/

正常!

把改動後的程式碼上傳到 heroku

上傳到 heroku 之前要先建立一個 git 版本,之前提到過的上傳三步驟:

git add .
git commit -m "註解"
git push heroku master

如果你覺得註解亂寫沒關係的話,我是沒差,你可以直接複製上面三行程式碼到小黑框貼上。不過我就一步步來。

git add .

選擇所有檔案加入這次的版本:

D:\只要有心,人人都可以作卡米狗\ironman>git add .
warning: LF will be replaced by CRLF in Gemfile.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in Gemfile.lock.
The file will have its original line endings in your working directory.
warning: LF will be replaced by CRLF in config/database.yml.
The file will have its original line endings in your working directory.

git commit -m "改用pg"

建立一個版本,我的註解是寫 改用pg 說明我們這次的改動:

D:\只要有心,人人都可以作卡米狗\ironman>git commit -m "改用pg"
[master e6f3871] '改用pg'
 3 files changed, 5 insertions(+), 2 deletions(-)

D:\只要有心,人人都可以作卡米狗\ironman>

git push heroku master

上傳程式碼到 heroku:

D:\只要有心,人人都可以作卡米狗\ironman>git push heroku master
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 297 bytes | 297.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Ruby app detected
remote: -----> Compiling Ruby/Rails
remote: -----> Using Ruby version: ruby-2.3.4
remote: ###### WARNING:
remote:        Removing `Gemfile.lock` because it was generated on Windows.
remote:        Bundler will do a full resolve so native gems are handled properly.
remote:        This may result in unexpected gem versions being used in your app.
remote:        In rare occasions Bundler may not be able to resolve your dependencies at all.
remote:        https://devcenter.heroku.com/articles/bundler-windows-gemfile
remote:
remote: -----> Installing dependencies using bundler 1.15.2
remote:        Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4
remote:        The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`.
remote:        Fetching gem metadata from https://rubygems.org/..........
remote:        Fetching version metadata from https://rubygems.org/..
remote:        Fetching dependency metadata from https://rubygems.org/.
remote:        Resolving dependencies...
remote:        Using rake 12.3.0
remote:        Using concurrent-ruby 1.0.5
remote:        Using minitest 5.11.1
remote:        Using thread_safe 0.3.6
remote:        Using builder 3.2.3
remote:        Using erubi 1.7.0
remote:        Using mini_portile2 2.3.0
remote:        Using crass 1.0.3
remote:        Using rack 2.0.3
remote:        Using nio4r 2.2.0
remote:        Using websocket-extensions 0.1.3
remote:        Using mini_mime 1.0.0
remote:        Using arel 8.0.0
remote:        Using bundler 1.15.2
remote:        Using coffee-script-source 1.12.2
remote:        Using execjs 2.7.0
remote:        Using method_source 0.9.0
remote:        Using thor 0.20.0
remote:        Using ffi 1.9.18
remote:        Using multi_json 1.12.2
remote:        Fetching pg 0.21.0
remote:        Using puma 3.11.0
remote:        Using rb-fsevent 0.10.2
remote:        Using tilt 2.0.8
remote:        Using turbolinks-source 5.0.3
remote:        Using tzinfo 1.2.4
remote:        Using nokogiri 1.8.1
remote:        Using i18n 0.9.1
remote:        Using rack-test 0.8.2
remote:        Using sprockets 3.7.1
remote:        Using websocket-driver 0.6.5
remote:        Using mail 2.7.0
remote:        Using coffee-script 2.4.1
remote:        Using uglifier 4.1.2
remote:        Using rb-inotify 0.9.10
remote:        Using turbolinks 5.0.1
remote:        Using loofah 2.1.1
remote:        Using activesupport 5.1.4
remote:        Using sass-listen 4.0.0
remote:        Using rails-html-sanitizer 1.0.3
remote:        Using rails-dom-testing 2.0.3
remote:        Using globalid 0.4.1
remote:        Using activemodel 5.1.4
remote:        Using jbuilder 2.7.0
remote:        Using sass 3.5.5
remote:        Using actionview 5.1.4
remote:        Using activejob 5.1.4
remote:        Using activerecord 5.1.4
remote:        Using actionpack 5.1.4
remote:        Using actioncable 5.1.4
remote:        Using actionmailer 5.1.4
remote:        Using railties 5.1.4
remote:        Using sprockets-rails 3.2.1
remote:        Using coffee-rails 4.2.2
remote:        Using rails 5.1.4
remote:        Using sass-rails 5.0.7
remote:        Installing pg 0.21.0 with native extensions
remote:        Bundle complete! 13 Gemfile dependencies, 56 gems now installed.
remote:        Gems in the groups development and test were not installed.
remote:        Bundled gems are installed into ./vendor/bundle.
remote:        Bundle completed (11.93s)
remote:        Cleaning up the bundler cache.
remote:        The latest bundler is 1.16.1, but you are currently running 1.15.2.
remote:        To update, run `gem install bundler`
remote: -----> Installing node-v6.11.1-linux-x64
remote: -----> Detecting rake tasks
remote: -----> Preparing app for Rails asset pipeline
remote:        Running: rake assets:precompile
remote:        Yarn executable was not detected in the system.
remote:        Download Yarn at https://yarnpkg.com/en/docs/install
remote:        Asset precompilation completed (1.50s)
remote:        Cleaning assets
remote:        Running: rake assets:clean
remote:
remote: ###### WARNING:
remote:        You have not declared a Ruby version in your Gemfile.
remote:        To set your Ruby version add this line to your Gemfile:
remote:        ruby '2.3.4'
remote:        # See https://devcenter.heroku.com/articles/ruby-versions for more information.
remote:
remote: ###### WARNING:
remote:        Removing `Gemfile.lock` because it was generated on Windows.
remote:        Bundler will do a full resolve so native gems are handled properly.
remote:        This may result in unexpected gem versions being used in your app.
remote:        In rare occasions Bundler may not be able to resolve your dependencies at all.
remote:        https://devcenter.heroku.com/articles/bundler-windows-gemfile
remote:
remote: ###### WARNING:
remote:        No Procfile detected, using the default web server.
remote:        We recommend explicitly declaring how to boot your server process via a Procfile.
remote:        https://devcenter.heroku.com/articles/ruby-default-web-server
remote:
remote: -----> Discovering process types
remote:        Procfile declares types     -> (none)
remote:        Default types for buildpack -> console, rake, web, worker
remote:
remote: -----> Compressing...
remote:        Done: 36.7M
remote: -----> Launching...
remote:        Released v8
remote:        https://people-all-love-kamigo.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/people-all-love-kamigo.git
   e6f3871..5ec30ea  master -> master

D:\只要有心,人人都可以作卡米狗\ironman>

這次看似上傳成功了,從最後面往上看,倒數第 5 行有一個網址:https://people-all-love-kamigo.herokuapp.com/,以及三個 WARNING。

先不管 WARNING,我們複製網址進去看(你的網址會跟我的不同,取決於你之前下 heroku create 指令時輸入的網站名稱)。

Heroku說:「找不到網頁。」

這是因為在我們本機的首頁,其實是不在專案資料夾裡面的,記得一開始修改網頁(第九天:作一個最簡單的 Rails 網站)時,我們是去哪改嗎?是在 C:/Ruby24-x64/lib/ruby/gems/2.4.0/gems/railties-5.1.4/lib/rails/templates/rails/welcome/index.html.erb,而這個檔案並不是在專案資料夾下,所以遠端伺服器沒有這個檔案也是很合邏輯的。

事實上,只有在 config/routes.rb 檔案裏面有寫到的那些路徑才是我們應該測的路徑,所以我們應該連到這裡:https://people-all-love-kamigo.herokuapp.com/kamigo/eat

吃土啦~

總結

程式碼除錯的流程大致上為:

  • 閱讀錯誤訊息
  • 修改程式碼
  • 測試網站,若失敗則回到第一步
  • 發布網站

工程師的日常就是除了一個錯之後看到的不是正常,而是看到下一個錯誤訊息。

要有耐心。

沒有留言: