Production Server with Rails and Phusion Passenger

First you need to install RVM, ruby, rubygem, rails, with LAMP already installed too.

rvmsudo passenger-install-apache2-module

# to find out where apache config file is
apachectl -V | grep SERVER_CONFIG_FILE

# load modules in Apache config (this may vary)
LoadModule passenger_module /home/vincent/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/ext/apache2/mod_passenger.so
PassengerRoot /home/vincent/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7
PassengerRuby /home/vincent/.rvm/wrappers/ruby-1.9.2-p180/ruby

# now this is an exmple of apache virtualhost
<VirtualHost *:80>
        DocumentRoot /home/www-data/depot/public
        ServerName appname.myserver.com
        <Directory /home/www-data/depot/public>
                AllowOverride all
                Options -MultiViews
        </Directory>

        # Speeds up spawn time tremendously -- if your app is compatible. 
        # RMagick seems to be incompatible with smart spawning
        RailsSpawnMethod smart

        # Keep the application instances alive longer. Default is 300 (seconds)
        PassengerPoolIdleTime 1000

        # Keep the spawners alive, which speeds up spawning a new Application
        # listener after a period of inactivity at the expense of memory.
        RailsAppSpawnerIdleTime 0

        # Additionally keep a copy of the Rails framework in memory. If you're 
        # using multiple apps on the same version of Rails, this will speed up
        # the creation of new RailsAppSpawners. This isn't necessary if you're
        # only running one or 2 applications, or if your applications use
        # different versions of Rails.
        RailsFrameworkSpawnerIdleTime 0

        # Just in case you're leaking memory, restart a listener 
        # after processing 5000 requests
        PassengerMaxRequests 5000

        # only check for restart.txt et al up to once every 5 seconds, 
        # instead of once per processed request
        PassengerStatThrottleRate 5
</VirtualHost>

Create the database needed for the new app, update config/database.yml content to allow app to connect to database on the production server.

Once the new rails app is uploaded to the server:

# install/update bundle
cd appfolder/
bundle install

# now setup database table and data
cd appfolder/
rake db:setup RAILS_ENV=production

Next you use a2ensite and /etc/init.d/apache restart to reload the new site.

Bashrc Profile bits

# Common alias
alias ll='ls -laF'
alias la='ls -A'
alias l='ls -CF'
alias dir='ls -Lla|grep ^d'

# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize

# don't put duplicate lines in the history. See bash(1) for more options
# ... or force ignoredups and ignorespace
HISTCONTROL=ignoredups:ignorespace

# append to the history file, don't overwrite it
shopt -s histappend

# Colorful terminal
export CLICOLOR=1
export LSCOLORS=ExFxCxDxBxegedabagacad

# Set colorful PS1 only on colorful terminals.
# dircolors --print-database uses its own built-in database
# instead of using /etc/DIR_COLORS.  Try to use the external file
# first to take advantage of user additions.  Use internal bash
# globbing instead of external grep binary.
safe_term=${TERM//[^[:alnum:]]/?}   # sanitize TERM
match_lhs=""
[[ -f ~/.dir_colors   ]] && match_lhs="${match_lhs}$(<~/.dir_colors)"
[[ -f /etc/DIR_COLORS ]] && match_lhs="${match_lhs}$(</etc/DIR_COLORS)"
[[ -z ${match_lhs}    ]] \
        && type -P dircolors >/dev/null \
        && match_lhs=$(dircolors --print-database)
[[ $'\n'${match_lhs} == *$'\n'"TERM "${safe_term}* ]] && use_color=true

if ${use_color} ; then
        # Enable colors for ls, etc.  Prefer ~/.dir_colors #64489
        if type -P dircolors >/dev/null ; then
                if [[ -f ~/.dir_colors ]] ; then
                        eval $(dircolors -b ~/.dir_colors)
                elif [[ -f /etc/DIR_COLORS ]] ; then
                        eval $(dircolors -b /etc/DIR_COLORS)
                fi
        fi

        if [[ ${EUID} == 0 ]] ; then
                PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\h\[\033[01;34m\] \W \$\[\033[00m\] '
        else
                PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[01;34m\] \w \$\[\033[00m\] '
        fi

else
        if [[ ${EUID} == 0 ]] ; then
                # show root@ when we don't have colors
                PS1='\u@\h \W \$ '
        else
                PS1='\u@\h \w \$ '
        fi
fi

# Remove variable name pollution 
unset use_color safe_term match_lhs

Setup Git Server (gitolite)

This setup using SSH connection for transfer instead of SVN’s http (webdav).

The gitolite use a default user (e.g. git) to establish a ssh connection, and wrap multiple users management with rsa pub key.

# generate your key if you don't have one
# (use default answers and choose a passphase)
ssh-keygen -v -t rsa -C username@hostname

# transfer the pub key to git server
scp ~/.ssh/id_rsa.pub username@server:username.pub

# add git user that gitolite will run as
# (questions doesnt matter much just remember the password)
sudo adduser git

# let user git own the pub key and move it to git's home
sudo mv username.pub ~git/username.pub
sudo chown git:git ~git/username.pub

# log in as git
su - git

# generate key for user git with no passphase
ssh-keygen -v -t rsa

# get the content of the key and keep it in clipboard for later
cat ~/.ssh/id_rsa.pub

# install gitolite from github
# update: can also sudo apt-get install gitolite
cd /home/git
git clone git://github.com/sitaramc/gitolite gitolite-source
cd gitolite-source
mkdir -p ~/bin ~/share/gitolite/conf ~/share/gitolite/hooks
/home/git/gitolite-source/src/gl-system-install ~/bin ~/share/gitolite/conf ~/share/gitolite/hooks
cd /home/git
/home/git/bin/gl-setup username.pub
rm -f username.pub

# administration of gitolite
# this is done via checking out a copy of the gitolite-admin from server
# and modify its /conf/gitolite.conf file and then push them back after commit locally first
# check out (clone) a copy of gitolite-admin
git clone git@servername:gitolite-admin

# modify conf/gitolite.conf
vim conf/gitolite.conf

# for example to add a new repository
# gitolite.conf content
repo    projectname
        RW+        = username

# and now commit then push back up to create the new repo for projectname
git add -A
git commit -m &quot;add new project repo&quot;
git push

# you can then create a new git (or skip this if using an existing one)
mkdir projectname
cd projectname
git init

# also set up basic stuff like user.name and user.email
git config --global user.name &quot;Vincent Lu&quot;
git config --global user.email vincent.lu@email.com

# now add the new git repo on server as a remote server for the current git local
git remote add origin git@servername:projectname.git
git push origin master

# you can track the remote by adding:
git config branch.master.remote servername
git config branch.master.merge refs/heads/master

# if run into memory issue on server or local, reduce memory usage by:
git config core.packedGitWindowSize 16m
git config core.packedGitLimit 64m
git config pack.windowMemory 64m
git config pack.packSizeLimit 64m
git config pack.thread 1
git config pack.deltaCacheSize 1m

# to add new users
# add access to gitolite-admin/conf/gitolite.conf
repo pluto RW+ = someone
# add key to gitolite-admin/keydir
ssh-keygen -v -t rsa -C someone@hostname
cp ~/.ssh/id_rsa.pub gitolite-admin/keydir/someone.pub
# push change back to server
cd gitolite-admin/
git commit -a -m &quot;add new user someone&quot;
git push

Migrate SVN repository to Git system

# create users.txt for git
touch users.txt
echo "vincent = Vincent Lu " > users.txt

# get git-svn
sudo apt-get install git-core git-svn

# create empty git repository
mkdir newproject
cd newproject
git-svn init http://svn.yoursite.com/oldproject/trunk --no-metadata
git config svn.authorsfile users.txt
git-svn fetch

# clone the git repository created by git-svn fetch
cd ..
git clone newproject myproject