I need deployment my rails app on EC2 recently, actually I use Heroku for a while, Heroku is excellent for development, but the price is not very well compare to EC2, also it's was little slow when access from China.
So I decide to deployment it to EC2, unlike Heroku, Setup EC2 require a lots of setting, which is headache for every one. But I found Rubber, and excellent tool for setup environment on EC2, it based on Capistrano.
From these link1, link2, I can start to do with rubber.
In my first try, I setup all db, app, web, all all server to a single EC2 instance, but there is a lot minor issue, record them here:
1. in rubber.yml, make sure set correct private net mask, default was 10.0.0.0/8, but in some AWS Region, it was become like 172.0.0.0/8, make sure it added to the list, otherwise, your app instance maybe can not access your db instance.
2. When build redis, I found it become build failed, like depends on jemalloc.a not been found, the fix is redis build Makefile sucks, and it need add following like into deloy-redis.rb (between two > )
> tar -zxf redis-#{rubber_env.redis_server_version}.tar.gz # Build the binaries. cd redis-#{rubber_env.redis_server_version} cd deps; make hiredis jemalloc linenoise lua; cd .. # to fix the build error. > make
3. postgresql, because my postgresql require uuid-ossp, I have add following task warper in config/deploy.rb
namespace :rubber do namespace :project do before "deploy:migrate", "rubber:project:add_pg_superuser_and_enable_hstore" after "deploy:migrate", "rubber:project:remove_pg_superuser" task :add_pg_superuser_and_enable_hstore, :roles => [:postgresql_master, :postgresql_slave] do alter_user_cmd = "ALTER USER #{rubber_env.db_user} SUPERUSER;" create_ext_cmd = 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp";' rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT ENDSCRIPT rsudo "sudo -i -u postgres psql -c "#{create_ext_cmd}"" end task :remove_pg_superuser, :roles => [:postgresql_master, :postgresql_slave] do alter_user_cmd = "ALTER USER #{rubber_env.db_user} NOSUPERUSER" rubber.sudo_script "add_superuser_create_hstore", <<-ENDSCRIPT sudo -i -u postgres psql -c "#{alter_user_cmd}" ENDSCRIPT end end
Also need this package change in rubber-postgresql.yml : 36
packages: [postgresql-client, libpq-dev, postgresql-contrib]
4. About figaro
If you're save your secret in ENV var like me, you maybe want to use figaro,
but when you use github to deploy code, the application.yml is not check in to repo, so you need add a task in your config/deploy.rb
# This task make sure application.yml will copy after git. namespace :figaro do desc "SCP transfer figaro configuration to the shared folder" task :setup do transfer :up, "config/application.yml", "#{shared_path}/application.yml", via: :scp end desc "Symlink application.yml to the release path" task :symlink do run "ln -sf #{shared_path}/application.yml #{latest_release}/config/application.yml" end desc "Check if figaro configuration file exists on the server" task :check do begin run "test -f #{shared_path}/application.yml" rescue Capistrano::CommandError unless fetch(:force, false) logger.important 'application.yml file does not exist on the server "shared/application.yml"' exit end end end end after "deploy:setup", "figaro:setup" after "deploy:finalize_update", "figaro:symlink"
5. Github ssh.
Because you maybe using a private github account to do deployment, you need to use ssh auth, but you don't want to the private put in every EC2 instance.
So you can consider use ssh agent forwarding to do this job, you need 3 steps to make it happen:
a) add following to your ~/.ssh/config
Host *.compute.amazonaws.com ForwardAgent yes
b) use this command to generate a new key for the deployment.
ssh-keygen -f ~/.ec2/github_key
c) add setting in your config/deploy.rb
ssh_options[:forward_agent] = true ssh_options[:port] = 22 ssh_options[:keys] = [File.join(ENV["HOME"], ".ec2", "github_key")]
Don't forgot change the scm part:
# Use a simple directory tree copy here to make demo easier. # You probably want to use your own repository for a real app set :scm, :git set :repository, "git@github.com:xxxx/yyyy.git" set :deploy_via, :remote_cache
After all, you can use github to deploy your new code.