035 Capistrano

15 Mar 2013

Capistrano is remote multi-server automation tool that is often used for deployment. In this episode, we will first learn how to execute command line tasks in several servers, then we will deploy a github repo on a newly fired up EC2 instance.

Download video: mp4

Sample code: Github

Similar episodes: 004 GIT, 019 Bash, 022 SSH, 015 Github, 033 AWS,

Version: 2.14.2 (For current Version 3, start with the Readme)

##Background on Capistrano

  1. Wiki, Github
  2. Capistrano tasks

##Things to learn with Capistrano

###1. install Capistrano

  1. install rubygem

    gem -v 2.0.0

  2. install capistrano gem

    ``` gem install capistrano gem list capistrano

    ** LOCAL GEMS ** capistrano (2.14.2) ```

  3. for all help commands run cap -h

###2. simple Capfile

  1. We will SSH into our local machine - i know it’s very meta, but it’s simple (rather than setting up another remote machine or EC2, etc)!
  2. Go to System Preferences > Sharing > Check Remote Login and take note of the SSH command e.g. ssh [email protected] and the corresponding IP address 10.0.1.22
  3. Hosts can ofcourse be www.example.com or in this case our own local machine 10.0.1.22
  4. Create a file named Capfile with the following contents and run in the command line cap list_files:

    task :list_files, :hosts => "10.0.1.22" do run "ls" end

  5. Let’s add in a second task and run cap whois_user or cap list_files:

    ``` task :whois_user, :hosts => “10.0.1.22” do run “echo $USER” end

    task :list_files, :hosts => “10.0.1.22” do run “ls” end ```

  6. Specifying the host over and over again is not efficient

    ``` role :libs, “10.0.1.22”

    task :whois_user do run “echo $USER” end

    task :list_files do run “ls” end

    ```

  7. We can also specify, multiple-servers now. cap whois_user will be execute in both the servers!

    ``` role :libs, “10.0.1.22”, “www.example.com”

    task :whois_user do run “echo $USER” end

    task :list_files do run “ls” end

    ```

  8. We can also specify different groups of hosts e.g. analytics and information:

    ``` role :info, “10.0.1.22”, “10.0.1.20” role :analytics, “10.0.1.22”

    task :whois_user, :roles => :info do run “echo $USER” end

    task :list_files, :roles => :info do run “ls” end

    task :show_free_space, :roles => :analytics do run “df -h /” end

    ```

  9. cap -T command will give all the task list with descriptions
  10. Include Task list with descriptions and then run cap -T:

    ``` role :info, “10.0.1.22”, “10.0.1.20” role :analytics, “10.0.1.22”

    desc “The Current Username” task :whois_user, :roles => :info do run “echo $USER” end

    desc “List Files in the home Directory” task :list_files, :roles => :info do run “ls” end

    desc “Show Free Spaces” task :show_free_space, :roles => :analytics do run “df -h /” end

    ```

  11. Simultaneously run commands in all servers:

    cap invoke COMMAND="ls"
    

###2. deploy a simple html file with Github and AWS EC2

####1. Open a new Github Repo

  1. Open a new github Repo

####2. Prepare a local project with git

  1. Go to an empty folder for the project
  2. Create a simple index.html
  3. Initiate a git repository and push to github

    git init git add README.md git commit -m "first commit" git remote add origin git@[username]/[repo-name].git git push -u origin master

####3. Prepare a capistrano task

  1. Go to the project folder and one level up in the command line (or anywhere you wish) to create the Capistrano task
  2. run in the command line capify . and this will create:

    . |-- Capfile `-- config `-- deploy.rb

  3. Include the capistrano config in file deploy/config.rb

    ``` set :application, “cap-github-ec2” set :deploy_to, “/var/www/html”

    set :scm, :git set :repository, [email protected]:chinee/hello-cap.git” set :scm_username, “sayanee”

    set :location, “ec2-54-234-17-185.compute-1.amazonaws.com” role :app, location role :web, location role :db, location, :primary => true set :user, “ec2-user” ssh_options[:keys] = [“/Users/sayanee/.ssh/ec2.pem”] default_run_options[:pty] = true

    set :branch, ‘master’ set :scm_verbose, true ```

####4. Create an EC2 instance

  1. Create a simple ec2 instance

  2. SSH login into EC2 instance with the *.pem file which has the correct permissions

    chmod 600 mykey.pem ssh -i mykey.pem ec2-user@[public-dns]

  3. Install Git

    sudo yum install git

  4. Install Apache Server

    sudo yum install httpd

  5. Ensure that the default folder exisrs

    cd ../../var/www/html/

  6. Start the Apache server and check its status

    sudo service httpd start sudo service httpd status

  7. visit the ec2 public dns with the addresshttp://ec2-xx-xxx-xx-xxx.compute-1.amazonaws.com and it should show a default Amazon Linux AMI Test Page

  8. Create an SSH key pair and upload to github

    cd ~/.ssh ssh-keygen -t rsa -f [name] -C "[email]"

  9. Create the SSH Config file

    touch ~/.ssh/config

  10. Edit the ~/.ssh/config using an editor such as sudo nano ~/.ssh/config file with the following contents:

    Hostname github.com
    IdentityFile ~/.ssh/[name]
    
  11. Change permsissions for the config file

    chmod 600 ~/.ssh/config

  12. copy the content of the public key:

    cat ~/.ssh/name.pub

  13. Go back to the Github repo page and add SSH keys to Github Repo > Setting > Deploy Keys and paste in the contents of ~/.ssh/name.pub

  14. Test whether SSH into Github works

    ssh -T [email protected]

  15. The project will be deployed to /var/www/html so ensure the permission is set to the current user

    cd /var/www/html sudo chown -R ec2-user:ec2-user .

  16. By default capistrano will release the latest project into the folder /var/www/[project-name]/current/public, so we will need to tell the Apache server to point to it. Open the config file

    sudo nano /etc/httpd/conf/httpd.conf

  17. Edit the lines to point to it

    … DocumentRoot "/var/www/html/current" … <Directory "/var/www/html/current/public">

  18. Stop and restart the Apache server

    sudo service httpd stop sudo service httpd start

####5. Deploy using Capistrano and Github

  1. Come back to the Local machine in the folder where the capistrano task is defined. Check everything is working!

    cap deploy:setup

  2. Deploy from Github to EC2

    cap deploy

  3. View the public DNS in the browser and it should show your simple index.html file!

##More Resources on Capistrano

  1. Deploying to a VPS with Capistrano
  2. Capistrano Handbook
  3. How to deploy your web app using capistrano and ec2
  4. Capistrano Tasks ##Build Link of this Episode

Access in Chrome browser: chrome://credits/