# Using Boxen with Rails Projects Boxen is designed to work extremely well with Rails. Let's break down some of the basics: ## Project Management We make a few assumptions about how you run Rails in development for ease and consistency: * You use a web server that listens on a socket * You use environment variables and something like [dotenv](https://github.com/bkeepers/dotenv) for managing secrets A typical Rails app that uses things like MySQL, Resque, and phantomjs might have a [project definition](../modules/projects/README.md) like so: ``` puppet class projects::rails_app { include phantomjs boxen::project { 'rails_app': ruby => '1.9.3', mysql => true, redis => true, nginx => true, source => 'username/rails_app' } } ``` This does a few things for you: * Clones `https://github.com/mycompany/rails_app.git` to `~/src/rails_app` * Ensures the default 1.9.3 version of Ruby is installed * Creates `~/src/rails_app/.ruby-version` with `1.9.3` in it * Ensures mysql is installed and running * Creates two mysql databases: `rails_app_test` and `rails_app_development` * Ensures redis is installed and running * Ensures nginx is installed and running * Copies the [template nginx config](../modules/projects/templates/shared/nginx.conf.erb) into the nginx config dir It won't necessarily do all of them in that order, but it will gaurantee that if they run successfully they're all done in a correct order. See the section below for some handy configuration tips on how to configure your app best to work with Boxen. ## Configuration ### MySQL ``` yaml # config/database.yml <% def boxen?; ENV['BOXEN_HOME']; end socket = [ ENV["BOXEN_MYSQL_SOCKET"], "/var/run/mysql5/mysqld.sock", "/tmp/mysql.sock" ].compact.detect { |f| File.exist? f } port = ENV["BOXEN_MYSQL_PORT"] || "3306" %> development: adapter: mysql2 database: rails_app_development username: root password: <% if socket %> host: localhost socket: <%= socket %> <% else %> host: 127.0.0.1 port: <%= port %> <% end %> test: adapter: mysql2 database: rails_app_test username: root password: <% if socket %> host: localhost socket: <%= socket %> <% else %> host: 127.0.0.1 port: <%= port %> <% end %> ``` ### PostgreSQL ``` yaml # config/database.yml development: adapter: postgresql database: rails_app_development encoding: unicode port: <%= ENV["BOXEN_POSTGRESQL_PORT"] || 5432 %> host: localhost test: adapter: postgresql database: rails_app_test encoding: unicode port: <%= ENV["BOXEN_POSTGRESQL_PORT"] || 5432 %> host: localhost ``` ### Redis ``` ruby # config/initializers/redis.rb $redis = Redis.new(ENV['BOXEN_REDIS_URL'] || 'redis://localhost:6379/') ``` ### Elasticsearch ``` ruby # config/initializers/elasticsearch.rb Tire.configure do url (ENV['BOXEN_ELASTICSEARCH_URL'] || 'http://localhost:9200/') end ``` ### MongoDB ``` yaml # config/mongo.yml development: host: 127.0.0.1 port: <%= ENV['BOXEN_MONGODB_PORT'] || 27017 %> database: rails_app_development test: host: 127.0.0.1 port: <%= ENV['BOXEN_MONGODB_PORT'] || 27017 %> database: rails_app_test ``` ### Memcached ``` ruby # config/initializers/memcached.rb $memcached = Dalli::Client.new( ENV['BOXEN_MEMCACHED_URL'] || 'memcached://localhost:11211/' ) ``` ### Unicorn ``` ruby # config/unicorn.rb if ENV['RACK_ENV'] == 'development' worker_processes 1 listen "#{ENV['BOXEN_SOCKET_DIR']}/rails_app", :backlog => 1024 timeout 120 end after_fork do |server, worker| ActiveRecord::Base.establish_connection if defined?(ActiveRecord) end ``` ``` shell # script/server #!/bin/sh set -e cd $(dirname "$0")/.. : ${RAILS_ENV:=development} : ${RACK_ENV:=development} export RAILS_ENV RACK_ENV bin/unicorn_rails -E "$RAILS_ENV" -c config/unicorn.rb ```