Skip to content

Instantly share code, notes, and snippets.

@manojnaidu619
Last active May 12, 2022 14:34
Show Gist options
  • Save manojnaidu619/0d1190c5630a549104e7fab14756d227 to your computer and use it in GitHub Desktop.
Save manojnaidu619/0d1190c5630a549104e7fab14756d227 to your computer and use it in GitHub Desktop.
Rails deployment to AWS EC2

Rails Deployment to AWS EC2

Stack : (Nginx + Phusion Passenger + Postgresql)

  • Step -1

    To Launch an EC2 instance from aws console with all the credentials and configurations hooked.

  • Step-2

    Create User, for application deployment. and assigning privileges.

    $ sudo adduser ______ 		# Fill the Blank with username 
    $ sudo mkdir -p ~_____/.ssh  	# Fill the Blank with username 
    $ touch $HOME/.ssh/authorized_keys
    $ sudo sh -c "cat $HOME/.ssh/authorized_keys >> ~_____/.ssh/authorized_keys"  	# Fill the Blank with username 
    $ sudo chown -R _____: ~_____/.ssh    # Fill the Blank with username
    $ sudo chmod 700 ~_____/.ssh      # Fill the Blank with username
    $ sudo sh -c "chmod 600 ~myappuser/.ssh/*"    # Fill the Blank with username

    Now, SSH into server under the username created now and follow next steps

  • Step-3

    Installing Dependencies

     # Adding Node.js 10 repository
     $ curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
     
     # Adding Yarn repository
     $ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
      
     $ echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
     
     $ sudo add-apt-repository ppa:chris-lea/redis-server
     
     # Refresh our packages list with the new repositories
     $ sudo apt-get update
      
     # Install our dependencies for compiiling Ruby along with Node.js and Yarn
     $ 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 software-properties-common libffi-dev dirmngr gnupg apt-transport-https ca-certificates redis-server redis-tools nodejs yarn
  • Step-4

    Installing Rbenv and Ruby

  $ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
  $ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
  $ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
  $ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
  $ echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
  $ git clone https://github.com/rbenv/rbenv-vars.git ~/.rbenv/plugins/rbenv-vars
  $ exec $SHELL
  $ rbenv install 2.6.5        
  $ rbenv global 2.6.5
  $ ruby -v
  # ruby 2.6.5
  # This installs the latest Bundler, currently 2.x.
  $ gem install bundler
  # For older apps that require Bundler 1.x, you can install it as well.
  $ gem install bundler -v 1.17.3
  # Test and make sure bundler is installed correctly, you should see a version number.
  $ bundle -v
  # Bundler version 2.0
  • Step-5

    Installing Nginx and Passenger

      $ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 561F9B9CAC40B2F7
      $ sudo sh -c 'echo deb https://oss-binaries.phusionpassenger.com/apt/passenger bionic main > /etc/apt/sources.list.d/passenger.list'
      $ sudo apt-get update
      $ sudo apt-get install -y nginx-extras libnginx-mod-http-passenger
      $ if [ ! -f /etc/nginx/modules-enabled/50-mod-http-passenger.conf ]; then sudo ln -s /usr/share/nginx/modules-available/mod-http-passenger.load /etc/nginx/modules-enabled/50-mod-http-passenger.conf ; fi
      $ sudo ls /etc/nginx/conf.d/mod-http-passenger.conf

    Now, edit the configuration file to point to correct Ruby version

    • Open the file $ sudo nano /etc/nginx/conf.d/mod-http-passenger.conf
    • edit, the line containing passenger_ruby to.. passenger_ruby /home/deploy/.rbenv/shims/ruby;
    • Start the server $ sudo service nginx start

    Before continuing, need to edit the nginx conf file so..

    • Remove the old file created by nginx, by default $ sudo rm /etc/nginx/sites-enabled/default
    • Create own conf file.. Note : change myapp to your app name $ sudo nano /etc/nginx/sites-enabled/myapp
    • Add the following contents inside it..
    server {
      listen 80;
      listen [::]:80;
    
      server_name _;
      root /home/deploy/myapp/current/public;   # Change myapp to your appname
    
      passenger_enabled on;
      passenger_app_env production;
    
      location /cable {
       passenger_app_group_name myapp_websocket;
       passenger_force_max_concurrent_requests_per_process 0;
      }
    
      # Allow uploads up to 100MB in size
      client_max_body_size 100m;
    
      location ~ ^/(assets|packs) {
       expires max;
       gzip_static on;
      }
     }
    
    • Reload the Server now.. $ sudo service nginx reload
  • Step-6

    Installing and Creating Database Note: * change deploy to user-owner in line 3 * change myapp to your database-name in line 4

     $ sudo apt-get install postgresql postgresql-contrib libpq-dev
     $ sudo su - postgres
     $ createuser --pwprompt deploy
     $ createdb -O deploy myapp
     $ exit

    Database can be accessed anytime by typing..

    $ psql -U USERNAME -W -h 127.0.0.1 -d DBNAME

  • Step-7 (To be performed in local machine)

    Setup Capistrano

    • Add these to your Gemfile
     gem 'capistrano', '~> 3.11'
     gem 'capistrano-rails', '~> 1.4'
     gem 'capistrano-passenger', '~> 0.2.0'
     gem 'capistrano-rbenv', '~> 2.1', '>= 2.1.4'
    • run these in terminal
    bundle install
    bundle exec cap install STAGES=production
    • The above command creates 3 files namely Capfile config/deploy.rb config/deploy/production.rb

      Now, editing them one by one..

      -> Inside Capfile make sure the below lines are uncommented/added.

      require 'capistrano/rails'
      require 'capistrano/passenger'
      require 'capistrano/rbenv'
      
      set :rbenv_type, :user
      set :rbenv_ruby, '2.6.5'       # Spcify your ruby version 

      -> Inside config/deploy.rb, need to link repo and configs.

       set :application, "myapp"
       set :repo_url, "[email protected]:username/MYAPP.git"
      
       # Deploy to the user's home directory
       set :deploy_to, "/home/deploy/#{fetch :application}"
      
       append :linked_dirs, 'log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', '.bundle', 'public/system', 'public/uploads'
      
       # Only keep the last 5 releases to save disk space
       set :keep_releases, 5
      
       # Optionally, you can symlink your database.yml and/or secrets.yml file from the shared directory during deploy
       # This is useful if you don't want to use ENV variables
       # append :linked_files, 'config/database.yml', 'config/secrets.yml'

      -> Inside config/deploy/production.rb

      • Replace 1.2.3.4 with your server publice IP address
      • change user: 'deploy' to user: 'YOUR_USERNAME'

      Save these changes and now ssh into server and make some changes there...

  • Step-8 (to be performed in server)

    Now, lets create a file to hold all ENV variables

     $ mkdir /home/deploy/YOUR_APP_NAME
     $ sudo nano /home/deploy/YOUR_APP_NAME/.rbenv-vars

    Here, you can store environment variables like SECRET_BASE_KEY, STRIPE_KEY...

  • Step-9 (to be performed in local machine)

    All Setup done, let's run final command.. $ cap production deploy

    NOTE: if capistrano throws any error saying missing key/ secret key then..

    • ssh into sever
    • run..
      $ cd /home/deploy
      $ sudo nano ~/.bashrc
    • now add SECRET_BASE_KEY at the top of the file.
  • Step-10 (to be performed in server)

    $ sudo service nginx restart
    

YOU MADE IT ! Your app is now live

Follow me!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment