To start you need a VPS to which you can connect through ssh. Assume we have one and we can connect to it via:
$ ssh vps.com
Domain name is also required as we want to serve apps using subdomains.
Let's say we have a vps.com
domain pointed to our VPS IP address.
VPS needs ruby, nginx, unicorn and all the staff to run RoR apps. chef-solo will help us with installation of the tools.
First we need to create a node for our VPS under the nodes/
directory. Node will run 3 roles:
- bootstrap (setting up locale, install nodejs, rbenv).
- web (nginx)
- database (postgresql)
# nodes/vps.com.json
{
"run_list": [
"role[bootstrap]",
"role[web]",
"role[database]"
]
}
Install gems before you start cooking VPS ($ gem install bundler
if you don't have it yet):
$ bundle install
You can fetch cookbooks if you want:
$ librarian-chef install
To prepare&cook vps run:
knife solo bootstrap vps
For sure you have a great RoR app and you cannot wait any longer to show your application to the world. Let's do this!
Create a role
for app (name can be the same as application name) which runs "rails_app" recipe:
# roles/example_app.json
{
"json_class": "Chef::Role",
"run_list": [
"recipe[rails_app]"
],
"override_attributes": {
"app_name": "example_app",
"authorized_keys": [
"ssh-rsa AsadsadsecretZZZ [email protected]",
"ssh-rsa AsadsadsecretZZZ [email protected]",
"ssh-rsa BsadsadsecretZZZ [email protected]"
]
}
}
Application will be available under subdomain, in this case: http://example_app.vps.com
.
In addition to the created role still need a node to run application role:
# nodes/example_app.vps.com.json
{
"run_list": [
"role[example_app]"
]
}
To cook this node you need ssh config for example_app.vps.com
for example:
Host example_app.vps.com
HostName vps.com
User example_app
ForwardAgent yes
IdentityFile ~/.ssh/me_rsa
Cook application node as a root user
knife solo cook root@example_app.com.vps
VPS is ready to go, all thats left is to deploy RoR application source code via Capistrano.
Add capistrano
and unicorn
gems to Gemfile
:
# Gemfile
gem 'capistrano', '3.2.1'
gem 'capistrano-rails'
gem 'capistrano-rbenv', '~> 2.0'
group :production do
gem 'unicorn', '4.8.3'
end
Next bundle new gems:
$ bundle install
Create file Capfile
into application root folder:
# Capfile
require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
Create config/deploy.rb
file:
# config/deploy.rb
lock '3.2.1'
set :application, 'example_app'
set :repo_url, '[email protected]:username/example_app.git'
set :rbenv_custom_path, '/usr/local/rbenv'
set :rbenv_ruby, '2.1.5'
set :pty, true
set :sudo_prompt, ""
set :linked_files, %w{
config/database.yml
config/nginx.production.conf
config/secrets.yml
config/unicorn.rb
config/unicorn_init.sh
}
set :linked_dirs, %w{ tmp log }
set :scm, :git
set :tmp_dir, "/home/#{fetch(:application)}/tmp"
namespace :deploy do
%w{start stop restart}.each do |command|
desc "#{command} unicorn server"
task command do
on roles(:app) do
execute "service unicorn_#{fetch(:application)} #{command}"
end
end
end
after :finishing, :restart
end
and create a production deployment config file:
# config/deploy/production.rb
set :branch, :master
set :deploy_to, '/home/example_app/production'
server 'example_app.vps.com',
user: 'example_app',
roles: %w{ web app db },
ssh_options: {
forward_agent: true
}
Also remember to add database.yml
and secret.yml
to .gitignore
as those files are already on VPS
and commit all your changes.
We're almost there... Let's deploy our app on VPS finally:
$ bundle exec cap production deploy
Application is live! Yay!
You need Vagrant and VirtualBox installed:
In chef-vps directory run:
$ bundle install
install Vagrant plugins:
$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-omnibus
then bring vagrant machine up and running:
$ vagrant up --provision
that creates the environment, provisioning is run and that's all.
Check this out :)
$ vagrant ssh
###Copyright and license
Code released under the MIT license.