#####################################
# 0. SET UP AWS (ASSUMING YOU HAVE ALREADY SET UP AN ACCOUNT)

# CREATE SECURITY GROUP
  • In the EC2 Dashboard, click Security Groups, then Create Security Group.
  • Enter Name
  • Enter Description
  • Rules to add:
    - HTTP
    - SSH
    - Custom TCP Rule : Port 3000 (if using Rails development environment)
  • Click Create

# CREATE IAM ROLE
  • Enter Name
  • Select Amazon EC2
  • Check AdministratorAccess
  • Click Next Step
  • Click Create Role

# CREATE EC2 INSTANCE
  • In the EC2 Dashboard, click Launch Instance.
  • Select Ubuntu Server 14.04 LTS (HVM), SSD Volume Type
  • Select t2.micro
  • Apply IAM role (if applicable)
  • Click Next (Add Storage)
  • Apply correct storage volume and size.
  • Click Review and Launch
  • Click Launch
  • If no key pair exists, select Create a new key pair from the dropdown
  • Enter Key pair name
  • Click Download key pair
  • Click Launch Instance
  • Click View Instance

# CREATE ELASTIC IP
  • In the EC2 Dashboard, click Elastic IPs
  • Allocate New Address
  • Click Yes, Allocate
  • Click Actions dropdown
  • Click Associate Address
  • Click in Instance input and select the correct instance
  • Click Associate

# UPDATE PEM PERMISSIONS
  chmod 400 <location/of/pem/file>

# TO SSH INTO THE INSTANCE
  ssh ubuntu@<elastic_ip> -i <location/of/pem/file>

#####################################
# 1. SET UP USER

# SET UP UBUNTU:
  sudo apt-get update
  sudo apt-get upgrade -y

# SET TIMEZONE:
  sudo dpkg-reconfigure tzdata

# IF YOU WANT TO ADD A USER:
  sudo su
  adduser <user> # I use deploy for <user>

# TO MODIFY THAT USER AS SUPERUSER (PERMFORM AS ROOT) (PERFORM ONLY IF NEW USER NEEDS ROOT ACCESS. DEFAULT IS NOT.):
  cd
  usermod -a -G sudo <user>

# OPERATE AS THAT USER:
  sudo su - <user>

# CREATE SSH DIRECTORY
  mkdir .ssh

# UPDATE DIRECTORY PERMISSIONS
  chmod 700 .ssh

# CREATE KEYS FILE
  touch .ssh/authorized_keys

# UPDATE FILE PERMISIONS
  chmod 600 .ssh/authorized_keys

# IF ONLY KEYS ARE DEFAULT PEM
  sudo vim /home/ubuntu/.ssh/authorized_keys

# COPY ALL CONTENTS, THEN
  vim .ssh/authorized_keys

# PASTE NEW CONTENTS, SAVE, and EXIT

# LOG OUT AS ubuntu AND LOG IN AS NEW USER

# REMOVE OLD USER
  sudo userdel -r ubuntu

#####################################
# 2. SET UP FIREWALL

# INSTALL FIREWALL, IF NECESSARY
  sudo apt-get install ufw

# CONFIGURE IPv4 & IPv6
  sudo vim /etc/default/ufw

# MAKE SURE THIS IS SET
  IPV6=yes

# RESTART FIREWALL
  sudo ufw disable
  sudo ufw enable

# DEFINE DEFAULTS
  sudo ufw default deny incoming
  sudo ufw default allow outgoing

# ALLOW CONNECTION FOR SSH/22
  sudo ufw allow ssh

# ALLOW CONNECTION FOR WWW/80 (IF NEED BE)
  sudo ufw allow www

#####################################
# 3. INSTALLING

# INSTALL DEPENDENCIES:
  sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev openssl bison -y

# DO NOT INSTALL GEM DOCS:
  echo "gem: --no-ri --no-rdoc" > ~/.gemrc

# INSTALL NODE.JS
  sudo add-apt-repository ppa:chris-lea/node.js
  sudo apt-get update
  sudo apt-get install nodejs -y

# INSTALL POSTGRES
  sudo apt-get install postgresql postgresql-contrib libpq-dev -y

# INSTALL RUBY WITH RBENV (THIS TAKES 5-10 MINS)
  cd
  git clone git://github.com/sstephenson/rbenv.git .rbenv
  echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
  echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  source ~/.bashrc

  git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
  echo 'export PATH="$HOME/.rbenv/plugins/rubybuild/bin:$PATH"' >> ~/.bashrc
  source ~/.bashrc

  git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash
  rbenv install 2.2.0
  rbenv global 2.2.0
  ruby –v

# INSTALL BUNDLER
  gem install bundler
  rbenv rehash

# INSTALL RAILS
  gem install rails

#####################################
# 4. SET UP POSTGRESQL DATABASE

# CREATE USER
  sudo -u postgres createuser -s <user>

#####################################
# 5. BUILD RAILS APPLICATION

# NEW RAILS APPLICATION
  rails new api -d postgresql
  cd api

# ADD TO .gitignore
  config/secrets.yml

# PUSH TO GITHUB
  git init
  git add .
  git commit -m "first commit"
  git remote add origin <origin.url>
  git push origin master

# GENERATE A BASIC RESTFUL SCAFFOLD
  rails generate scaffold User name:string age:integer

# SET UP LOCAL DATABASE (ENSURE POSTGRES IS RUNNING)
  rake db:create
  rake db:migrate

# ADD TO config/routes.rb
  root 'users#index'

# START SERVER TO MAKE SURE THINGS WORK PROPERLY
  rails s

# VISIT localhost:3000/ IF EVERYTHING IS SOLID, COMMIT

#####################################
# 6. SET UP SERVER (NGINX / PASSENGER)

# CREATE APP FOLDER
  cd
  mkdir <appname>

# INSTALL THE APT KEY
  sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 561F9B9CAC40B2F7

# CREATE AN APT SOURCE FILE
  sudo vim /etc/apt/sources.list.d/passenger.list

# INSERT
  deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main

# CHANGE OWNER AND PERMISSIONS
  sudo chown root: /etc/apt/sources.list.d/passenger.list
  sudo chmod 600 /etc/apt/sources.list.d/passenger.list

# UPDATE APT CACHE
  sudo apt-get update

# INSTALL NGINX AND PASSENGER
  sudo apt-get install nginx-extras passenger -y

# UPDATE NGINX CONFIG FILE
  sudo vim /etc/nginx/nginx.conf

# UNCOMMENT/ADD THESE LINES
  passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
  passenger_ruby /home/<user>/.rbenv/shims/ruby

# SAVE and EXIT

# OPEN DEFAULT SERVER BLOCK
  sudo vim /etc/nginx/sites-available/default

# COMMENT THESE LINES (OR COMMENT EVERYTHING)
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;

# CREATE PROPER SERVER CONFIG FILE
  sudo vim /etc/nginx/sites-available/<appname>

# ADD
  server {
    listen 80 default_server;
    server_name <dns_or_elastic_ip>;
    passenger_enabled on;
    # passenger_app_env development; # ONLY IF IN DEVELOPMENT MODE
    root /home/<user>/<appname>/current/public;
  }

# CREATE SYM LINK TO SITES-ENABLED
  sudo ln -s /etc/nginx/sites-available/<appname> /etc/nginx/sites-enabled/<appname>

# RELOAD AND RESTART NGINX SO CHANGES TAKE EFFECT
  sudo nginx -s reload
  sudo service nginx restart

#####################################
# 7. CONFIGURE APP FOR DEPLOYMENT

# ADD TO Gemfile
  # Use Passenger as the app server
  gem 'passenger'

  # Use Capistrano for deployment
  gem 'capistrano', '~> 3.4.0'
  gem 'capistrano-bundler', '~> 1.1.2'
  gem 'capistrano-rails', '~> 1.1'
  gem 'capistrano-passenger'
  gem 'capistrano-rbenv', '~> 2.0'
  gem 'capistrano-rbenv-install', '~> 1.2.0'
  gem 'capistrano-secrets-yml'

# THEN
  bundle install

# INSTALL Capfile AND SET UP FOR STAGING AND PRODUCTION DEPLOYMENTS
  cap install

# ADD TO Capfile
  require 'capistrano/rbenv'
  require 'capistrano/bundler'
  require 'capistrano/rails/assets'
  require 'capistrano/rails/migrations'
  require 'capistrano/passenger'
  require 'capistrano/secrets_yml'

# RUN IN APP ROOT
  rake secret

# COPY THE OUTPUT TO config/secrets.yml
  production:
    secret_key_base: <secret_output>

# REMOVE DB USERNAME AND PASSWORD FROM config/database.yml
  # username: <appname>
  # password: <%= ENV['<APPNAME>_DATABASE_PASSWORD'] %>

# ADD TO config/deploy/production.rb
  set :application, '<appname>'

  server '<dns_or_elastic_ip>',
    user: '<user>',
    roles: %w{web app},
    primary: true,
    ssh_options: {
      keys: %w( location/of/pem/file )
    }

  set :rails_env, 'production'
  set :branch, 'master'
  set :repo_url, '<git.repo.url>'

  set :deploy_via, :remote_cache
  set :deploy_to, "/home/<user>/<appname>"

# ADD TO config/deploy.rb
  # config valid only for current version of Capistrano
  lock '3.4.0'

  set :application, '<appname>'
  set :repo_url, '<git.repo.url>'

  # https://github.com/capistrano/rbenv/
  set :rbenv_type, :user # or :system, depends on your rbenv setup
  set :rbenv_ruby, '2.2.0' # run ruby -v on server to ensure the version is correct

  # in case you want to set ruby version from the file:
  # set :rbenv_ruby, File.read('.ruby-version').strip

  set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
  set :rbenv_map_bins, %w{rake gem bundle ruby rails}
  set :rbenv_roles, :all # default value

# COMMIT AND PUSH TO GITHUB, THEN RUN
  cap production setup
  cap production deploy

#####################################
# 8. CREATE DATABASE ON PRODUCTION SERVER

# SSH IN TO SERVER AND
  cd <appname>/current
  RAILS_ENV=production rake db:create
  RAILS_ENV=production rake db:migrate

# CHECK YOUR WORK, BECAUSE YOU ARE DONE

#####################################
# NOTES

# SEE NGINX LOG
  sudo less /var/log/nginx/error.log
# OR
  sudo cat /var/log/nginx/error.log