# Deploy Rails App to AWS EC2 ### Creating AWS EC2 Instance ``` - login to 'AWS Management Console' (https://aws.amazon.com/console/) - from 'Services'(in navbar) choose 'EC2' - from 'Create Instance' section, click on 'Launch Instance' - then select 'AMI' (Amazon Machine Image), we will be using 'Ubuntu Server 16.04 LTS (HVM)' as example - select 'Instance Type' as per your requirement - then click 'Next:Configure Instance Details' to continue change 'Configure Instance Details' or used as default settings - click 'Next: Add Storage' adjust size as per your need (default is 8GB) - click 'Next: Tag Instance' create tag if you need any tagging for your instance - click 'Next: Configure Security Group' click 'Add Rule' to add new rule(for port, ip address etc.) default you can set it to - SSH TCP 22 Anywhere 0.0.0.0/0 HTTP TCP 80 Anywhere 0.0.0.0/0 - then click 'Review and Launch' check all your setting, then click 'Launch' - select existing or create new keypair to connect to your instance click 'Launch Instance', this will generate the key (in case of new keypair) & launches your instance find 'Public IP' from 'Description' ``` ### Setup Elastic IP ``` - you can generate an Elastic IP from 'Network & Security' tab - click 'Allocate new address' - then click 'Allocate', this will generate an Elastic IP - click 'Close', this will redirect you to Elastic IP Dashboard - select you Elastic IP & on right click select 'Associate address' - choose you instance (whom you want to associate) & click 'Associate' this will replace your Public IP with Elastic IP (& now this IP is used) ``` ### Setup the server to connect ``` #login to your server from terminal using pem file (generated private key) - ssh -i "" ubuntu@ - sudo apt-get update && sudo apt-get -y upgrade #to update existing packages - create 'deploy' user for deploying the application to server - sudo useradd -d /home/deploy -m deploy #the application will be deployed in /home/deploy directory - sudo passwd deploy #set the password for 'deploy' user - run 'sudo visudo' & add 'deploy ALL=(ALL:ALL) ALL' into the file & save ``` ### Generating ssh-key ``` - su - deploy - ssh-keygen #do not set a passphrase for the key - cat .ssh/id_rsa.pub - copy the ssh-key & set it as your deploy key on your repository(project on bitbucket or github) - copy your system public ssh-key & paste it into the following file on your instance as deploy user nano .ssh/authorized_keys #save & exit ``` ### Installing GIT ``` - sudo apt-get install git ``` ### Installing Nginx ``` - sudo apt-get install nginx - sudo nano /etc/nginx/sites-available/default #to configure default site ``` ``` #add this content to file upstream app { # Path to Puma SOCK file, as defined previously server unix:/home/deploy//shared/tmp/sockets/puma.sock fail_timeout=0; } server { listen 80; server_name localhost; root /home/deploy//public; try_files $uri/index.html $uri @app; location / { proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_redirect off; proxy_http_version 1.1; proxy_set_header Connection ''; proxy_pass http://app; } location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt { gzip_static on; expires max; add_header Cache-Control public; } error_page 500 502 503 504 /500.html; client_max_body_size 4G; keepalive_timeout 10; } ``` ### Installing ruby ``` - su - deploy - gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 - \curl -sSL https://get.rvm.io | bash -s stable - rvm install ruby #you can specify required ruby version - rvm use ruby - gem install bundler #install bundler ``` ### Create files required by capistrano ``` - mkdir - mkdir -p /shared/config - nano /shared/config/database.yml #for rails 5.2 'master.key' file is used for secret key #for rails lower versions 'application.yml' or 'secrets.yml' is used for secret key - nano contactbook/shared/config/application.yml #change application.yml file name as per you required - add this to it #you can add master.key for rails 5.2 SECRET_KEY_BASE: "8a2ff74119cb2b8f14a85dd6e213fa24d8540fc34dcaa7ef8a35c246ae452bfa8702767d19086461ac911e1435481c22663fbd65c97f21f6a91b3fce7687ce63" ``` ### Rails application setup ``` #configuring capistrano #add this to gemfile group :development do gem 'capistrano' gem 'capistrano3-puma' gem 'capistrano-rails', require: false gem 'capistrano-bundler', require: false gem 'capistrano-rvm' end - bundle install #create configuration files for capistrano - config/deploy.rb - config/deploy/production.rb #add these line to capfile require 'capistrano/bundler' require 'capistrano/rvm' require 'capistrano/rails/assets' # for asset handling add require 'capistrano/rails/migrations' # for running migrations require 'capistrano/puma' ``` edit deploy.rb ``` lock '3.4.0' set :application, 'contactbook' set :repo_url, 'git@github.com:devdatta/contactbook.git' # Edit this to match your repository set :branch, :master set :deploy_to, '/home/deploy/contactbook' set :pty, true set :linked_files, %w{config/database.yml config/application.yml} set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system public/uploads} set :keep_releases, 5 set :rvm_type, :user set :rvm_ruby_version, 'jruby-1.7.19' # Edit this if you are using MRI Ruby set :puma_rackup, -> { File.join(current_path, 'config.ru') } set :puma_state, "#{shared_path}/tmp/pids/puma.state" set :puma_pid, "#{shared_path}/tmp/pids/puma.pid" set :puma_bind, "unix://#{shared_path}/tmp/sockets/puma.sock" #accept array for multi-bind set :puma_conf, "#{shared_path}/puma.rb" set :puma_access_log, "#{shared_path}/log/puma_error.log" set :puma_error_log, "#{shared_path}/log/puma_access.log" set :puma_role, :app set :puma_env, fetch(:rack_env, fetch(:rails_env, 'production')) set :puma_threads, [0, 8] set :puma_workers, 0 set :puma_worker_timeout, nil set :puma_init_active_record, true set :puma_preload_app, false ```