RoR♡DevOpsチュートリアル
はじめに
これは著者が考える「今ドキのDevOps☆スタイルでRailsアプリを開発する考え方と手順」をできるだけ細かく説明していくページです。
RoRの経験が少なかったり、Vagrant・ChefなどのDevOpsとセットで語られることがあるツールを始めたばかりでも、ある程度ついていけて、読み終えたあとに一定の知識がつくような説明を目指しています。
Rubyや基本的なLinuxコマンドの知識を前提としています。
ひな形作成
まずはrails newコマンドを実行して、プロジェクトのひな形を作成する。
$ rails new uiharu
実行結果の例は以下のとおり。
ひな形が作成されたあと、Gemfileが生成されて、bundle installによるgemのインストールまでが自動で行われる。
$ rails new uiharu create create README.rdoc create Rakefile create config.ru create .gitignore create Gemfile create app create app/assets/javascripts/application.js create app/assets/stylesheets/application.css create app/controllers/application_controller.rb create app/helpers/application_helper.rb create app/views/layouts/application.html.erb create app/assets/images/.keep create app/mailers/.keep create app/models/.keep create app/controllers/concerns/.keep create app/models/concerns/.keep create bin create bin/bundle create bin/rails create bin/rake create config create config/routes.rb create config/application.rb create config/environment.rb create config/environments create config/environments/development.rb create config/environments/production.rb create config/environments/test.rb create config/initializers create config/initializers/backtrace_silencers.rb create config/initializers/filter_parameter_logging.rb create config/initializers/inflections.rb create config/initializers/mime_types.rb create config/initializers/secret_token.rb create config/initializers/session_store.rb create config/initializers/wrap_parameters.rb create config/locales create config/locales/en.yml create config/boot.rb create config/database.yml create db create db/seeds.rb create lib create lib/tasks create lib/tasks/.keep create lib/assets create lib/assets/.keep create log create log/.keep create public create public/404.html create public/422.html create public/500.html create public/favicon.ico create public/robots.txt create test/fixtures create test/fixtures/.keep create test/controllers create test/controllers/.keep create test/mailers create test/mailers/.keep create test/models create test/models/.keep create test/helpers create test/helpers/.keep create test/integration create test/integration/.keep create test/test_helper.rb create tmp/cache create tmp/cache/assets create vendor/assets/javascripts create vendor/assets/javascripts/.keep create vendor/assets/stylesheets create vendor/assets/stylesheets/.keep run bundle install Fetching gem metadata from https://rubygems.org/.......... Fetching gem metadata from https://rubygems.org/.. Resolving dependencies... Installing rake (10.1.1) Installing i18n (0.6.9) Using minitest (4.7.5) Installing multi_json (1.8.4) Using atomic (1.1.14) Using thread_safe (0.1.3) Using tzinfo (0.3.38) Using activesupport (4.0.2) Using builder (3.1.4) Using erubis (2.7.0) Using rack (1.5.2) Using rack-test (0.6.2) Using actionpack (4.0.2) Installing mime-types (1.25.1) Using polyglot (0.3.3) Installing treetop (1.4.15) Using mail (2.5.4) Using actionmailer (4.0.2) Using activemodel (4.0.2) Using activerecord-deprecated_finders (1.0.3) Using arel (4.0.2) Using activerecord (4.0.2) Using bundler (1.3.5) Installing coffee-script-source (1.7.0) Installing execjs (2.0.2) Installing coffee-script (2.2.0) Using thor (0.18.1) Using railties (4.0.2) Installing coffee-rails (4.0.1) Using hike (1.2.3) Installing jbuilder (1.5.3) Installing jquery-rails (3.1.0) Using json (1.8.1) Using tilt (1.4.1) Installing sprockets (2.10.1) Using sprockets-rails (2.0.1) Using rails (4.0.2) Installing rdoc (4.1.1) Installing sass (3.2.14) Installing sass-rails (4.0.1) Installing sdoc (0.4.0) Installing sqlite3 (1.3.8) Installing turbolinks (2.2.1) Installing uglifier (2.4.0) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. Post-install message from rdoc: Depending on your version of ruby, you may need to install ruby rdoc/ri data: <= 1.8.6 : unsupported = 1.8.7 : gem install rdoc-data; rdoc-data --install = 1.9.1 : gem install rdoc-data; rdoc-data --install >= 1.9.2 : nothing to do! Yay!
テーブル設計
方針
ユーザ(いわゆるお客さま)がWeb UIなどから直接・間接的に利用するデータ(Webサービスの状態)だけをテーブルに保持する。
その他のデータ、例えば履歴、バックアップはバッチ処理などユーザと関係ないところで使うことを主な目的と考えて、
S3などの容量単価が安くバッチ処理に強くWebサービスと独立したストレージに保存する。
*がついたカラムは初期実装では必須ではない、後付しやすいもの。
Tasks
ID | Title | Assignee ID | Assignor ID | Start Date | *Due Date | Finish Date |
---|---|---|---|---|---|---|
foreign key: users.id | foreign key: users.id | |||||
このテーブルに対応するscaffoldを以下のコマンドで作成する。
$ rails g scaffold task title:string assignee_id:integer assignor_id:integer start_date:date due_date:date finish_date:date
scaffold作成時のログは以下のとおり。model、view、controller、route、helperやそのspec、scssファイルが作成される。
invoke active_record create db/migrate/20140218061028_create_tasks.rb create app/models/task.rb invoke rspec create spec/models/task_spec.rb invoke resource_route route resources :tasks invoke scaffold_controller create app/controllers/tasks_controller.rb invoke erb create app/views/tasks create app/views/tasks/index.html.erb create app/views/tasks/edit.html.erb create app/views/tasks/show.html.erb create app/views/tasks/new.html.erb create app/views/tasks/_form.html.erb invoke rspec create spec/controllers/tasks_controller_spec.rb create spec/views/tasks/edit.html.erb_spec.rb create spec/views/tasks/index.html.erb_spec.rb create spec/views/tasks/new.html.erb_spec.rb create spec/views/tasks/show.html.erb_spec.rb create spec/routing/tasks_routing_spec.rb invoke rspec create spec/requests/tasks_spec.rb invoke helper create app/helpers/tasks_helper.rb invoke rspec create spec/helpers/tasks_helper_spec.rb invoke jbuilder create app/views/tasks/index.json.jbuilder create app/views/tasks/show.json.jbuilder invoke assets invoke coffee create app/assets/javascripts/tasks.js.coffee invoke scss create app/assets/stylesheets/tasks.css.scss invoke scss create app/assets/stylesheets/scaffolds.css.scss
scssファイルの文法については、「SASS公式ドキュメントのSCSS紹介ページ」が詳しい。
Users
ID | Authentication Method | *Withdrawal Date | *Suspension Date |
---|---|---|---|
OAuth2Users
ID | User ID | Access Token | *Issue Date | *Expiration Date |
---|---|---|---|---|
Further readings
Akka + SprayでRailsアプリと連携するバックエンドをつくる。
開発環境セットアップ
Railsアプリの開発に必要そうなツール、ライブラリ等を一通りインストールしておく。
基本的には以下の内容の通りでOK。
https://devcenter.heroku.com/articles/getting-started-with-rails4#migrate-your-database
http://blog.mah-lab.com/2014/01/08/rails-wercker-heroku-deploy/
rbenvを使う場合の一通りの手順は「 rbenvによるRuby環境のセットアップ」を参照。
Railsに必要なgemのインストール
rails newでGemfileが生成されるので、そこに記述されているgemをbundleコマンドでインストールする。
$ bundle install Fetching gem metadata from https://rubygems.org/......... Fetching additional metadata from https://rubygems.org/.. Installing rake (10.1.1) Installing i18n (0.6.9) Using minitest (4.7.5) Installing multi_json (1.8.4) Installing atomic (1.1.14) Installing thread_safe (0.1.3) Installing tzinfo (0.3.38) Installing activesupport (4.0.2) Installing builder (3.1.4) Installing erubis (2.7.0) Installing rack (1.5.2) Installing rack-test (0.6.2) Installing actionpack (4.0.2) Installing mime-types (1.25.1) Installing polyglot (0.3.3) Installing treetop (1.4.15) Installing mail (2.5.4) Installing actionmailer (4.0.2) Installing activemodel (4.0.2) Installing activerecord-deprecated_finders (1.0.3) Installing arel (4.0.2) Installing activerecord (4.0.2) Installing coffee-script-source (1.7.0) Installing execjs (2.0.2) Installing coffee-script (2.2.0) Installing thor (0.18.1) Installing railties (4.0.2) Installing coffee-rails (4.0.1) Installing diff-lcs (1.2.5) Installing hike (1.2.3) Installing jbuilder (1.5.3) Installing jquery-rails (3.1.0) Using json (1.8.1) Installing pg (0.17.1) Using bundler (1.5.3) Installing tilt (1.4.1) Installing sprockets (2.10.1) Installing sprockets-rails (2.0.1) Installing rails (4.0.2) Installing rdoc (4.1.1) Installing rspec-core (2.14.7) Installing rspec-expectations (2.14.4) Installing rspec-mocks (2.14.4) Installing rspec-rails (2.14.0) Installing sass (3.2.14) Installing sass-rails (4.0.1) Installing sdoc (0.4.0) Installing turbolinks (2.2.1) Installing uglifier (2.4.0) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. Post-install message from rdoc: Depending on your version of ruby, you may need to install ruby rdoc/ri data: <= 1.8.6 : unsupported = 1.8.7 : gem install rdoc-data; rdoc-data --install = 1.9.1 : gem install rdoc-data; rdoc-data --install >= 1.9.2 : nothing to do! Yay!
PostgeSQL
DBはRailsが対応しているものならなんでもいいのだが、今回はHerokuへのデプロイも視野にいれて、ローカルとHerokuの両方で使えるPostgreSQLを使う。
PostgreSQLはHomebrewでインストールすると楽。
$ brew install postgresql Warning: Your Xcode (4.6.3) is outdated Please update to Xcode 5.0.1. Xcode can be updated from the App Store. ==> Installing postgresql dependency: ossp-uuid ==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/ossp-uuid-1.6.2.mountain_lion.bottle.1.tar.gz ######################################################################## 100.0% ==> Pouring ossp-uuid-1.6.2.mountain_lion.bottle.1.tar.gz ==> Caveats This formula is keg-only, so it was not symlinked into /usr/local. OS X provides a uuid.h which conflicts with ossp-uuid's header. Generally there are no consequences of this for you. If you build your own software and it requires this formula, you'll need to add to your build variables: LDFLAGS: -L/usr/local/opt/ossp-uuid/lib CPPFLAGS: -I/usr/local/opt/ossp-uuid/include ==> Summary 🍺 /usr/local/Cellar/ossp-uuid/1.6.2: 15 files, 232K ==> Installing postgresql ==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/postgresql-9.3.2.mountain_lion.bottle.tar.gz ######################################################################## 100.0% ==> Pouring postgresql-9.3.2.mountain_lion.bottle.tar.gz ==> Caveats If builds of PostgreSQL 9 are failing and you have version 8.x installed, you may need to remove the previous version first. See: https://github.com/Homebrew/homebrew/issues/issue/2510 To migrate existing data from a previous major version (pre-9.3) of PostgreSQL, see: http://www.postgresql.org/docs/9.3/static/upgrading.html When installing the postgres gem, including ARCHFLAGS is recommended: ARCHFLAGS="-arch x86_64" gem install pg To install gems without sudo, see the Homebrew wiki. To have launchd start postgresql at login: ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents Then to load postgresql now: launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist Or, if you don't want/need launchctl, you can just run: postgres -D /usr/local/var/postgres ==> /usr/local/Cellar/postgresql/9.3.2/bin/initdb /usr/local/var/postgres -E utf8 ==> Summary 🍺 /usr/local/Cellar/postgresql/9.3.2: 2924 files, 40M
PostgreSQLを起動するためには、postgresコマンドに-Dオプションとデータを保存するディレクトリを指定して実行する。
$ postgres -D /usr/local/var/postgres LOG: database system was shut down at 2014-02-18 15:18:40 JST LOG: database system is ready to accept connections LOG: autovacuum launcher started
サーバを立ち上げただけでは、Railsアプリが使うDBが作られていないのでテストもできない。
RailsはテーブルをDBマイグレーションで作成できるが、DBまではさすがに作ってくれないので、自分で作る必要がある。
DBを作成するためには、PostgreSQLに付属しているcreatedbコマンドが使える。
そして、どのようなDBを作成するか?
ローカルで実行するのはdevelopment環境だけなので、それに対応したuiharu_developmentというデータベース名にする。
この名前は、config/database.ymlの内容と対応する。
$ createdb uiharu_development
pg
ActiveRecordをPostgreSQLと連携させるためには、それPostgreSQL用のドライバであるpgが必要である。
Gemfileに書くか、単にgemコマンドでインストールする。
$ gem install pg -- --with-pg-config=/usr/local/bin/pg_config Fetching: pg-0.17.1.gem (100%) Building native extensions with: '--with-pg-config=/usr/local/bin/pg_config' This could take a while... Successfully installed pg-0.17.1 invalid options: -f fivefish (invalid options are ignored) Parsing documentation for pg-0.17.1 Installing ri documentation for pg-0.17.1 Done installing documentation for pg after 1 seconds 1 gem installed
rails server
rails newで作成したひな形のアプリをとりあえず起動してみたい。
Railsには開発サーバがビルドインされているのでそれを使う。
$ rails server => Booting WEBrick => Rails 4.0.2 application starting in development on http://0.0.0.0:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server [2014-02-18 16:16:26] INFO WEBrick 1.3.1 [2014-02-18 16:16:26] INFO ruby 2.1.0 (2013-12-25) [x86_64-darwin12.0] [2014-02-18 16:16:26] INFO WEBrick::HTTPServer#start: pid=22896 port=3000
heroku create
このひな形は、すでにHerokuにデプロイできる状態になっている。
デプロイ先となるHerokuのappを作成する。
既にインストールしたHeroku Toolbeltに含まれるherokuコマンドを使って、コマンドラインからappを作成することができる。
$ heroku create Enter your Heroku credentials. Email: ykuoka@gmail.com Password (typing will be hidden): Creating mysterious-wave-3109... done, stack is cedar http://mysterious-wave-3109.herokuapp.com/ | git@heroku.com:mysterious-wave-3109.git Git remote heroku added
作成されたアプリの管理画面は以下のURLにある。
https://dashboard.heroku.com/apps/mysterious-wave-3109/resources
Herokuへデプロイ
appを作成したら、そのappに対応するgitレポジトリにソースをpushすることでデプロイできる。
デプロイするにあたって、gitレポジトリへはsshで接続する。そのとき公開鍵認証が使われるが、そのときに使う公開鍵をHerokuに教える必要がある。
そのためには、heroku keys:addコマンドを使う。
$ heroku keys:add ~/.ssh/id_rsa.pub Uploading SSH public key /Users/yusuke.kuoka/.ssh/id_rsa.pub... done
ここまで完了したら、Herokuへのデプロイが行える。
デプロイはgit pushでよい。
$ git push heroku master Initializing repository, done. Counting objects: 117, done. Delta compression using up to 4 threads. Compressing objects: 100% (97/97), done. Writing objects: 100% (117/117), 24.57 KiB | 0 bytes/s, done. Total 117 (delta 14), reused 0 (delta 0) -----> Ruby app detected -----> Compiling Ruby/Rails -----> Using Ruby version: ruby-2.1.0 -----> Installing dependencies using 1.5.2 Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment Fetching gem metadata from https://rubygems.org/.......... Fetching additional metadata from https://rubygems.org/.. Using minitest (4.7.5) Installing i18n (0.6.9) Installing multi_json (1.8.4) Installing rake (10.1.1) Installing builder (3.1.4) Installing erubis (2.7.0) Installing atomic (1.1.14) Installing polyglot (0.3.3) Installing mime-types (1.25.1) Installing rack (1.5.2) Installing tzinfo (0.3.38) Installing activerecord-deprecated_finders (1.0.3) Installing coffee-script-source (1.7.0) Installing arel (4.0.2) Using json (1.8.1) Installing execjs (2.0.2) Using bundler (1.5.2) Installing thor (0.18.1) Installing hike (1.2.3) Installing rails_serve_static_assets (0.0.2) Installing tilt (1.4.1) Installing rails_stdout_logging (0.0.3) Installing thread_safe (0.1.3) Installing rack-test (0.6.2) Installing sass (3.2.14) Installing treetop (1.4.15) Installing coffee-script (2.2.0) Installing uglifier (2.4.0) Installing sprockets (2.10.1) Installing rails_12factor (0.0.2) Installing rdoc (4.1.1) Installing mail (2.5.4) Installing activesupport (4.0.2) Installing sdoc (0.4.0) Installing activemodel (4.0.2) Installing jbuilder (1.5.3) Installing actionpack (4.0.2) Installing activerecord (4.0.2) Installing actionmailer (4.0.2) Installing sprockets-rails (2.0.1) Installing railties (4.0.2) Installing coffee-rails (4.0.1) Installing jquery-rails (3.1.0) Installing sass-rails (4.0.1) Installing turbolinks (2.2.1) Installing rails (4.0.2) Installing pg (0.17.1) Your bundle is complete! Gems in the groups development and test were not installed. It was installed into ./vendor/bundle Post-install message from rdoc: Depending on your version of ruby, you may need to install ruby rdoc/ri data: <= 1.8.6 : unsupported = 1.8.7 : gem install rdoc-data; rdoc-data --install = 1.9.1 : gem install rdoc-data; rdoc-data --install >= 1.9.2 : nothing to do! Yay! Bundle completed (25.62s) Cleaning up the bundler cache. -----> Writing config/database.yml to read from DATABASE_URL -----> Preparing app for Rails asset pipeline Running: rake assets:precompile I, [2014-02-18T07:37:28.794311 #1074] INFO -- : Writing /tmp/build_ee08872d-9d2e-4784-bbcb-49af3d88b173/public/assets/application-10b0a77d1cd631cfedc5334e0632bc3f.js I, [2014-02-18T07:37:28.842627 #1074] INFO -- : Writing /tmp/build_ee08872d-9d2e-4784-bbcb-49af3d88b173/public/assets/application-27fc57308d4ce798da2b90e9a09dad4f.css Asset precompilation completed (6.70s) Cleaning assets Running: rake assets:clean -----> Discovering process types Procfile declares types -> (none) Default types for Ruby -> console, rake, web, worker -----> Compressing... done, 22.1MB -----> Launching... done, v5 http://mysterious-wave-3109.herokuapp.com deployed to Heroku To git@heroku.com:mysterious-wave-3109.git * [new branch] master -> master
初回DBマイグレーション
「heroku run コマンド」でherokuのdyno上でコマンドを実行できる。
今回はrake db:migrateをdyno上で実行することで、dynoに割り当てられたDBのマイグレーションを行う。
dyno上でrakeを実行するので、dyno上にRakefileが存在しなければならない。いいかえれば、git push heroku masterによってRakefileが既にdyno上に設置されている必要がある。
$ heroku run rake db:migrate Running `rake db:migrate` attached to terminal... up, run.5914 Migrating to CreateTasks (20140218061028) == CreateTasks: migrating ==================================================== -- create_table(:tasks) -> 0.0101s == CreateTasks: migrated (0.0104s) ===========================================
実行
$ heroku ps:scale web=1 Scaling dynos... done, now running web at 1:1X.
/tasksにアクセスして以下のようなページが閲覧できればOK。
WebサーバとしてUnicornを使う
$ bundle install Fetching gem metadata from https://rubygems.org/......... Fetching additional metadata from https://rubygems.org/.. Resolving dependencies... Using rake (10.1.1) Using i18n (0.6.9) Using minitest (4.7.5) Using multi_json (1.8.4) Using atomic (1.1.14) Using thread_safe (0.1.3) Using tzinfo (0.3.38) Using activesupport (4.0.2) Using builder (3.1.4) Using erubis (2.7.0) Using rack (1.5.2) Using rack-test (0.6.2) Using actionpack (4.0.2) Using mime-types (1.25.1) Using polyglot (0.3.3) Using treetop (1.4.15) Using mail (2.5.4) Using actionmailer (4.0.2) Using activemodel (4.0.2) Using activerecord-deprecated_finders (1.0.3) Using arel (4.0.2) Using activerecord (4.0.2) Using bundler (1.5.3) Using coffee-script-source (1.7.0) Using execjs (2.0.2) Using coffee-script (2.2.0) Using thor (0.18.1) Using railties (4.0.2) Using coffee-rails (4.0.1) Using diff-lcs (1.2.5) Using hike (1.2.3) Using jbuilder (1.5.3) Using jquery-rails (3.1.0) Using json (1.8.1) Installing kgio (2.9.2) Using pg (0.17.1) Using tilt (1.4.1) Using sprockets (2.10.1) Using sprockets-rails (2.0.1) Using rails (4.0.2) Using rails_serve_static_assets (0.0.2) Using rails_stdout_logging (0.0.3) Using rails_12factor (0.0.2) Installing raindrops (0.12.0) Using rdoc (4.1.1) Using rspec-core (2.14.7) Using rspec-expectations (2.14.4) Using rspec-mocks (2.14.4) Using rspec-rails (2.14.0) Using sass (3.2.14) Using sass-rails (4.0.1) Using sdoc (0.4.0) Using turbolinks (2.2.1) Using uglifier (2.4.0) Installing unicorn (4.8.2) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. Bundler gave the error "Could not find kgio-2.9.2 in any of the sources" while processing "/Users/yusuke.kuoka/oss/uiharu/Gemfile". Perhaps you forgot to run "bundle install"? $ cat > config/unicorn.rb worker_processes Integer(ENV["WEB_CONCURRENCY"] || 3) timeout 15 preload_app true before_fork do |server, worker| Signal.trap 'TERM' do puts 'Unicorn master intercepting TERM and sending myself QUIT instead' Process.kill 'QUIT', Process.pid end defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect! end after_fork do |server, worker| Signal.trap 'TERM' do puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT' end defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection end ^C
unicornはbundle exec経由で以下のように起動する。
$ bundle exec unicorn -p 3000 -c ./config/unicorn.rb
このコマンドを実行してから、ブラウザでlocalhost:3000へアクセスできればOK。
Foremanを使う
Foremanを使ってUnicornでRailsアプリを起動できるようにする。
最終的にはこれを使ってHerokuでアプリを起動するため。
まず、以下のような内容のProcfileを作成する。
web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb
環境変数PORTや、RackのパラメータになるRACK_ENVをどうやって設定するのか?
それは、Foremanがデフォルトで利用する.envファイルに記述する。
$ cat > Procfile web: bundle exec unicorn -p $PORT -c ./config/unicorn.rb ^C $ cat > .env RACK_ENV=development PORT=3000 ^C
Herokuのdyno上ではこの.envファイルは不要なので、.gitignoreにも追加しておく。
$ echo .env >> .gitignore
Foremanはbundle経由で利用しない、プロジェクトとは直接関係ないライブラリなので、gemコマンドで直接インストールする。
Gemfileに書いたりしない。
$ gem install foreman Fetching: dotenv-0.9.0.gem (100%) Successfully installed dotenv-0.9.0 Fetching: foreman-0.63.0.gem (100%) Successfully installed foreman-0.63.0 Parsing documentation for dotenv-0.9.0 Installing ri documentation for dotenv-0.9.0 Parsing documentation for foreman-0.63.0 Installing ri documentation for foreman-0.63.0 Done installing documentation for dotenv, foreman after 0 seconds 2 gems installed
foreman gemに含まれるforemanコマンドを使ってProcfileに定義したRailsアプリを起動する。
$ foreman start 17:59:50 web.1 | started with pid 81264 17:59:51 web.1 | I, [2014-02-18T17:59:51.103899 #81264] INFO -- : Refreshing Gem list 17:59:52 web.1 | I, [2014-02-18T17:59:52.430294 #81264] INFO -- : listening on addr=0.0.0.0:3000 fd=10 17:59:52 web.1 | I, [2014-02-18T17:59:52.668409 #81264] INFO -- : master process ready 17:59:52 web.1 | I, [2014-02-18T17:59:52.675927 #81362] INFO -- : worker=1 ready 17:59:52 web.1 | I, [2014-02-18T17:59:52.676715 #81361] INFO -- : worker=0 ready 17:59:52 web.1 | I, [2014-02-18T17:59:52.678449 #81363] INFO -- : worker=2 ready
localhost:3000にブラウザでアクセスしてみて、200 OKなら成功。
このProcfileを使ってdyno上でアプリが起動できるか確認するため、Herokuにデプロイしてみる。
$ git push heroku master Fetching repository, done. Counting objects: 20, done. Delta compression using up to 4 threads. Compressing objects: 100% (14/14), done. Writing objects: 100% (14/14), 2.19 KiB | 0 bytes/s, done. Total 14 (delta 7), reused 0 (delta 0) -----> Ruby app detected -----> Compiling Ruby/Rails -----> Using Ruby version: ruby-2.1.0 -----> Installing dependencies using 1.5.2 Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment Fetching gem metadata from https://rubygems.org/.......... Fetching additional metadata from https://rubygems.org/.. Using minitest (4.7.5) Using multi_json (1.8.4) Using i18n (0.6.9) Using rake (10.1.1) Using atomic (1.1.14) Using tzinfo (0.3.38) Using erubis (2.7.0) Using rack (1.5.2) Using builder (3.1.4) Using mime-types (1.25.1) Using polyglot (0.3.3) Using activerecord-deprecated_finders (1.0.3) Using arel (4.0.2) Using coffee-script-source (1.7.0) Using thor (0.18.1) Using hike (1.2.3) Using json (1.8.1) Using execjs (2.0.2) Using pg (0.17.1) Using bundler (1.5.2) Using rails_serve_static_assets (0.0.2) Using tilt (1.4.1) Using rails_stdout_logging (0.0.3) Using thread_safe (0.1.3) Using sass (3.2.14) Using rack-test (0.6.2) Using rdoc (4.1.1) Using treetop (1.4.15) Using coffee-script (2.2.0) Using uglifier (2.4.0) Using sprockets (2.10.1) Using rails_12factor (0.0.2) Using activesupport (4.0.2) Using sdoc (0.4.0) Using mail (2.5.4) Using actionpack (4.0.2) Using jbuilder (1.5.3) Using activemodel (4.0.2) Using actionmailer (4.0.2) Using railties (4.0.2) Using sprockets-rails (2.0.1) Using activerecord (4.0.2) Using coffee-rails (4.0.1) Using jquery-rails (3.1.0) Using sass-rails (4.0.1) Using rails (4.0.2) Using turbolinks (2.2.1) Installing raindrops (0.12.0) Installing kgio (2.9.2) Installing unicorn (4.8.2) Your bundle is complete! Gems in the groups development and test were not installed. It was installed into ./vendor/bundle Bundle completed (21.65s) Cleaning up the bundler cache. -----> Writing config/database.yml to read from DATABASE_URL -----> Preparing app for Rails asset pipeline Running: rake assets:precompile Asset precompilation completed (1.62s) Cleaning assets Running: rake assets:clean -----> Discovering process types Procfile declares types -> web Default types for Ruby -> console, rake, worker -----> Compressing... done, 23.1MB -----> Launching... done, v6 http://mysterious-wave-3109.herokuapp.com deployed to Heroku To git@heroku.com:mysterious-wave-3109.git 98c3e32..cc76c93 master -> master
heroku psで確認してみて、先ほどProcfileに定義したコマンドでプロセスが起動していたら稼働確認としてはOK。
$ heroku ps === web (1X): `bundle exec unicorn -p $PORT -c ./config/unicorn.rb` web.1: up 2014/02/18 18:04:20 (~ 3m ago)
ブラウザでhttp://mysterious-wave-3109.herokuapp.com/tasksにアクセスして、200 OKなら正常性確認としてはOK。
bootstrap-sass導入
まずはGemfileにbootstrap-sass gemを追加する。
$ git diff diff --git a/Gemfile b/Gemfile index 0211bb5..88d8885 100644 --- a/Gemfile +++ b/Gemfile @@ -8,6 +8,8 @@ gem 'pg' # Use SCSS for stylesheets gem 'sass-rails', '~> 4.0.0' +gem 'bootstrap-sass', '~> 3.1.1' + # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0'
Bundlerでbootstrap-sassなどのgemをインストールする。
$ bundle install Fetching gem metadata from https://rubygems.org/......... Fetching additional metadata from https://rubygems.org/.. Resolving dependencies... Using rake (10.1.1) Using i18n (0.6.9) Using minitest (4.7.5) Using multi_json (1.8.4) Using atomic (1.1.14) Using thread_safe (0.1.3) Using tzinfo (0.3.38) Using activesupport (4.0.2) Using builder (3.1.4) Using erubis (2.7.0) Using rack (1.5.2) Using rack-test (0.6.2) Using actionpack (4.0.2) Using mime-types (1.25.1) Using polyglot (0.3.3) Using treetop (1.4.15) Using mail (2.5.4) Using actionmailer (4.0.2) Using activemodel (4.0.2) Using activerecord-deprecated_finders (1.0.3) Using arel (4.0.2) Using activerecord (4.0.2) Using sass (3.2.14) Installing bootstrap-sass (3.1.1.0) Using bundler (1.5.3) Using coffee-script-source (1.7.0) Using execjs (2.0.2) Using coffee-script (2.2.0) Using thor (0.18.1) Using railties (4.0.2) Using coffee-rails (4.0.1) Using diff-lcs (1.2.5) Using hike (1.2.3) Using jbuilder (1.5.3) Using jquery-rails (3.1.0) Using json (1.8.1) Using kgio (2.9.2) Using pg (0.17.1) Using tilt (1.4.1) Using sprockets (2.10.1) Using sprockets-rails (2.0.1) Using rails (4.0.2) Using rails_serve_static_assets (0.0.2) Using rails_stdout_logging (0.0.3) Using rails_12factor (0.0.2) Using raindrops (0.12.0) Using rdoc (4.1.1) Using rspec-core (2.14.7) Using rspec-expectations (2.14.4) Using rspec-mocks (2.14.4) Using rspec-rails (2.14.0) Using sass-rails (4.0.1) Using sdoc (0.4.0) Using turbolinks (2.2.1) Using uglifier (2.4.0) Using unicorn (4.8.2) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. Bundler gave the error "Could not find bootstrap-sass-3.1.1.0 in any of the sources" while processing "/Users/yusuke.kuoka/oss/uiharu/Gemfile". Perhaps you forgot to run "bundle install"?
開発サーバを起動して動作確認する。
$ rails server => Booting WEBrick => Rails 4.0.2 application starting in development on http://0.0.0.0:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server [2014-02-18 18:46:01] INFO WEBrick 1.3.1 [2014-02-18 18:46:01] INFO ruby 2.1.0 (2013-12-25) [x86_64-darwin12.0] [2014-02-18 18:46:01] INFO WEBrick::HTTPServer#start: pid=2811 port=3000
application.cssをapplication.css.scssに変更した上で@import 'bootstrap'を追加する。
そして、必要なテンプレートを編集したら、herokuへpushする。
$ git push heroku master Fetching repository, done. Counting objects: 26, done. Delta compression using up to 4 threads. Compressing objects: 100% (13/13), done. Writing objects: 100% (14/14), 1.52 KiB | 0 bytes/s, done. Total 14 (delta 9), reused 0 (delta 0) -----> Ruby app detected -----> Compiling Ruby/Rails -----> Using Ruby version: ruby-2.1.0 -----> Installing dependencies using 1.5.2 Running: bundle install --without development:test --path vendor/bundle --binstubs vendor/bundle/bin -j4 --deployment Fetching gem metadata from https://rubygems.org/.......... Fetching additional metadata from https://rubygems.org/.. Using minitest (4.7.5) Using atomic (1.1.14) Using tzinfo (0.3.38) Using multi_json (1.8.4) Using builder (3.1.4) Using i18n (0.6.9) Using erubis (2.7.0) Using rack (1.5.2) Using mime-types (1.25.1) Using polyglot (0.3.3) Using activerecord-deprecated_finders (1.0.3) Using arel (4.0.2) Using sass (3.2.14) Using coffee-script-source (1.7.0) Using execjs (2.0.2) Using thor (0.18.1) Using hike (1.2.3) Using json (1.8.1) Using pg (0.17.1) Using bundler (1.5.2) Using rake (10.1.1) Using kgio (2.9.2) Using tilt (1.4.1) Using rails_stdout_logging (0.0.3) Using rails_serve_static_assets (0.0.2) Using raindrops (0.12.0) Using thread_safe (0.1.3) Using rack-test (0.6.2) Using coffee-script (2.2.0) Using treetop (1.4.15) Using rdoc (4.1.1) Using uglifier (2.4.0) Using rails_12factor (0.0.2) Using unicorn (4.8.2) Using activesupport (4.0.2) Using mail (2.5.4) Using sprockets (2.10.1) Using activemodel (4.0.2) Using sdoc (0.4.0) Using actionpack (4.0.2) Using jbuilder (1.5.3) Using activerecord (4.0.2) Using railties (4.0.2) Using actionmailer (4.0.2) Using sprockets-rails (2.0.1) Using coffee-rails (4.0.1) Using sass-rails (4.0.1) Using jquery-rails (3.1.0) Using rails (4.0.2) Using turbolinks (2.2.1) Installing bootstrap-sass (3.1.1.0) Your bundle is complete! Gems in the groups development and test were not installed. It was installed into ./vendor/bundle Bundle completed (6.80s) Cleaning up the bundler cache. -----> Writing config/database.yml to read from DATABASE_URL -----> Preparing app for Rails asset pipeline Running: rake assets:precompile I, [2014-02-18T10:25:41.594562 #663] INFO -- : Writing /tmp/build_4d79d4fb-d142-47b2-a024-d0d2879eb44c/public/assets/application-8e34ec78f6b0ccf42b356db8b2d4eaaf.css I, [2014-02-18T10:25:41.599609 #663] INFO -- : Writing /tmp/build_4d79d4fb-d142-47b2-a024-d0d2879eb44c/public/assets/bootstrap/glyphicons-halflings-regular-9424bcf8f49d772c152e0b760b39b8f9.eot I, [2014-02-18T10:25:41.600117 #663] INFO -- : Writing /tmp/build_4d79d4fb-d142-47b2-a024-d0d2879eb44c/public/assets/bootstrap/glyphicons-halflings-regular-ab814146cdfc4d37cc90765f7bf86107.svg I, [2014-02-18T10:25:41.600607 #663] INFO -- : Writing /tmp/build_4d79d4fb-d142-47b2-a024-d0d2879eb44c/public/assets/bootstrap/glyphicons-halflings-regular-7531c2bd6e03c07cc2d83fa38e1e2218.ttf I, [2014-02-18T10:25:41.601070 #663] INFO -- : Writing /tmp/build_4d79d4fb-d142-47b2-a024-d0d2879eb44c/public/assets/bootstrap/glyphicons-halflings-regular-fcc658a3dec1be1cb0a9bb81f4c7c6de.woff Asset precompilation completed (4.45s) Cleaning assets Running: rake assets:clean -----> Discovering process types Procfile declares types -> web Default types for Ruby -> console, rake, worker -----> Compressing... done, 23.6MB -----> Launching... done, v7 http://mysterious-wave-3109.herokuapp.com deployed to Heroku To git@heroku.com:mysterious-wave-3109.git cc76c93..d4d6e26 master -> master
http://mysterious-wave-3109.herokuapp.com/tasksへアクセスして、bootstrapが適用されていれば成功。
Vagrant + Chef Solo + Berkshelf
$ vagrant box add precise64 http://files.vagrantup.com/precise64.box Downloading or copying the box... Extracting box...te: 1234k/s, Estimated time remaining: 0:00:01) Successfully added box 'precise64' with provider 'virtualbox'! $ vagrant box list | grep precise64 precise64 (virtualbox) $ rbenv local system # omnibus-ruby環境にBerkshelfをインストールするため、PATHの先頭にomnibus-rubyがきているとして、local systemで一時的にomnibus-rubyを優先する # さらに、omnibus-rubyはrootでインストールされているので、gem installにsudoが必要 $ sudo gem install berkshelf Password: Fetching: nio4r-1.0.0.gem (100%) Building native extensions. This could take a while... Fetching: ridley-1.5.3.gem (100%) Fetching: berkshelf-2.0.14.gem (100%) Fetching: hitimes-1.2.1.gem (100%) Building native extensions. This could take a while... Fetching: multi_json-1.8.4.gem (100%) Successfully installed nio4r-1.0.0 Successfully installed ridley-1.5.3 Successfully installed berkshelf-2.0.14 Successfully installed hitimes-1.2.1 Successfully installed multi_json-1.8.4 5 gems installed Installing ri documentation for nio4r-1.0.0... Installing ri documentation for ridley-1.5.3... Installing ri documentation for berkshelf-2.0.14... Installing ri documentation for hitimes-1.2.1... Installing ri documentation for multi_json-1.8.4... Installing RDoc documentation for nio4r-1.0.0... Installing RDoc documentation for ridley-1.5.3... Installing RDoc documentation for berkshelf-2.0.14... Installing RDoc documentation for hitimes-1.2.1... Installing RDoc documentation for multi_json-1.8.4... $ cat > Berksfile source "http://api.berkshelf.com" metadata cookbook 'nginx' cookbook 'apt' cookbook 'build-essential' cookbook 'rvm' ^C # Berkshelf 0.3系 $ berks vendor cookbooks # Berkshelf 0.2系(いいかえると、上記でvendorコマンドがないというエラーになるなら) $ berks install --path cookbooks Installing nginx (2.2.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Using apt (2.0.0) Installing build-essential (1.4.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing rvm (0.0.4) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing bluepill (2.3.1) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing rsyslog (1.10.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing ohai (1.1.12) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing runit (1.5.8) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing yum (3.1.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing yum-epel (0.3.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' $ vagrant up
vagrantのChef Solo ProvisionerはデフォルトでcookbooksディレクトリへCookbookを読み込みにいく。
そこで、Berkshelfで予めcookbooksディレクトリへCookbookをインストールしておく。
こうすることで、vagrant-berkshelfなどに依存しなくてもBerkshelfでCookbookを管理できる。
test-kitchenでVMのセットアップ
vagrant-berkshelfがdeprecateされるので、代替方法が必要。
berks installとVagrantのChef Solo Provisionerという方法もあるが、そのときberks installを手動で実行してからvagrant up/provisionを実行する、という手順がめんどう。
そこで、test-kitchenを使う。具体的には、test-kitchenでBerkshelfによるCookbookの解決とVMのセットアップとそこへのログインが可能なので、Vagrant + vagrant-berkshelf + chef-soloの代替として使う。
まず、kitchen initでtest-kitchenの基本的な設定ファイルを生成する。test-kitchenはBerkfileを置いておくとBerkshelfを呼び出してくれるため、Berksfileも設置する。このとき注意点として、「トラブルシューティング」の章で後述するとおり、Rails 4とBerkshelf 2系がそれぞれ異なるActiveSupportに依存していて併用できない(bundle installに失敗する)。そのためRails 4とtest-kitchenのプロジェクトは分割する。例えば、provisionディレクトリ以下にtest-kitchenプロジェクトを作成する場合以下のような手順となる。
$ mkdir provision $ cd provision $ touch Gemfile $ kitchen init identical .kitchen.yml append Gemfile append Gemfile You must run `bundle install' to fetch any new gems. $ cp ../Berksfile .
次に、test-kitchenの実行に必要なgemをインストールする。
kitchen initでGemfileが変更されたことからも推測できるように、すぐBundlerでインストールできる。
$ bundle install
bundle installで必要なgemがインストールされたら、test-kitchenを使いはじめることが出来る。
VMを用意してログインできるようにするだけ、Vagrantでいうとvagrant upに相当するところまで行いたい場合は、
kitchen setupを実行する。
$ kitchen setup -----> Starting Kitchen (v1.2.1) -----> Creating <default-precise64>... Bringing machine 'default' up with 'virtualbox' provider... [default] Importing base box 'precise64'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Fixed port collision for 22 => 2222. Now on port 2201. [default] Creating shared folders metadata... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2201 (adapter 1) [default] Running 'pre-boot' VM customizations... [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... [default] Machine booted and ready! [default] Setting hostname... [default] Mounting shared folders... Vagrant instance <default-precise64> created. Finished creating <default-precise64> (0m51.75s). -----> Converging <default-precise64>... Preparing files for transfer Resolving cookbook dependencies with Berkshelf 3.0.0.beta6... Removing non-cookbook files before transfer -----> Installing Chef Omnibus (true) downloading https://www.getchef.com/chef/install.sh to file /tmp/install.sh trying wget... Downloading Chef for ubuntu... downloading https://www.getchef.com/chef/metadata?v=&prerelease=false&p=ubuntu&pv=12.04&m=x86_64 to file /tmp/install.sh.1204/metadata.txt trying wget... url https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.10.2-1.ubuntu.12.04_amd64.deb md5 6758caf8e0e0f4c3c21490e4772668f9 sha256 8e767884eaec1169457500adbcd7ee5683f31ca6cbe4673a063419853c45d2d4 downloaded metadata file looks valid... downloading https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.10.2-1.ubuntu.12.04_amd64.deb to file /tmp/install.sh.1204/chef_11.10.2-1.ubuntu.12.04_amd64.deb trying wget... Checksum compare with sha256sum succeeded. Installing Chef installing with dpkg... Selecting previously unselected package chef. (Reading database ... (Reading database ... 51095 files and directories currently installed.) Unpacking chef (from .../chef_11.10.2-1.ubuntu.12.04_amd64.deb) ... Setting up chef (11.10.2-1.ubuntu.12.04) ... Thank you for installing Chef! Transfering files to <default-precise64> [2014-02-19T10:22:02+00:00] INFO: Forking chef instance to converge... Starting Chef Client, version 11.10.2 [2014-02-19T10:22:02+00:00] INFO: *** Chef 11.10.2 *** [2014-02-19T10:22:02+00:00] INFO: Chef-client pid: 1312 [2014-02-19T10:22:02+00:00] INFO: Setting the run_list to ["rvm::vagrant", "rvm::shystem", "rvm::gem_package", "nginx", "openssl", "postgresql::server", "database::postgresql"] from JSON [2014-02-19T10:22:02+00:00] INFO: Run List is [recipe[rvm::vagrant], recipe[rvm::shystem], recipe[rvm::gem_package], recipe[nginx], recipe[openssl], recipe[postgresql::server], recipe[database::postgresql]] [2014-02-19T10:22:02+00:00] INFO: Run List expands to [rvm::vagrant, rvm::shystem, rvm::gem_package, nginx, openssl, postgresql::server, database::postgresql] [2014-02-19T10:22:02+00:00] INFO: Starting Chef Run for default-precise64 [2014-02-19T10:22:02+00:00] INFO: Running start handlers [2014-02-19T10:22:02+00:00] INFO: Start handlers complete. Compiling Cookbooks... (略)
kitchen setupは最新版のChefをVM上にインストールしたうえで、Berkshelfを呼び出してBerksfileに書かれているCookbookをインストール、Chef Soloで適用する。
Cookbookの適用が完了してconvergeしたら、VMにログイン可能になる。
VMへのログインはkitchen loginコマンドで行える。これはVagrantでいうところのvagrant sshに相当する。
$ kitchen login
使い終わったVMは以下のコマンドで削除できる。
$ kitchen destroy -----> Starting Kitchen (v1.2.1) -----> Destroying <default-precise64>... [default] Forcing shutdown of VM... [default] Destroying VM and associated drives... Vagrant instance <default-precise64> destroyed. Finished destroying <default-precise64> (0m3.78s). -----> Kitchen is finished. (0m4.98s)
Signed Cookieの秘密鍵を変える
Railsでは、Signed Cookieの秘密鍵をconfig/initializers/secret_token.rbで設定する。
ところで、この秘密鍵は本番環境向けにはprivateにしておかなければならない。なぜなら、この秘密鍵が知られてしまうと、Signed Cookieを復号化することができてしまうため。
しかし、開発サーバではそのようなセキュリティを考える必要はないので、開発環境向けの秘密鍵はpublicでもよい。
ここで具体的には話をすると、rails newした時点では、開発環境・本番環境ともに同じ秘密鍵が使われる設定になっている。
それをpublicなレポジトリへgit pushしたら、秘密鍵をpublicにしたことになってしまう。この秘密鍵を本番環境でも使ってしまうのはまずい。
そのような場合におすすめなのは、環境変数経由で秘密鍵を上書きできるようにする方法である。
具体的には、secret_token.rbで以下のように環境変数で指定された秘密鍵を優先的に使うようにする。
そして、開発環境では環境変数を指定せずにデフォルトの秘密鍵を使ってよいことにする。
Uiharu::Application.config.secret_key_base = ENV['SECRET_KEY_BASE'] || 'd45a23217a423ad16f79aed216db06da88e1a9ca90d9d722518a4bd31e5c6db63bd25948339695dfa8a54a98d7094b78847fcc8434ab1201aa26b662a26930da'
Heroku上で環境変数経由でこの秘密鍵を設定するためには、以下のようにする。rake secretコマンドで新しい秘密鍵を生成できるので、それを応用する。
$ heroku config:set SECRET_KEY_BASE=`rake secret` Setting config vars and restarting mysterious-wave-3109... done, v8 SECRET_KEY_BASE: 本番環境で使う秘密鍵(secret_token.rbで設定されている開発環境向けの秘密鍵とは別で、Heroku以外からは見えないprivateなもの)
プロトタイピング
Fluid UIでプロトタイピングする。
https://www.fluidui.com/editor/live/
https://www.fluidui.com/editor/live/preview/p_Br1ZwPQHw2I0auUIV0VIIlHOmmkl3Iya.1392713479992
トラブルシューティング
Ruby on Rails
InvalidAuthenticityToken
CSRF対策のAuthenticityTokenがついていない、書き換えられているなどの理由で検証に失敗したことを表すエラー。
もしCSRF対策が不要なアクションなのであれば、以下のようにコントローラ単位でAuthenticityTokenの検証をオフにできる。
class SessionsController < ApplicationController skip_before_filter :verify_authenticity_token
参考: https://github.com/intridea/omniauth/issues/237
DBが存在しない
たとえば、DBが存在しないのにrake db:migrateを実行した場合や、
$ rake db:migrate rake aborted! FATAL: database "uiharu_development" does not exist Tasks: TOP => db:migrate (See full trace by running task with --trace)
rails serverで起動したサーバへアクセスした場合に発生する。
この場合、単にDBを作成すればよい。
$ createdb uiharu_development
PostgreSQL: Documentation: 8.1: Creating a Database
DB作成後にdb:migrateを実行すると、以下のように成功する。
$ rake db:migrate == CreateTasks: migrating ==================================================== -- create_table(:tasks) -> 0.0056s == CreateTasks: migrated (0.0057s) ===========================================
同様にDB作成後にrails server起動後、localhost:3000/tasksにアクセスするとページにアクセスできる。
$ rails server => Booting WEBrick => Rails 4.0.2 application starting in development on http://0.0.0.0:3000 => Run `rails server -h` for more startup options => Ctrl-C to shutdown server [2014-02-18 16:54:50] INFO WEBrick 1.3.1 [2014-02-18 16:54:50] INFO ruby 2.1.0 (2013-12-25) [x86_64-darwin12.0] [2014-02-18 16:54:50] INFO WEBrick::HTTPServer#start: pid=46115 port=3000 Started GET "/tasks" for 127.0.0.1 at 2014-02-18 16:55:02 +0900 ActiveRecord::SchemaMigration Load (0.4ms) SELECT "schema_migrations".* FROM "schema_migrations" Processing by TasksController#index as HTML Task Load (0.5ms) SELECT "tasks".* FROM "tasks" Rendered tasks/index.html.erb within layouts/application (4.1ms) Completed 200 OK in 641ms (Views: 627.4ms | ActiveRecord: 0.5ms) Started GET "/assets/scaffolds.css?body=1" for 127.0.0.1 at 2014-02-18 16:55:03 +0900
rails_serve_static_assetsがみつからないというエラーが出る
Bundler gave the error "Could not find rails_serve_static_assets-0.0.2 in any of the sources" while processing "/Users/yusuke.kuoka/oss/uiharu/Gemfile". Perhaps you forgot to run "bundle install"?
このようなエラーがでたとしても、以下のようにインストールに成功しているのであれば問題ない。
$ bundle install Using rake (10.1.1) Using i18n (0.6.9) Using minitest (4.7.5) Using multi_json (1.8.4) Using atomic (1.1.14) Using thread_safe (0.1.3) Using tzinfo (0.3.38) Using activesupport (4.0.2) Using builder (3.1.4) Using erubis (2.7.0) Using rack (1.5.2) Using rack-test (0.6.2) Using actionpack (4.0.2) Using mime-types (1.25.1) Using polyglot (0.3.3) Using treetop (1.4.15) Using mail (2.5.4) Using actionmailer (4.0.2) Using activemodel (4.0.2) Using activerecord-deprecated_finders (1.0.3) Using arel (4.0.2) Using activerecord (4.0.2) Using coffee-script-source (1.7.0) Using execjs (2.0.2) Using coffee-script (2.2.0) Using thor (0.18.1) Using railties (4.0.2) Using coffee-rails (4.0.1) Using diff-lcs (1.2.5) Using hike (1.2.3) Using jbuilder (1.5.3) Using jquery-rails (3.1.0) Using json (1.8.1) Using pg (0.17.1) Using bundler (1.5.3) Using tilt (1.4.1) Using sprockets (2.10.1) Using sprockets-rails (2.0.1) Using rails (4.0.2) Using rails_serve_static_assets (0.0.2) Using rails_stdout_logging (0.0.3) Using rails_12factor (0.0.2) Using rdoc (4.1.1) Using rspec-core (2.14.7) Using rspec-expectations (2.14.4) Using rspec-mocks (2.14.4) Using rspec-rails (2.14.0) Using sass (3.2.14) Using sass-rails (4.0.1) Using sdoc (0.4.0) Using turbolinks (2.2.1) Using uglifier (2.4.0) Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed. Bundler gave the error "Could not find rails_serve_static_assets-0.0.2 in any of the sources" while processing "/Users/yusuke.kuoka/oss/uiharu/Gemfile". Perhaps you forgot to run "bundle install"?
rake testするとschema.rbが無いというエラーになる
エラー内容どおり、rake db:migrateを実行すれば解消される。
$ rake test /Users/yusuke.kuoka/oss/uiharu/db/schema.rb doesn't exist yet. Run `rake db:migrate` to create it, then try again. If you do not intend to use a database, you should instead alter /Users/yusuke.kuoka/oss/uiharu/config/application.rb to limit the frameworks that will be loaded.
Heroku + Rails
Rakefileが存在しないというエラーがでる
git push heroku masterし忘れいているとこうなる。
$ heroku rake db:migrate WARNING: `heroku rake` has been deprecated. Please use `heroku run rake` instead. Running `rake db:migrate` attached to terminal... up, run.4134 rake aborted! No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb) /usr/local/lib/ruby/1.9.1/rake.rb:2367:in `raw_load_rakefile' /usr/local/lib/ruby/1.9.1/rake.rb:2007:in `block in load_rakefile' /usr/local/lib/ruby/1.9.1/rake.rb:2058:in `standard_exception_handling' /usr/local/lib/ruby/1.9.1/rake.rb:2006:in `load_rakefile' /usr/local/lib/ruby/1.9.1/rake.rb:1991:in `run' /usr/local/bin/rake:31:in `<main>'
$ heroku run rake db:migrate Running `rake db:migrate` attached to terminal... up, run.3109 rake aborted! No Rakefile found (looking for: rakefile, Rakefile, rakefile.rb, Rakefile.rb) /usr/local/lib/ruby/1.9.1/rake.rb:2367:in `raw_load_rakefile' /usr/local/lib/ruby/1.9.1/rake.rb:2007:in `block in load_rakefile' /usr/local/lib/ruby/1.9.1/rake.rb:2058:in `standard_exception_handling' /usr/local/lib/ruby/1.9.1/rake.rb:2006:in `load_rakefile' /usr/local/lib/ruby/1.9.1/rake.rb:1991:in `run' /usr/local/bin/rake:31:in `<main>'
Herokuにアクセスすると「そんなページは存在しない」というエラーになる
プロセスを起動していないか、そのようなルートが存在しない場合にこうなる。
vagrant provision時にChef SoloがNameErrorになる
$ vagrant up Bringing machine 'default' up with 'virtualbox' provider... [default] Importing base box 'precise64'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Creating shared folders metadata... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] -- 3000 => 30000 (adapter 1) [default] Running 'pre-boot' VM customizations... [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... [default] Machine booted and ready! [default] Configuring and enabling network interfaces... [default] Mounting shared folders... [default] -- /uiharu [default] -- /vagrant [default] -- /tmp/vagrant-chef-1/chef-solo-1/cookbooks [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo... stdin: is not a tty [2014-02-19T01:20:15+00:00] INFO: *** Chef 10.14.2 *** [2014-02-19T01:20:15+00:00] INFO: Setting the run_list to ["recipe[nginx]"] from JSON [2014-02-19T01:20:15+00:00] INFO: Run List is [recipe[nginx]] [2014-02-19T01:20:15+00:00] INFO: Run List expands to [nginx] [2014-02-19T01:20:15+00:00] INFO: Starting Chef Run for precise64 [2014-02-19T01:20:15+00:00] INFO: Running start handlers [2014-02-19T01:20:15+00:00] INFO: Start handlers complete. ================================================================================ Recipe Compile Error in /tmp/vagrant-chef-1/chef-solo-1/cookbooks/apt/providers/repository.rb ================================================================================ NameError --------- undefined local variable or method `use_inline_resources' for #<Class:0x7ff15cfbb0f8> Cookbook Trace: --------------- /tmp/vagrant-chef-1/chef-solo-1/cookbooks/apt/providers/repository.rb:20:in `class_from_file' Relevant File Content: ---------------------- /tmp/vagrant-chef-1/chef-solo-1/cookbooks/apt/providers/repository.rb: 1: # 2: # Cookbook Name:: apt 3: # Provider:: repository 4: # 5: # Copyright 2010-2011, Opscode, Inc. 6: # 7: # Licensed under the Apache License, Version 2.0 (the "License"); 8: # you may not use this file except in compliance with the License. 9: # You may obtain a copy of the License at [2014-02-19T01:20:15+00:00] ERROR: Running exception handlers [2014-02-19T01:20:15+00:00] ERROR: Exception handlers complete [2014-02-19T01:20:15+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out [2014-02-19T01:20:15+00:00] FATAL: NameError: undefined local variable or method `use_inline_resources' for #<Class:0x7ff15cfbb0f8> Chef never successfully completed! Any errors should be visible in the output above. Please fix your recipes so that they properly complete.
エラーの内容は「NameError: undefined local variable or method `use_inline_resources' for #<Class:0x7ff15cfbb0f8>」であり、かつ
「[2014-02-19T01:20:15+00:00] INFO: *** Chef 10.14.2 ***」とあるように、Vagrant上でchef 10系が実行されている。
これは、ark cookbookなどについて報告されているとおり、Vagrantで起動した仮想マシンにインストールされているものより新しいChefを要求するレシピを使っていることが原因である。
したがって、Cookbookを旧バージョンに下げるか、もしくは仮想マシン内に新しいバージョンのChefをインストールすることで解決される。
vagrant provision時にshell provisionerがapt-get installに失敗する
本質的にはVagrantには関係ないのだが、Vagrantfileをコピペしたりするとある日突然なることもあるため。
例えば以下のような実行結果を考える。
The following SSH command responded with a non-zero exit status. Vagrant assumes that this means the command failed! chmod +x /tmp/vagrant-shell && /tmp/vagrant-shell Stdout from the command: Reading package lists... Building dependency tree... Reading state information... The following extra packages will be installed: dpkg-dev fakeroot g++ g++-4.6 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libdpkg-perl libruby1.9.1 libstdc++6-4.6-dev libyaml-0-2 make patch ruby1.9.1 Suggested packages: debian-keyring g++-multilib g++-4.6-multilib gcc-4.6-doc libstdc++6-4.6-dbg libstdc++6-4.6-doc make-doc diffutils-doc ruby1.9.1-examples ri1.9.1 graphviz The following NEW packages will be installed: build-essential dpkg-dev fakeroot g++ g++-4.6 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libdpkg-perl libruby1.9.1 libstdc++6-4.6-dev libyaml-0-2 make patch ruby1.9.1 ruby1.9.1-dev 0 upgraded, 16 newly installed, 0 to remove and 66 not upgraded. Need to get 15.0 MB of archives. After this operation, 45.9 MB of additional disk space will be used. Get:1 http://us.archive.ubuntu.com/ubuntu/ precise/main libyaml-0-2 amd64 0.1.4-2 [56.9 kB] Get:2 http://us.archive.ubuntu.com/ubuntu/ precise/main libstdc++6-4.6-dev amd64 4.6.3-1ubuntu5 [1,660 kB] Get:3 http://us.archive.ubuntu.com/ubuntu/ precise/main g++-4.6 amd64 4.6.3-1ubuntu5 [6,954 kB] Get:4 http://us.archive.ubuntu.com/ubuntu/ precise/main g++ amd64 4:4.6.3-1ubuntu5 [1,442 B] Get:5 http://us.archive.ubuntu.com/ubuntu/ precise/main make amd64 3.81-8.1ubuntu1 [118 kB] Get:6 http://us.archive.ubuntu.com/ubuntu/ precise/main libdpkg-perl all 1.16.1.2ubuntu7 [181 kB] Get:7 http://us.archive.ubuntu.com/ubuntu/ precise/main patch amd64 2.6.1-3 [80.2 kB] Get:8 http://us.archive.ubuntu.com/ubuntu/ precise/main dpkg-dev all 1.16.1.2ubuntu7 [468 kB] Get:9 http://us.archive.ubuntu.com/ubuntu/ precise-updates/main build-essential amd64 11.5ubuntu2.1 [5,816 B] Get:10 http://us.archive.ubuntu.com/ubuntu/ precise/main fakeroot amd64 1.18.2-1 [87.2 kB] Get:11 http://us.archive.ubuntu.com/ubuntu/ precise/main libalgorithm-diff-perl all 1.19.02-2 [50.7 kB] Get:12 http://us.archive.ubuntu.com/ubuntu/ precise/main libalgorithm-diff-xs-perl amd64 0.04-2build2 [12.4 kB] Get:13 http://us.archive.ubuntu.com/ubuntu/ precise/main libalgorithm-merge-perl all 0.08-2 [12.7 kB] Err http://us.archive.ubuntu.com/ubuntu/ precise-updates/main libruby1.9.1 amd64 1.9.3.0-1ubuntu2 404 Not Found [IP: 91.189.91.15 80] Err http://us.archive.ubuntu.com/ubuntu/ precise-updates/main ruby1.9.1 amd64 1.9.3.0-1ubuntu2 404 Not Found [IP: 91.189.91.15 80] Err http://us.archive.ubuntu.com/ubuntu/ precise-updates/main ruby1.9.1-dev amd64 1.9.3.0-1ubuntu2 404 Not Found [IP: 91.189.91.15 80] Fetched 9,688 kB in 28s (337 kB/s) Stderr from the command: stdin: is not a tty Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/r/ruby1.9.1/libruby1.9.1_1.9.3.0-1ubuntu2_amd64.deb 404 Not Found [IP: 91.189.91.15 80] Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/r/ruby1.9.1/ruby1.9.1_1.9.3.0-1ubuntu2_amd64.deb 404 Not Found [IP: 91.189.91.15 80] Failed to fetch http://us.archive.ubuntu.com/ubuntu/pool/main/r/ruby1.9.1/ruby1.9.1-dev_1.9.3.0-1ubuntu2_amd64.deb 404 Not Found [IP: 91.189.91.15 80] E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?
これは、apt-get installが出力したエラーメッセージ「E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?」にもあるとおり、apt-get updateしていないためpackage index fileが更新されておらず、パッケージの配布場所の変更に追従できていないことが原因。apt-get update後にapt-get installするようにプロビジョニング手順を変更すれば解決される。
berks installでgithub: 'url'が無視される
Issueで報告されているとおり、Berkfile.lockを削除する。
例えば、
cookbook 'rvm'
というBerksfileでberks installしたあと、Berksfile.lockを削除せずにBerksfileを
coobook 'rvm' github: 'fnichol/chef-rvm'
のように変更してからberks installしたとしても、rvm cookbookはGitHubからインストールされない。
このときberks installのログでは以下のように「Using <cookbook名> (バージョン)」というメッセージが出力されている。
$ berks install --path cookbooks (略) Using rvm (0.0.4) (略)
理由は、Berksfile.lockにrvmという名前のcookbookの情報がキャッシュされてしまっているから。
Berksfile.lockを削除すれば、GitHubから改めてインストールされる。実際やってみると以下のようになる。
$ rm Berksfile.lock $ berks install --path cookbooks (略) Installing rvm (0.9.1) from github: 'fnichol/chef-rvm' with branch: 'master' over protocol: 'git' (略)
「Installing rvm (バージョン) from github」というメッセージが出力されているとおり、GitHubからインストールされる。
fnichol/chef-rvm cookbookでwarnメッセージが出力される
しかし、Chefの実行自体は成功している、というケース。
Issue報告されているとおり、実害はない。2014/02/19時点では修正のマージ待ちというステータス。
[2014-02-19T03:14:50+00:00] INFO: rvm_ruby[ruby-2.1.0-p0] build time was 1.7967338131166666 minutes. [2014-02-19T03:14:50+00:00] INFO: Setting default ruby to rvm_ruby[ruby-2.1.0-p0] /tmp/vagrant-chef-1/chef-solo-1/cookbooks/rvm/libraries/rvm_chef_user_environment.rb:32: warning: class variable access from toplevel /tmp/vagrant-chef-1/chef-solo-1/cookbooks/rvm/libraries/rvm_chef_user_environment.rb:32: warning: class variable access from toplevel [2014-02-19T03:14:52+00:00] INFO: package[libxslt-dev] is a virtual package, actually acting on package[libxslt1-dev] [2014-02-19T03:14:52+00:00] INFO: package[ncurses-dev] is a virtual package, actually acting on package[libncurses5-dev] /tmp/vagrant-chef-1/chef-solo-1/cookbooks/rvm/libraries/rvm_chef_user_environment.rb:32: warning: class variable access from toplevel [2014-02-19T03:14:55+00:00] INFO: bash[assign-postgres-password] ran successfully [2014-02-19T03:14:55+00:00] INFO: Chef Run complete in 155.045877365 seconds [2014-02-19T03:14:55+00:00] INFO: Running report handlers [2014-02-19T03:14:55+00:00] INFO: Report handlers complete
Rails 4 + Berkshelf 2.xでbundle installに失敗する件
以下のようなGemfileがあるとき
gem 'rails', '4.0.2' gem 'berkshelf', '~> 2.0.13'
bundle installに失敗する。
$ kitchen setup -----> Starting Kitchen (v1.2.1) D, [2014-02-19T18:54:51.804768 #30893] DEBUG -- : Shutdown completed cleanly /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/faraday-0.9.0/lib/faraday.rb:99:in `method_missing': undefined method `register_middleware' for #<Faraday::Connection:0x007fc4c1bfd050> (NoMethodError) from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley/middleware/chef_auth.rb:90:in `<top (required)>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley/middleware.rb:9:in `require_relative' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley/middleware.rb:9:in `block in <top (required)>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley/middleware.rb:8:in `each' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley/middleware.rb:8:in `<top (required)>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley.rb:56:in `require_relative' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley.rb:56:in `<module:Ridley>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/ridley-1.2.6/lib/ridley.rb:13:in `<top (required)>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/berkshelf-2.0.5/lib/berkshelf.rb:10:in `<top (required)>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `require' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/provisioner/chef/berkshelf.rb:67:in `load_berkshelf!' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/provisioner/chef/berkshelf.rb:43:in `load!' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/provisioner/chef_base.rb:135:in `load_needed_dependencies!' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/provisioner/base.rb:44:in `instance=' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/instance.rb:240:in `setup_provisioner' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/instance.rb:93:in `initialize' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:128:in `new' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:128:in `new_instance' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:73:in `block in build_instances' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:72:in `map' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:72:in `with_index' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:72:in `build_instances' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/config.rb:52:in `instances' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/command.rb:64:in `get_filtered_instances' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/command.rb:85:in `parse_subcommand' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/command/action.rb:37:in `block in call' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/2.1.0/benchmark.rb:279:in `measure' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/command/action.rb:36:in `call' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/cli.rb:47:in `perform' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/cli.rb:118:in `block (2 levels) in <class:CLI>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor/command.rb:27:in `run' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor/invocation.rb:120:in `invoke_command' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/cli.rb:233:in `invoke_task' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor.rb:363:in `dispatch' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/thor-0.18.1/lib/thor/base.rb:439:in `start' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/bin/kitchen:13:in `block in <top (required)>' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/lib/kitchen/errors.rb:81:in `with_friendly_errors' from /Users/yusuke.kuoka/.rbenv/versions/2.1.0/lib/ruby/gems/2.1.0/gems/test-kitchen-1.2.1/bin/kitchen:13:in `<top (required)>' from /opt/chef/embedded/bin/kitchen:23:in `load' from /opt/chef/embedded/bin/kitchen:23:in `<main>'
原因は、Berkshelf 2.xがActiveSupport 3系に依存していて、それがRails 4のActiveSupport 4依存と競合してしまうため。
Berkshelf 3系はActiveSupportに依存していないので、Berkshelf 3系を使う・・という手段も考えられるが、実際にはRailsと組み合わせた場合に限りtest-kitchenがBerkshelfの呼び出し時にエラーとなってしまうため不可能。Railsプロジェクトとtest-kichenプロジェクトを分割することで解決できる。
Rails4とBerkshelf 3系(2014/02/19時点の最新版である3.0.0.beta6)とtest-kitchenを組み合わせた場合のログは以下のとおり。NoSolutionErrorというエラーでconvergeに失敗している。
$ kitchen setup -----> Starting Kitchen (v1.2.1) -----> Converging <default-precise64>... Preparing files for transfer Resolving cookbook dependencies with Berkshelf 3.0.0.beta6... >>>>>> ------Exception------- >>>>>> Class: Kitchen::ActionFailed >>>>>> Message: Failed to complete #converge action: [Berkshelf::NoSolutionError] >>>>>> ---------------------- >>>>>> Please see .kitchen/logs/kitchen.log for more details >>>>>> Also try running `kitchen diagnose --all` for configuration
一方、Rails4プロジェクトとtest-kitchenプロジェクトを分けた場合、Berkshelf3 + test-kitchenのログは以下のとおり。Berkshelf 3.0.0.beta6によるCookbookの解決が成功していることがわかる。
$ kitchen setup -----> Starting Kitchen (v1.2.1) -----> Creating <default-precise64>... Bringing machine 'default' up with 'virtualbox' provider... [default] Importing base box 'precise64'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Creating shared folders metadata... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] Running 'pre-boot' VM customizations... [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... [default] Machine booted and ready! [default] Setting hostname... [default] Configuring and enabling network interfaces... [default] Mounting shared folders... Vagrant instance <default-precise64> created. Finished creating <default-precise64> (0m46.05s). -----> Converging <default-precise64>... Preparing files for transfer Resolving cookbook dependencies with Berkshelf 3.0.0.beta6... Removing non-cookbook files before transfer -----> Installing Chef Omnibus (true) (略)
ソースコード
GitHubで公開しています。
https://github.com/mumoshu/uiharu
参考
- Snir David : How to install nginx with passenger using chef
- Chef Solo - Provisioning - Vagrant Documentation
- Vagrant tutorial
- Getting Started Writing Chef Cookbooks the Berkshelf Way, Part 3 - Mischa Taylor's Coding Blog