Skip to content

Instantly share code, notes, and snippets.

@napcs
Created May 6, 2011 04:10
Show Gist options
  • Select an option

  • Save napcs/958437 to your computer and use it in GitHub Desktop.

Select an option

Save napcs/958437 to your computer and use it in GitHub Desktop.

Revisions

  1. napcs revised this gist May 10, 2011. 1 changed file with 8 additions and 9 deletions.
    17 changes: 8 additions & 9 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -126,15 +126,14 @@ Create a new vhost

    Put this code in the file:

    <VirtualHost *:80>
    ServerName demo.napcs.com
    DocumentRoot /var/www/demo.napcs.com/current/public
    <Directory /var/www/demo.napcs.com/current/public>
    AllowOverride all
    Options -MultiViews
    </Directory>
    </VirtualHost>

    <VirtualHost *:80>
    ServerName demo.napcs.com
    DocumentRoot /var/www/demo.napcs.com/current/public
    <Directory /var/www/demo.napcs.com/current/public>
    AllowOverride all
    Options -MultiViews
    </Directory>
    </VirtualHost>

    Then enable the site

  2. napcs revised this gist May 6, 2011. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -258,7 +258,9 @@ And we're done! At this point, make changes to your code, commit them, redeploy

    cap deploy

    Bonus: Stream your logfiles! Add this to `deploy.rb`
    Bonus: Stream your logfiles!
    --------------------
    Add this to `deploy.rb`

    desc "tail production log files"
    task :tail_logs, :roles => :app do
  3. napcs created this gist May 6, 2011.
    284 changes: 284 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,284 @@
    Deploying Rails to Linode
    ==================
    Installing Ruby Enterprise Edition, Apache, MySQL, and Passenger for deploying Rails 3.0 applications.

    Get a Linode, and set it up with Ubuntu 10.04 LTS so that you have till April 2013 to get updates. Once the Linode is formatted, boot it and continue on.

    Set up an 'A' record in your DNS, pointing to the IP of your Linode. I'm using `demo.napcs.com` here.

    Initial setup
    -------
    Log in with `ssh root@your_ip`

    Add a user

    adduser deploy

    Add the user to the SUDOERS list with `visudo`

    # User privilege specification
    root ALL=(ALL) ALL
    deploy ALL=(ALL) ALL


    Change the default SSH port and disallow root acces. `vim /etc/ssh/sshd_config`

    # What ports, IPs and protocols we listen for
    Port 16888

    ...
    PermitRootLogin no

    Logout and reboot your linode via the console. Don't attempt to restart SSHD while connected. :)

    Test the new settings - Log back in with `ssh deploy@your_ip -p 16888` and log out again

    Create your authorized keys file

    mkdir ~/.ssh
    touch ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys

    Logout and upload your public key

    cat ~/.ssh/id_rsa.pub | ssh deploy@your_ip -p 16888 'cat >> .ssh/authorized_keys'

    That looks a little complex, but we're just printing out the SSH key,
    piping the output to SSH and directing it into the `authorized_keys` on the remote server.
    You could do this many ways, but this is something you could turn into a script and use this
    to add multiple keys.

    Log back in and you're set with keys.

    Installing Ruby
    -----------

    We'll use Ruby Enterprise Edition.

    sudo apt-get install build-essential patch zlib1g-dev libssl-dev libreadline5-dev

    mkdir src
    cd src
    wget http://rubyenterpriseedition.googlecode.com/files/ruby-enterprise-1.8.7-2011.03.tar.gz
    tar -xzvf ruby-enterprise-1.8.7-2011.03.tar.gz
    cd ruby-enterprise-1.8.7-2011.03
    sudo ./installer

    Instructions will guide us through the install process.

    Now make a symlink to REE and symlinks to the individual
    components so it's not so long to type commands to do installs:

    sudo ln -fs /opt/ruby-enterprise-1.8.7-2011.03/ /opt/ruby

    sudo ln -fs /opt/ruby/bin/ruby /usr/local/bin/ruby
    sudo ln -fs /opt/ruby/bin/rake /usr/local/bin/rake
    sudo ln -fs /opt/ruby/bin/irb /usr/local/bin/irb
    sudo ln -fs /opt/ruby/bin/gem /usr/local/bin/gem
    sudo ln -fs /opt/ruby/bin/bundle /usr/local/bin/bundle

    This also puts them on our path, and in our sudo path.

    Installing MySQL for Rails
    ---------
    We install MySQL with the package manager:

    sudo apt-get install mysql-server libmysqlclient-dev
    gem install mysql

    Now log into mysql with `mysql -u root -p` and create a user

    create user 'rails'@'localhost' identified by 'rails';
    create databse projects_production;
    grant all on projects_production.* to 'rails'@'localhost';

    These permissions are not the greatest. They could be hardened.
    But you have to make sure you don't tighten them too much to the point where
    you can't run migrations. Read a good MySQL book.

    Installing Git and Apache
    ------
    sudo apt-get install apache2 git-core

    Now disable the default site.

    sudo a2dissite default
    sudo /etc/init.d/apache2 restart

    Configuring Apache and Passenger
    ------
    sudo gem install passenger
    sudo apt-get install libcurl4-openssl-dev apache2-prefork-dev libapr1-dev libaprutil1-dev

    sudo /opt/ruby/bin/passenger-install-apache2-module

    Follow the instructions.

    Modify `/etc/apache2.conf` and add this:

    LoadModule passenger_module /opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.7/ext/apache2/mod_passenger.so
    PassengerRoot /opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.7
    PassengerRuby /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby

    Create a new vhost

    sudo vim /etc/apache2/sites-available/demo.napcs.com

    Put this code in the file:

    <VirtualHost *:80>
    ServerName demo.napcs.com
    DocumentRoot /var/www/demo.napcs.com/current/public
    <Directory /var/www/demo.napcs.com/current/public>
    AllowOverride all
    Options -MultiViews
    </Directory>
    </VirtualHost>


    Then enable the site

    sudo a2ensite demo.napcs.com
    sudo /etc/init.d/apache2 restart

    And give the `deploy` user permissions to the `/var/www` root folder:

    sudo chown -R deploy:deploy /var/www

    Again, not the best approach, but an acceptable one.

    We're done with server setup!


    Preparing Your Rails app
    ---------

    Create the Rails 3 application. We'll do a simple one with a single table.

    rails new demo
    cd demo
    rails g scaffold projects name:string description:text
    rake db:migrate
    rm public/index.html

    Add a root route to `config/routes.rb`

    root :to => "projects#index"

    Add the `mysql2` gem to your Gemfile and get the sqlite3 one only in dev mode. Specify the version numbers for the gems or you'll get burned!'

    group :development do
    gem 'sqlite3', '1.3.3'
    end

    group :production do
    gem 'mysql2', '0.2.7'
    end

    Then

    bundle

    Let's deploy!

    Capistrano setup
    -----------

    Generate the capistrano config file:

    capify .

    Modify the `config/deploy.rb` file with our settings for our server.

    require 'bundler/capistrano'

    set :application, "demo.napcs.com"

    # Deploy from your local Git repo by cloning and uploading a tarball
    set :scm, :git
    set :repository, "."
    set :deploy_via, :copy

    set :user, :deploy
    set :deploy_to, "/var/www/#{application}"
    set :use_sudo, false

    role :web, "demo.napcs.com" # Your HTTP server, Apache/etc
    role :app, "demo.napcs.com" # This may be the same as your `Web` server
    role :db, "demo.napcs.com", :primary => true # This is where Rails migrations will run

    namespace :deploy do
    task :start do ; end
    task :stop do ; end
    task :restart, :roles => :app, :except => { :no_release => true } do
    run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
    end
    end

    Pay attention to this part:

    set :scm, :git
    set :repository, "."
    set :deploy_via, :copy

    This lets you from your local Git repo by cloning and uploading a tarball. This means you can
    push code from your computer to your server, rather than having to pull code from your remote
    Git repository to your server. Or if Github is down.


    Now specify your production database info in `database.yml`:

    production:
    adapter: mysql2
    host: localhost
    database: projects_production
    username: rails
    password: rails

    Here, we're putting our production db password in our `database.yml` file.
    You probably want to keep this file out of your repository, and instead
    write a custom Capistrano task to build the `database.yml` file during
    deployment. That's something you can Google on your own.

    Now make a Git repo

    git init
    git add .
    git commit -a -m "Initial import"

    Finally, set up the app on the server:

    cap deploy:setup

    Deploy the app

    cap deploy:cold

    And we're done! At this point, make changes to your code, commit them, redeploy with

    cap deploy

    Bonus: Stream your logfiles! Add this to `deploy.rb`

    desc "tail production log files"
    task :tail_logs, :roles => :app do
    run "tail -f #{shared_path}/log/production.log" do |channel, stream, data|
    puts # for an extra line break before the host name
    puts "#{channel[:host]}: #{data}"
    break if stream == :err
    end
    end

    Then run it with

    cap tail_logs

    Capistrano isn't just for deploying Rails apps. You can use it to automate anything
    you do with SSH.