rails.md 3.76 KB

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 for managing secrets

A typical Rails app that uses things like MySQL, Resque, and phantomjs might have a project definition like so:

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 into the nginx config dir

It won't necessarily do all of them in that order, but it will guarantee 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

# 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

# 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

# config/initializers/redis.rb

$redis = Redis.new(ENV['BOXEN_REDIS_URL'] || 'redis://localhost:6379/')

Elasticsearch

# config/initializers/elasticsearch.rb

Tire.configure do
  url (ENV['BOXEN_ELASTICSEARCH_URL'] || 'http://localhost:9200/')
end

MongoDB

# 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

# config/initializers/memcached.rb

$memcached = Dalli::Client.new(
  ENV['BOXEN_MEMCACHED_URL'] || 'memcached://localhost:11211/'
)

Unicorn

# 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
# 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