Forked from dhirajbajaj/successful-rails-nginx-production-deployment.txt
Created
January 30, 2018 04:49
-
-
Save anhphamt/e9bd5000979eea2c1c97cf996ca27de1 to your computer and use it in GitHub Desktop.
Ruby on Rails / Postgres / Nginx / Passenger / Capistrano / Ubuntu 14.04 / AWS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
##################################### | |
# 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 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment