SSL/HTTPS for Passenger in development on Ubuntu Jaunty

Making a certificate

sudo mkdir /etc/apache2/ssl
sudo /usr/sbin/make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/apache2/ssl/apache.pem
sudo a2dissite default-ssl
sudo a2enmod ssl
sudo /etc/init.d/apache2 restart

Configure passenger

<VirtualHost *:80>
 ServerAlias *.something.com
 RailsEnv development
 DocumentRoot /apps/something/public
</VirtualHost>
<VirtualHost *:443>
 SSLEngine on
 SSLCertificateFile /etc/apache2/ssl/apache.pem
 ServerAlias *.something.com
 RailsEnv development
 DocumentRoot /apps/something/public
</VirtualHost>

host

Automated SSH Login with Password and Additional Commands

The normal answer to most ssh related problems is: “use public/private keys”
but sometimes this does not work…

What i did regularly was this:

  • ssh to xxx@asdads.com
  • enter password
  • sudo su admin
  • cd /apps/hosts/some_project

Thats not very complicated, but its frustrating. What I do now is: “sshxx”, which executes this excpect script in ~/bin/sshxx

#!/usr/bin/expect
set pass [lindex $argv 0] #get first argument
spawn ssh xxx@asdads.com
expect "assword" #matches Password and password
send "$pass\r"
expect "xxx@" #wait for the prompt
send "sudo su admin\r"
send "cd /apps/hosts/some_project\r"
send "clear\r" #clean up the mess
interact

(For Ubuntu you need to “sudo apt get install expect” first)

Capistrano Recipe to Install or Update Passenger

Update:

  • the basic installation can be done via “passenger-install-apache2-module –auto”
  • a better script that does the whole job can be found in cap-recipes

Took me some minutes to figure this out, so here for your laziness-pleasure (for Ubuntu):

Usage
To install passenger or update to the newest release:
cap install_passenger

Install

#deploy.rb
  desc "Install Passenger"
  task :install_passenger do
    install_passenger_module
    config_passenger
  end

  desc "Install Passenger Module"
  task :install_passenger_module do
    sudo "gem install passenger --no-ri --no-rdoc"
    input = ''
    run "sudo passenger-install-apache2-module" do |ch,stream,out|
      next if out.chomp == input.chomp || out.chomp == ''
      print out
      ch.send_data(input = $stdin.gets) if out =~ /(Enter|ENTER)/
    end
  end

  desc "Configure Passenger"
  task :config_passenger do
    version = 'ERROR'#default
    #passenger (2.0.3, 1.0.5)
    run("gem list | grep passenger") do |ch, stream, data|
      version = data.sub(/passenger \(([^,]+).*/,"\\1").strip
    end

    puts "    passenger version #{version} configured"

    passenger_config =<<-EOF
      LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-#{version}/ext/apache2/mod_passenger.so
      PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-#{version}
      PassengerRuby /usr/bin/ruby1.8
    EOF

    put passenger_config, "src/passenger"
    sudo "mv src/passenger /etc/apache2/conf.d/passenger"
  end

Source
Basic recipe

The Simpelest Mongrel Server (Without Rails)

I tried to make my own small server and mongrel came in handy!
Some things i covered:

  • making the server stop on ctr+c
  • ignoring favicon requests
  • using the local ip (192.168.X.X) or localhost
  • parsing the request parameters (?aaa=bbb&…) to a hash

The rest is up to you!

Stick your code into process, then run ‘ruby server.rb’ and your done 🙂

#server.rb
require 'mongrel'
require 'yaml'

module SimpleServer
  class SimpleHandler < Mongrel::HttpHandler
    def process(request, response)
      return if request.params['REQUEST_URI']=='/favicon.ico'

      params = extract_params request
      puts "Called with:"
      puts params.to_yaml

      response.start(200) do |head,out|
        head["Content-Type"] = "text/plain"
        out.write("HELLO WORLD!")
      end
    end

    def extract_params request
      params = request.params['QUERY_STRING']
      return {} if !params

      arr = params.split('&')

      hash = {}
      arr.each do |value|
        break if !value
        temp = value.split('=')
        hash[temp[0]]= temp[1]
      end 

      hash
    end
  end

  #SERVER
  def self.start
    require 'socket'
    #or use 'localhost' if u do not want to be callable from outside
    host = IPSocket.getaddress(Socket.gethostname)
    config = Mongrel::Configurator.new :host => host, :port => 3000 do
      listener {uri "/", :handler => SimpleHandler.new}
      trap("INT") { stop }
      run
    end

    #show what we are running
    puts "Running at"
    puts config.defaults.to_yaml
    config.join
  end
end

SimpleServer::start