2012-08-27

SimpleMembershipProvider ... HUH?!?!

UPDATE (2012-08-30):
John Galloway of Microsoft has put together a very helpful insight into Simple Membership Provider at http://bit.ly/PtkPN1 So, if any of you is still looking for some background information or the basic idea behind Simple Membership Provider, have a go and read his blog post. Thanks John!
Hi,
Yesterday I was playing around with the new Visual Studio 2012 and MVC4.
So far I am impressed with Visual Studio and asp.net 4.5 but my yesterday's adventure made me go HUH?!?!

Well, I created a new MVC4-Application. That should not be too hard, just hit File -> New -> Project and select Web -> MVC 4 Application.

So far so good, a new application was created and ready to run. Then to use the default 'localDB' file, I followed what I had learned to work fine with the previous release candidates and installed the corresponding Default Membership Provider package via Nu-Get (based on Scott Hanselman - Introducing System.Web.Providers), which worked well in some previous release candidate of vs2012
install-package System.Web.Providers.localDB
After the installation was finished I ran the application and hit 'Register' so the application would create the corresponding database-file. Which it did and the server explorer even listed it correctly. Then I entered the credentials of a new testuser 'tommy', 'test123$', 'test123$' and clicked 'Register' and then the application gave up:


Zeile 80:                 try
Zeile 81:                 {
Zeile 82:                     WebSecurity.CreateUserAndAccount(model.UserName, model.Password);
Zeile 83:                     WebSecurity.Login(model.UserName, model.Password);
Zeile 84:                     return RedirectToAction("Index", "Home");

Quelldatei: c:\Users\igambin\Documents\Visual Studio 2012\Projects\MvcApplication6\MvcApplication6\Controllers\AccountController.cs    Zeile: 82
At some point before the final release of Visual Studio 2012, Microsoft seems to have decided to use the SimpleMembershipProvider (see Matthew M. Osborne - Using SimpleMembership With ASP.NET WebPages) by Default instead of the DefaultMembershipProvider.
Basically and in relation to Azure or Web Pages that might be helpful and even advantageous, but for someone used to the old MembershipProviders at first it seems a strange decision. I mean, I loved the MembershipProviders as they represented a full-fledged and secure means of user/role/membership data management which Visual Studio even offered a built in solution to manage.

Well, that built-in management won't work with SimpleMembership (at least not yet) but I wanted at least to get the "NEW Default" MembershipProvider up and running. So I decided instead of using localDB I would want to use SqlServer Compact Edition. So I installed that
install-package sqlservercompact
And again based on ScottHa's BlogPost mentioned above, I added a corresponding "ConnectionString" to my web.config:
At that moment I realized: "hey, there is nothing that relates SimpleMembership to use that new ConnectionString". Therefore I started looking into the SimpleMembership files and did find the AccountModel.cs which named the connection string in its constructor
public class UsersContext : DbContext
{
    public UsersContext()
        : base("Sql_CE")
    {
    }
    public DbSet UserProfiles { get; set; }
}
where I put my SqlServerCompact ConnectionString so SimpleMembership would use the right file.

Yes, at that point I was a bit surprised that the ConnectionString was hardcoded into the model file. The old Membership Providers had that kind of configuration done in the web.config file. Actually I think I would have preferred the old way to do it. Well, again I tried to start my application and add a new user and again the application stroke back


Zeile 39: }
Zeile 40:
Zeile 41: WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);Zeile 42: }
Zeile 43: catch (Exception ex)

Quelldatei: c:\Users\igambin\Documents\Visual Studio 2012\Projects\MvcApplication5\MvcApplication5\Filters\InitializeSimpleMembershipAttribute.cs    Zeile: 41             


Not only is the ConnectionString hardcoded into SimpleMembership once, it indeed has been done twice!

I modified that line to also use the connectionString I defined in my web.config. At that point the application worked and the SimpleMembership Provider provided what it should.

Still... I really miss hitting PROJECT->ASP.NET Configuration to just open up the Asp.net configuration web-site where I would manage my users and roles and user-role memberships.




2012-06-29

Dead LCD Screen revived for < 1€

Last week, when I came home I wanted to quickly check something on the internet. So I walked to my office, switched on my computer and the screen and ... waited ... 

While the computer ran the usual noises and beeps the screen stayed black...

What do you do when the screen fails? Right... 

check the powerplug,
 then 
switch it off an on
then
check the video connectors...

All the basic stuff failed... so next Step

Warranty?!? -> screen is too old .. no more warranty

So, I went to my usual computer store and asked what the repair would cost. The estimation of my favorite vendor was, "45€ for sending the screen in to Samsung + 15€ - 50€ for the parts that need replaced + 50€ - 100€ for the time some worker needs to repair the screen".

R i g h t !!! 

My luck will produce the Worst Case: I pay more for the repair than I would for a new screen. 

End of story. Screen is dead. Thanks God I got a 2nd one on my desk. 

O R . . . m a y b e   N O T !!!

There are many cases where I am way too nosy. Then I start collecting information to try and figure out what is wrong and why it is. 

So I asked Google about "Samsung Syncmaster 245B screen stays black".

I did get a couple of links that listed comments, threads from people in blogs and forums who had a similar problem.

First thread mentioned a set of probably blown capacitators. They would be easily to find so I opened up the screen and had a look. No luck there though, didn't find a blown one. 

Next thread said something about "broken resistors". The post even pointed out 3 resistors that are often broken because they were chosen too cheap and are not really fit to do their task. To check out this possible source of the screens death I needed to unpack my meter from our packing cases of our last move. 

S T R I K E !!!

One of the three resitors was broken indeed. So today I went to a store that has all kinds of electronic parts waiting to be sold. As those resistors were said to not beeing fit for their job, I chose to replace all three of them instead of only the broken one by a set of 3 68 Ohm resistors that can process a higher power demand (1W instead of the original resistors 0.5W). 

I reconnected all connectors and closed the screen again, hooked it up to my computer and...

TADAAA! It works again.


Well giving it to the repair center would have cost me 100 - 200€. 

Repairing it myself cost me 90 cents (Theoretically I could have done it for 30cents, if I had only replaced the broken resistor). Well putting an avg. hourly cost of 30€ if I would calculate my own work time, the self repair would cost 60.90€. But as I still like to spend time on such problems .. just for the fun of it, I keep thinking I repaired my screen for 90 cents. And the time I've spent???  Well I'd call that taking a recreational timeout. 


2012-06-04

Wann im Jahr ist Ostersonntag? (When is easter sunday?)

- Wann ist Ostersonntag?

- Warum?

- Damit ich Feiertage bestimmen kann.

- Wo brauchst Du es?

- In meiner Excel-Datei... Zeitnachweise und so...


... hat mich ein Kollege kürzlich gefragt. Ich sagte ihm, er finde die Lösung zu seinem Problem unter "Gaußsche Osterformel" bei de.Wikipedia.org

Da ihn die Ausführungen dort mehr oder weniger verwirrten, gab ich ihm einfach die für den gregorianischen Kalender passende Excel-Formel. Dabei ist A2 die Referenz auf die Zelle, in welcher die Jahreszahl des zu berechnenden Ostersonntag-Termins steht:
= DATUM(A2;3;(21 + (REST( 19*(REST(A2;19)) + (15 + GANZZAHL( (3*(GANZZAHL(A2/100))+3) / 4 ) - GANZZAHL( (8*(GANZZAHL(A2/100))+13) / 25)); 30)) - (GANZZAHL(GANZZAHL( ((REST( 19*(REST(A2;19)) + (15 + GANZZAHL( (3*(GANZZAHL(A2/100))+3) / 4 ) - GANZZAHL( (8*(GANZZAHL(A2/100))+13) / 25)); 30)) + (REST(A2;19))) /11 ) / 29)))+(7 - REST((21 + (REST( 19*(REST(A2;19)) + (15 + GANZZAHL( (3*(GANZZAHL(A2/100))+3) / 4 ) - GANZZAHL( (8*(GANZZAHL(A2/100))+13) / 25)); 30)) - (GANZZAHL(GANZZAHL( ((REST( 19*(REST(A2;19)) + (15 + GANZZAHL( (3*(GANZZAHL(A2/100))+3) / 4 ) - GANZZAHL( (8*(GANZZAHL(A2/100))+13) / 25)); 30)) + (REST(A2;19))) /11 ) / 29))) - (7 - REST( A2 + GANZZAHL(A2 / 4) + (2 - GANZZAHL( (3*(GANZZAHL(A2/100))+3) / 4)); 7 )); 7)))

(english)
A short while ago a friend asked me how to calculate "easter sunday" based on a given "gregorian" year. He would need a formula for his excel file. So I gave him the following formula with A2 referring to the cell that contains an integer determining the year for which the easter sunday is to be calculated:
= DATE(A2;3;(21 + (MOD( 19*(MOD(A2;19)) + (15 + INT( (3*(INT(A2/100))+3) / 4 ) - INT( (8*(INT(A2/100))+13) / 25)); 30)) - (INT(INT( ((MOD( 19*(MOD(A2;19)) + (15 + INT( (3*(INT(A2/100))+3) / 4 ) - INT( (8*(INT(A2/100))+13) / 25)); 30)) + (MOD(A2;19))) /11 ) / 29)))+(7 - MOD((21 + (MOD( 19*(MOD(A2;19)) + (15 + INT( (3*(INT(A2/100))+3) / 4 ) - INT( (8*(INT(A2/100))+13) / 25)); 30)) - (INT(INT( ((MOD( 19*(MOD(A2;19)) + (15 + INT( (3*(INT(A2/100))+3) / 4 ) - INT( (8*(INT(A2/100))+13) / 25)); 30)) + (MOD(A2;19))) /11 ) / 29))) - (7 - MOD( A2 + INT(A2 / 4) + (2 - INT( (3*(INT(A2/100))+3) / 4)); 7 )); 7)))

2012-03-21

ASP.Net Default Password Hash (+Salt)

Today I played around with custom user controls so I wondered if I could create my own login control, that would allow me to check credentials against the built-in ASP.net security mechanisms. The included Table structure is easy enough to understand, but it took me a while to find out how to apply salt and hashing algorithms to the entered user password to get the same hash that the ASP.net security mechanisms generate. Just to not forget it or to whoever might need it:


        public static string EncodePassword(string pass, string saltBase64)
        {
            byte[] bytes = Encoding.Unicode.GetBytes(pass);
            byte[] src = Convert.FromBase64String(saltBase64);
 
            byte[] dst = new byte[src.Length + bytes.Length];
            System.Buffer.BlockCopy(src, 0, dst, 0, src.Length);
            System.Buffer.BlockCopy(bytes, 0, dst, src.Length, bytes.Length);
            HashAlgorithm algorithm = HashAlgorithm.Create("SHA1");
 
            byte[] inArray = algorithm.ComputeHash(dst);
            return Convert.ToBase64String(inArray);
        }


And if you have to create a new Salt, just use:


        public string CreateSalt(int saltLength)
        {
            //Create and populate random byte array
            byte[] randomArray = new byte[length];
            string randomString;
 
            //Create random salt and convert to string
            RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
            rng.GetBytes(randomArray);
            randomString = Convert.ToBase64String(randomArray);
            return randomString;
        }


Resources: forums.asp.netPeter Stathakos Blog

ASP.Net DateTime vs. Javascript Date

Lately I am spending quite some time with programming C# ASP.net applications. It is fun and far easier than I thought it would be. Of course, occasionally, one gets to the point where one wonders, 'WTF... Why doesn't this work!!!'

Yesterday, I got to that point, so as it was late I went to bed and started looking for a solution around the net today.

My problem was, that if you receive JSONified data from ASP the Date will be something like
 "/Date(139356000000+0200)/"

This is not necessarily a problem as one can guess what this string represents. The part before the '+' is the time in Milliseconds and the rest (including the '+') is the TimezoneOffzet as in '+/-hhmm', but there is no natural way to easily transform it (or at least, if it exists, it slipped my attention) to a Javascript Date-Object.

So in the end, the value above, that you get by JSON.parsing a ASP.net Webservice-Response, can be transformed by this Javascript-Function:
function DateTime2Date(input) {
    return new Date(parseInt(input.replace("/Date(""").replace(")/"""), 10))
}
And then of course, there is the next problem handling the Javascript Date when you want to send it back to the ASP.net WebService. The natural representation of the Javascript-Date when JSON.stringified looks like
"2012-03-06T23:00:00:000Z"
which again is a value that the ASP.net Webservice won't even consider to route through to the according Webservice Recipient. So in order to send (POST/PUT) this Date to the Webservice you will again have to modify the representation into a String using this Javascript Function:
function Date2DateTime(input) {
    var tzo = (input.getTimezoneOffset() / 60 * -100);
    tzo = (tzo < 0  ?    "" + ( tzo / -1000 >= 1 ? tzo : "0"+tzo )
                    :   "+" + ( tzo /  1000 >= 1 ? tzo : "0"+tzo ));
    return "\/Date(" + input.valueOf() + tzo + ")\/";
}
This method looks a bit odd, but if you know that 'getTimezoneOffset()' returns the offset in minutes rather than hours or in the '+/-hhmm' format and if you know that the value is returned is not the offset based on GMT but based on your local Timezone, it might make a bit more sense.

I hope this will help anyone who faces a similar situation.

2011-03-29

Stack Overflow

About two weeks ago I have registered at stackoverflow.com

For a long time I considered it a nice place to find answers to questions already asked. But lately I found myself having questions... hence my decision to register, log in and start being part of the community.

And you know what... I like it.

So far the community is very nice and helpful and I am having fun in helping out others as well. So maybe every now and then I will write some more or less lengthy post here in order to answer or give examples to my answers over at stackoverflow.com. Of course I will add links to the according questions.

2010-08-09

Installation of Ruby, Rails & Co. on Ubuntu

reqs: Ubuntu
tested version: 10.04

target: development environment with ruby 1.9.2-rc2 and rails3-rc1

Installation of a Ruby on Rails development environment has become way easier under Linux nowadays. There is this fantastic gem "rvm", which actually does nearly all the stuff necessary for a clean rails development environment.

Ok first thing to do after the installation of Ubuntu: open the terminal console, and using 'sudo'

we install some background software, which the system will need to do the actual installations.
apt-get -y install build-essential zlib1g-dev libssl-dev gzip zip unzip libzip1 libzip-dev git-core subversion curl bison vim libreadline5 openssl libreadline5-dev libxml2-dev libxslt-dev autoconf sqlite3 libsqlite3-dev sqliteman
Incase the following packages are not yet installed and if you want/need them (you might) try
apt-get -y install postgresql-8.4 libpq-dev pgadmin3 imagemagick mercurial tortoisehg tortoisehg-nautilus sun-java-jre6 openssh-server yakuake
Then type
exit
to leave the sudo mode and with your normal user account install rvm (you might want to re-check http://rvm.beginrescueend.com/rvm/install/ as they might change the install script every now and then)
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

At the end of the rvm installation you will get some explanations to modify your .bashrc. Follow these instructions (usually there shouldn't be any 'return' line (and if its a comment line)  in a fresh ubuntu install) and then type
echo "source \"\$HOME/.rvm/scripts/rvm\"" >> .bashrc
to add environment-loader to the end of your .bashrc file, as that line is crucial for running rvm.

Type
rvm reload
to reload the rvm environment and exit the terminal console.

Start a new terminal console.

After that is done you just
rvm install 1.9.2
which will load, compile and install ruby 1.9.2 from its source.

Then we have to tell our system, that we want to use 1.9.2 as default ruby
rvm 1.9.2 --default
and are ready to install rails3 (rc1 still is a pre-release so don't forget --pre)
gem install rails --pre
and there you go.

Nice and easy install of (as of now, might change soon again when ruby 1.9.2 or rails 3 go stable) Ruby 1.9.2rc2, rails 3 rc1.

Have fun developing your Ruby on Rails applications.

2010-04-07

Install production server with Ruby 1.9.1 / Gem 1.3.6 / Rails 3b / Passenger


Environment: x86 32bit celeron mini tower, 4GB ram, big mirrored harddisk, ubuntu 9.10

This time I wrote a bash-script that, if used on an ubuntu (tested for 9.10) pc will install ruby, rubgems, rails, apache, passenger and necessesary dependencies for a naked (as in freshly installed ubuntu) pc. 

It needs to be run as root and will download all packages, sources as needed and compile/install them in order. As I usually work with sqlite3, postgresql and an oracle database I also included the required installations for those. Just make sure if you dont want to #-comment the oracle-installation, that it will need the actual instantclient-zipfiles and the tnsnames.ora-file located in /tmp. The script will then find these (tested for instantclient_11.x) and install them accordingly.

Enjoy!

#Ruby 1.9.1 / Gem 1.3.6 / Rails 3b / Passenger
#!/bin/bash
red='\E[31;40m'
green='\E[32;40m'
cecho ()                     # Color-echo.
                             # Argument $1 = message
                             # Argument $2 = color
{
local default_msg="No message passed."
                             # Doesn't really need to be a local variable.
message=${1:-$default_msg}   # Defaults to default message.
color=${2:-$white}           # Defaults to black, if not specified.
  echo -e "$color"
  echo "$message"
  tput sgr0                  # Reset to normal.
  return
}
##
## Installation Script for user 'root' on an Ubuntu system to install a ruby on rails production server
##
## This script can be used to automatically install all you need to deploy rails apps on a so far ruby-clean machine.
## Be careful tho, it is not yet thoroughly tested and may contain bugs which may result in unexpected problems.
##
## Still, I hope I got it all right and it would work effortlessly through the whole installation.
## You can of course copy/paste all commands to your console and execute them step by step. If you do so,
## don't forget to replace variables by their intended values.
##
##    if you work through it manually replace occurences of
##        $INSTANTCLIENTDIR
##        $RUBYVERSION
##        $GEMSVERSION
        RUBYVERSION=1.9.1-p376
        GEMSVERSION=1.3.6
##    with the right content
##
## double-##-ed are comments, unindented they start a new installation chapter
## single-#-ed lines usually need some adaptation
## non-#-ed lines usually are copy/pasteable
##
## if you want to use oracle, then please predownload the oracle-instantclient files
## and drop them at /tmp and put the tnsnames.ora file there before running this script
## else disable the oracle installation lines by putting a # infront of the according lines
##
## start installation
    cecho "goto homedirectory" $green
    ## switch to homedirectory
    cd
## make sure no ruby/ruby-remains are on your system
    cecho "uninstall ruby-remains if installed" $green
    apt-get -y remove ruby irb ri
    apt-get -y autoremove
## get the builing package
    cecho "install build-essentials and git-core" $green
    apt-get -y install build-essential zlib1g-dev libssl-dev gzip zip unzip libzip1 libzip-dev git git-core
## download latest ruby (in this case 1.9.1-p376, check www.ruby-lang.org/en/downloads for latest)
    cecho "get Ruby v$RUBYVERSION" $green
    wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-$RUBYVERSION.tar.gz
## unarchive and compile ruby
    cecho "unarchive and compile ruby $RUBYVERSION" $green
    tar -xzf ruby-$RUBYVERSION.tar.gz
    cd ruby-$RUBYVERSION
    ./configure
    make
## install ruby
    cecho "install ruby $RUBYVERSION" $green
    make install
    cd
## download rubygems
    cecho "get rubygems $GEMSVERSION" $green
    wget http://rubyforge.org/frs/download.php/69366/rubygems-$GEMSVERSION.zip
    cecho "unarchive and install rubygems $GEMSVERSION" $green
    unzip rubygems-$GEMSVERSION.zip
    cd rubygems-$GEMSVERSION
    ruby setup.rb
    cd
## install rails
    cecho "install rails3b dependencies needed to be done manually for rails3 beta" $green
    gem install tzinfo builder memcache-client rack rack-test
    gem install erubis mail text-format bundler thor i18n
    gem install rack-mount --version=0.4.0
    cecho "install rails3 beta" $green
    gem install rails --pre
## make sure all databases are installed and ready
## install ruby support for sqlite3, postgres
    cecho "install ruby support for sqlite3 and postgresql" $green
    apt-get -y install sqlite3 postgresql-8.4 libpq-dev libsqlite3-dev
    gem install sqlite3-ruby pg
##
## start oracle addition ## here is whats needed to connect this rails to oracle
##
## comment all lines of this chapter if you don't want/need oracle support
##
    ## first install some untold dependencies for ruby-oci8
    apt-get -y install libaio1 libaio-dev
    ## prepare a directory to hold the instantclient
    mkdir /opt/oracle
    ## adapt the following subparagraph to your version/system architecture
    ## have the oracle instantclient files downloaded as .zip files to /tmp (basic, jdbc and sdk are needed)
    ## NOTE:    this script was written for Version 11.2 of the instantclient and might need
    ##             adaptations for different versions
   
    cecho "trying to find instantclient components looking in /tmp" $green
    ## find oracle-instantclient components
    PARTS=`ls /tmp | grep instantclient-`
    ## install oracle-instantclient components
    cd /opt/oracle
    for ORAFILE in $PARTS
    do
            PART=`echo $ORAFILE | cut -d'-' -f 2`
            ARCH=`echo $ORAFILE | cut -d'-' -f 3`
            VERSION=`echo $ORAFILE | cut -d'-' -f 4`
            VERSION=${VERSION%.zip}
        cecho "unzipping instantclient component $PART for $ARCH v$VERSION" $green
        unzip /tmp/$ORAFILE
    done
    ## define the instantclient directory name
    INSTANTCLIENTDIR=/opt/oracle/`ls /opt/oracle | grep instantclient_`
    mkdir $INSTANTCLIENTDIR/network
    mkdir $INSTANTCLIENTDIR/network/admin
   
    ## place tnsnames.ora, have it located at /tmp
    cecho "trying to find your tnsnames.ora looking in /tmp" $green
    cp /tmp/tnsnames.ora $INSTANTCLIENTDIR/network/admin/tnsnames.ora
    ## set env-vars to environment file for permanent existence after reboot/relogon
    cecho "set oracle environment variables" $green
    echo ORACLE_HOME=$INSTANTCLIENTDIR >> /etc/environment
    echo TNS_ADMIN=$INSTANTCLIENTDIR/network/admin >> /etc/environment
    echo SQLPATH=$INSTANTCLIENTDIR >> /etc/environment
    echo LD_LIBRARY_PATH=$INSTANTCLIENTDIR >> /etc/environment
    ## GERMAN_GERMANY.UTF8 for my personal installation ... default would be US-ASCII, use what you need
    echo NLS_LANG=GERMAN_GERMANY.UTF8 >> /etc/environment
    ## set env-vars to actual session
    export ORACLE_HOME=$INSTANTCLIENTDIR
    export TNS_ADMIN=$INSTANTCLIENTDIR/network/admin
    export SQLPATH=$INSTANTCLIENTDIR
    export LD_LIBRARY_PATH=$INSTANTCLIENTDIR
    export NLS_LANG=GERMAN_GERMANY.UTF8
    ## ubuntu only
        echo # configure oracle instantclient libraries > /etc/ld.so.conf.d/oracle.conf
        echo $INSTANTCLIENTDIR >> /etc/ld.so.conf.d/oracle.conf
        ldconfig       
    ## set symbolic links
    cecho "add symlinks to oracle libs" $green
    ln -s $INSTANTCLIENTDIR/libclntsh.so.11.1 $INSTANTCLIENTDIR/libclntsh.so
    ln -s $INSTANTCLIENTDIR/libocci.so.11.1 $INSTANTCLIENTDIR/libocci.so
    ## install ruby support for oracle
    cecho "install ruby support for oracle" $green
    gem install activerecord-oracle_enhanced-adapter ruby-oci8
## end oracle addition ##
## prepare system to install passenger
    cecho "install dependencies for passenger" $green
    apt-get -y install apache2 apache2-prefork-dev libapr1-dev libaprutil1-dev
## install passenger-gem
    cecho "install passenger gem" $green
    gem install passenger
## install passenger apache2-mod
    cecho "install passenger apache2-mod" $green
    passenger-install-apache2-module
## create passenger apache configuration
    ## ubuntu-specific (adapt to your needs)
    echo LoadModule passenger_module /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.11/ext/apache2/mod_passenger.so > /etc/apache2/mods-available/passenger.load
    echo PassengerRoot /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.11 > /etc/apache2/mods-available/passenger.conf
    echo PassengerRuby /usr/local/bin/passenger-ruby >> /etc/apache2/mods-available/passenger.conf
    a2enmod passenger
    apache2ctl restart
## adapt passenger-ruby wrapper
    cecho "create ruby wrapper for passenger" $green
    echo '#!/bin/sh' > /usr/local/bin/passenger-ruby
    echo 'export LD_LIBRARY_PATH=$INSTANTCLIENTDIR' >> /usr/local/bin/passenger-ruby
    echo 'export NLS_LANG=GERMAN_GERMANY.UTF8' >> /usr/local/bin/passenger-ruby
    echo 'exec "/usr/local/bin/ruby" "$@"' >> /usr/local/bin/passenger-ruby
## deploy your rails-apps
    ## create a new user 'rails'
    cecho "create new user for rails deployment" $green
    useradd -m -s /bin/bash -r rails
    ## dont forget to 'passwd rails' afterwards if you want the account to be ssh-able
    ## create app and apphook-directories
    cecho "create application deployment directories /apps and /hooks in /home/rails" $green
    mkdir /home/rails/apps
    mkdir /home/rails/hooks
    ##     create apache site setup
    echo "## generated by IGambins (igambin@brilliant.de) install-script for a ruby production environment" > /etc/apache2/sites-available/deployRails
    echo '' >> /etc/apache2/sites-available/deployRails
    echo '  ServerName tools' >> /etc/apache2/sites-available/deployRails
    echo '  DocumentRoot /home/rails/hooks' >> /etc/apache2/sites-available/deployRails
    ## in the following line replace app1...app3 by the app-names to be published
    ## don't forget to place the applications into the corresponding directories
    for RAILSAPP in hwmng
    do
        mkdir /home/rails/apps/$RAILSAPP
        mkdir /home/rails/apps/$RAILSAPP/public
         ln -s /home/rails/apps/$RAILSAPP/public /home/rails/hooks/$RAILSAPP
        echo "  RailsBaseURI /$RAILSAPP" >> /etc/apache2/sites-available/deployRails
     done
    echo '  ' >> /etc/apache2/sites-available/deployRails
    echo '    AllowOverride all' >> /etc/apache2/sites-available/deployRails
    echo '    Options -MultiViews' >> /etc/apache2/sites-available/deployRails
    echo '  ' >> /etc/apache2/sites-available/deployRails
    echo '' >> /etc/apache2/sites-available/deployRails
    ## enable apache site setup
    cecho "enable newly configured apache2-configuration 'deployRails'" $green
    a2ensite deployRails
    ## restart apache
    cecho "restart apache2" $green
    /etc/init.d/apache2 restart

Sources:

  • http://www.rubyonrails.org
    rails in general
  • http://oscardelben.com/install-rails-3
    rails3 installation on ubuntu
  • http://http://www.modrails.com/
    good old passenger


2010-03-01

Install Ruby on Rails, Gem and Passenger on Apache on Ubuntu Karmic

Hi,

I wanted to install ruby on rails on my laptop for development purposes. So after finding several resources (see 'chapter IX') I combined what I had to get my system up and running.

In the meantime I played around with RVM though and to purely develop RoR apps I would not use anything else than the RVM approach so far. I will add a new article about the RVM install as soon as possible, but that even is so straight forward, that you could easily follow the installation procedures from the rvm and the rails 3 sites.

Well now to this article and my environment for which I wrote it:
This howto is written for my laptop at work. Its a Dell Latitude D830 Laptop, running a default Ubuntu Karmic Koala (9.10) (Locales set to GERMAN/GERMANY).My workflow basically looks like:
  • work on the code and apply changes/enhancements
  • commit/push the changes to a Mercurial Repository
  • test the changes locally
  • push the changes to the deployment environment, which automatically migrates and updates itself (I will address this topic in my next howto)
  • enjoy the updated production environment
So here is what I usually do to setup my development envionment. Be aware that these instructions will probably only work in an environment like the one I wrote this Howto for. So if you use another Linux, you might have to do things differently, like use different installers, have a different approach to configure apache, etc... Feel free to adapt this howto to your environment and add a comment stating what you had to do differently on your system (including a system description of course).


I. Install RUBY

First thing to do before I install new things is to update my system, so there we go
sudo apt-get update
sudo apt-get upgrade
    In case you get warnings about your locale, just set em right in accordance to your needs, I didn't have any trouble. But if you wanted to set your environment to US english you'd do it like this:
    sudo locale-gen en_US.UTF-8
    sudo /usr/sbin/update-locale LANG=en_US.UTF-8
      Now, before we are going to install ruby, think about which database you will be going to use for your Ruby-Application. I usually like postgresql or if its for local apps i'd vote for sqlite3. But you might also be fond of or used to MySql. So here are 2 options for the default ruby installation including everything (apt-point of view) you need to connect to your favourite database. So either go

      with a MySql co-installation 
      sudo apt-get install ruby ri rdoc mysql-server libmysql-ruby ruby1.8-dev irb1.8 libdbd-mysql-perl libdbi-perl libmysql-ruby1.8 libmysqlclient15off libnet-daemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 mysql-client-5.1 mysql-common mysql-server-5.1 rdoc1.8 ri1.8 ruby1.8 irb libopenssl-ruby libopenssl-ruby1.8 libhtml-template-perl mysql-server-core-5.1 libmysqlclient16 libreadline5 psmisc 
      or a PostgreSql co-installation
      sudo apt-get install ruby ri rdoc ruby1.8-dev irb1.8 libdbi-perl  libnet-daemon-perl libplrpc-perl libreadline-ruby1.8 libruby1.8 rdoc1.8 ri1.8 ruby1.8 irb libopenssl-ruby libopenssl-ruby1.8 libhtml-template-perl libreadline5 psmisc postgresql-8.3 postgresql-8.3-plruby libpq-dev
      Of course after the database stuff is installed you should go and setup your database management system, i. e. setup your admin access, your roles, databases and secure the general access to your database system.

      Now check if the installation also included the non-versioned symlinks to the executable files. Type:
      ruby -v
        and if your system does not respond with something like
        ruby 1.8.7 (2010-01-10 patchlevel 249) [i686-linux]
        then you can set the symlinks yourself using:
        sudo ln -s /usr/bin/ruby1.8 /usr/local/bin/ruby
        sudo ln -s /usr/bin/rdoc1.8 /usr/local/bin/rdoc
        sudo ln -s /usr/bin/ri1.8 /usr/local/bin/ri
        sudo ln -s /usr/bin/irb1.8 /usr/local/bin/irb
          where you might have to change the version identifiers in accordance to the ruby version you use.


          II. Install GEMS

          Check http://rubyforge.org/ for the latest version of "rubygems". Then you can install that using
          wget http://rubyforge.org/frs/download.php/<check online for latest version...>
          tar -xvzf rubygems-.tgz
          cd rubygems-
          sudo ruby setup.rb
            For gem too we want to check if the symlink exists
            gem -v
              and gem usually just returns the version info, e. g.
              1.3.5
              If it does not, just create the symlink for gem like you might have done before for ruby & co.
              sudo ln -s /usr/bin/gem1.8 /usr/local/bin/gem

                 III: Install Rails

                Should be easy and not cause any trouble:
                sudo gem install rails
                  At this point you can continue to install all gems you might be interested in. Some gems I usually install because I just like to have them for form building and database connectivitym, are:
                  • formtastic,  justinfrench-formtastic => great form builder
                  • sqlite3 => for developping local apps
                  • RedCloth => for Wiki-like text formatting support (*xxx* => xxx)
                  • ruby-oci8 => connect to Oracle Databases using OCI8
                  • activerecord-oracle_enhanced-adapter => activerecord plugin to connect to Oracle Database
                  • ruby-pg => connect to postgres databases and/or
                  • mysql-ruby => connect to mysql databases
                  At this point you can stop working this howto, in case you only want to develop on your machine. 

                  But if you want to install deployment too... even if only for deployment testing... here is how you may go on:

                    IV. Install Phusion Passenger to deploy apps to production

                     Agreed, there are many ways to do the "deployment"-part of RoR applications right. Personally, I develop not only in Ruby, I also work occasionally on several C/C++, Java and PHP projects. Because most of the projects I participate in use Mercurial RCS, I got very fond of that lovely tool and therefore here I want to explain what I do to develop and safe my applications using the Mercurial RCS to take care of my code versioning and having Phusion Passenger to collaborate with Apache to deploy my applications "on the fly" when I update my versioning repositories.

                    So to get passenger up and running for production, i first install some background stuff to avoid later dependency troubles:
                    sudo apt-get install libc6 libpcre3 libpcre3-dev libpcrecpp0 libssl0.9.8 libssl-dev zlib1g zlib1g-dev lsb-base
                     and then we install the passenger gem
                    sudo gem install passenger
                    At this point you could call the installation script for passenger (see next step), but on a default ubuntu installation it will probably fail because of a few missing dependencies.Trying does not really hurt, because the installation script will tell you what is missing and name the packages you have to install first. Or you can just do the following install to preempt this problem:
                    sudo apt-get install apache2-prefork-dev libapr1-dev libaprutil1-dev
                    Now we call the passenger installation script:
                    sudo passenger-install-apache2-module

                    V. Configure Phusion Passenger <-> Apache Collaboration

                    We can easily configure Apache to use the passenger module for ruby applications. To do so just (be aware that you might install the software with other versions, so be sure to adapt the version identifiers for your apache configuration)
                    sudo echo 'LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so' >> /etc/apache2/mods-available/passenger.load
                    sudo echo 'PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.9' >> /etc/apache2/mods-available/passenger.conf
                    sudo echo 'PassengerRuby /usr/bin/passenger_ruby_wrapper' >> /etc/apache2/mods-available/passenger.conf
                    And with that last command here you might think "Huh! What is this wrapper stuff doing there ?!?!". It is a pretty common technique to wrap the actual ruby command by a wrapper shell-script in order to load/set environment variables for the passenger configuration to start, because passenger does not access your systems environment variables. The wrapper script would look like
                    #!/bin/sh
                    #Add your environment variables before the exec line, e.g.
                    #export LD_LIBRARY_PATH=/opt/oracle/instantclient_*_*
                    #export NLS_LANG=GERMAN_GERMANY.UTF8
                    #both of which are pretty useful when you want your app to talk to an oracle database
                    exec "/usr/bin/ruby" "$@"
                    Now you can enable the plugin by
                    sudo a2enmod passenger
                    and restarting your apache2 installation by
                    sudo /etc/init.d/apache2 restart

                    VI. Deploy your Rails applications

                    My way to do this on a machine is to create a new user... like 'rails', then I set this users password to something pretty fuzzy, followed by copying my default users public ssh-key to the new users .ssh/authorized_keys... Well thats my way of beeing lazy. I agree I would not actually need to do this as I could do all further commands using sudo... but in my next article I will write about deployment on a remote machine and then this procedure comes in very handy.

                    So to get our applications up and running, I create a 2 new directories in that users home directory.
                    mkdir /home/rails/sources
                    which is the directory where I put copies of my rails application directories, and
                    mkdir /home/rails/apps
                    in which I create symlinks that point to the 'public' directory of the according application directory in the sources tree.

                    So lets say I developed an application called 'moviemng'. To get it deployed, I would
                    sudo cp -r moviemng /home/rails/sources
                    sudo ln -s /home/rails/sources/moviemng/public /home/rails/apps/moviemng
                    No more configuration needed. Just add the symlink to the apache vhost configuration (as described in the following section).


                    VII. Create one apache VHost for all your rails-apps

                    One nice thing about passenger is, that you can have multiple apps accessible by one vhost. That of course would also leave you with the option to create multiple vhosts with one app or even a collection of apps each...

                    A passenger vhost would have the following content (again I use my way, i. e. user rails deploys the production environment in his home directory)

                    <VirtualHost *:80>

                      ServerName www.yourhost.com

                      DocumentRoot /home/rails/apps

                      # Name the symlinks from the
                      # DocumentRoots point of view
                      # to your apps here
                      RailsBaseURI /moviemng

                      <Directory /home/rails/apps>

                        # v-- relax Apache security settings
                        AllowOverride all

                        # v-- MultiViews must be turned off
                        Options -MultiViews

                      </Directory>

                    </VirtualHost>

                    So to add another application 'testapp', of which you have dropped its directory in the '/home/rails/sources' directory and for which you have created a new symlink 'testapp' in '/home/rails/apps' pointing to '/home/rails/sources/testapp/public' you just have to add another
                    RailsBaseURI /testapp
                    and restart your apache
                    sudo /etc/init.d/apache2 restart


                    VIII. Conclusion:


                    From this point on you should have fun working on your rails app while also beeing able to (maybe temporarily, maybe not) deploy your apps locally.
                    This deployment technique also works for remote servers. I will write another howto soon that will cover whats needed to know for that.



                    IX. Sources

                     http://www.hackido.com/2009/11/install-ruby-on-rails-on-ubuntu-karmic.html
                    acually the base source for this article. 'Hackido' has a good collection of lovely howtos for many different things, among which you will find not only ruby, rails and ubuntu information but also mobile stuff and other linux related howtos

                    http://dague.net/2008/05/19/perfect-rails-development-deployment-environment-with-mercurial-and-passenger/
                    this article from Sean had great influence in my final decision to do the whole deployment-stuff with mercurial and phusion passenger. His tag cloud covers a lot of topic of which there for sure are several that might be interesting for the average coding or just purely funhaving internet surfer. I will soon dedicate an article where I will describe this post of Seans set up in my environment.
                    http://www.modrails.com/
                    where Phusion Passenger comes from, good documentation
                    http://ubuntuforums.org/
                    always a great place to start collecting ideas to get your problems solved