<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>kris.me.uk</title>
 <link href="http://kris.me.uk/atom.xml" rel="self"/>
 <link href="http://kris.me.uk/"/>
 <updated>2015-12-26T12:20:07+00:00</updated>
 <id>http://kris.me.uk/</id>
 <author>
   <name>Kris Brown</name>
   <email>kris@kris.me.uk</email>
 </author>

 
 <entry>
   <title>Send Email on OS X Yosemite through GMail</title>
   <link href="http://kris.me.uk/2015/03/05/send-email-on-osx-yosemite-through-gmail.html"/>
   <updated>2015-03-05T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2015/03/05/send-email-on-osx-yosemite-through-gmail</id>
   <content type="html">&lt;p&gt;This guide covers how to utilise the installed postfix program so that it relays local email through google mail.  I predominately use this for notifications such as logs of cron tasks that have run.  This guide borrows heavily from the references listed at the end.&lt;/p&gt;

&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;/h2&gt;

&lt;h3 id=&quot;launch-configuration&quot;&gt;Launch configuration&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/System/Library/LaunchDaemons/org.postfix.master.plist&lt;/code&gt; to include OnDemand key.  The resulting file should look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
&amp;lt;dict&amp;gt;
  &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;
  &amp;lt;string&amp;gt;org.postfix.master&amp;lt;/string&amp;gt;
  &amp;lt;key&amp;gt;Program&amp;lt;/key&amp;gt;
  &amp;lt;string&amp;gt;/usr/libexec/postfix/master&amp;lt;/string&amp;gt;
  &amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;
  &amp;lt;array&amp;gt;
    &amp;lt;string&amp;gt;master&amp;lt;/string&amp;gt;
    &amp;lt;string&amp;gt;-e&amp;lt;/string&amp;gt;
    &amp;lt;string&amp;gt;60&amp;lt;/string&amp;gt;
  &amp;lt;/array&amp;gt;
  &amp;lt;key&amp;gt;QueueDirectories&amp;lt;/key&amp;gt;
  &amp;lt;array&amp;gt;
    &amp;lt;string&amp;gt;/Library/Server/Mail/Data/spool/maildrop&amp;lt;/string&amp;gt;
  &amp;lt;/array&amp;gt;
  &amp;lt;key&amp;gt;AbandonProcessGroup&amp;lt;/key&amp;gt;
  &amp;lt;true/&amp;gt;
  &amp;lt;key&amp;gt;OnDemand&amp;lt;/key&amp;gt;
  &amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;postfix-main-configuration&quot;&gt;Postfix main configuration&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/main.cf&lt;/code&gt; to include necessary configuration.  Add the following to the end of the file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;relayhost = smtp.gmail.com:587
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_loglevel=1
smtp_tls_security_level=encrypt
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: the &lt;code&gt;smtp_sasl_mechanism_filter&lt;/code&gt; option was required since Yosemite.&lt;/p&gt;

&lt;h3 id=&quot;postfix-aliases&quot;&gt;Postfix aliases&lt;/h3&gt;

&lt;p&gt;First, note the username of the user you wish to receive root’s email.  If logged in as the user, you can check the value by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;whoami
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/aliases&lt;/code&gt; enabling root email to be aliased to your user.  Change the following line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#root:    you
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;by uncommenting and changing you to your username, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root:    username
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You need to then run &lt;code&gt;newaliases&lt;/code&gt; to pick up the modifications:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /etc/postfix
sudo newaliases
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;postfix-local-email-to-gmail-mappings&quot;&gt;Postfix local email to gmail mappings&lt;/h3&gt;

&lt;p&gt;In order to configure correctly, note the user and hostname you want to map:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;whoami
hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/generic&lt;/code&gt; adding mappings of local email to gmail accounts, substituting username, hostname and gmailaccount as appropriate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;username@hostname gmailaccount
@hostname gmailaccount
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You need to then run &lt;code&gt;postmap&lt;/code&gt; to pick up the modifications:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /etc/postfix
sudo postmap generic
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;smtp-password&quot;&gt;SMTP password&lt;/h3&gt;

&lt;p&gt;Ensure that the password file exists:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /etc/postfix
sudo touch sasl_passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/sasl_passwd&lt;/code&gt; adding the details for gmail:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;smtp.gmail.com:587 gmailaccount:gmailpassword
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Rebuild the postmap database file and delete the raw file containing the raw password:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo postmap sasl_passwd
sudo rm sasl_passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;forwarding-using-forward&quot;&gt;Forwarding using .forward&lt;/h3&gt;

&lt;p&gt;Individual users can use sendmail forwarding by creating &lt;code&gt;~/.forward&lt;/code&gt; containing only the email address to forward to.  This will override the accounts configured above, allowing someone without sudo permissions to configure their desired email address.&lt;/p&gt;

&lt;h2 id=&quot;run-postfix&quot;&gt;Run postfix&lt;/h2&gt;

&lt;p&gt;Run the following commands to ensure postfix is running with the latest configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl unload -w /System/Library/LaunchDaemons/org.postfix.master.plist
sudo launchctl load -w /System/Library/LaunchDaemons/org.postfix.master.plist
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;h3 id=&quot;sending-to-root&quot;&gt;Sending to root&lt;/h3&gt;

&lt;p&gt;Run the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo $(date) | mail -s &quot;test&quot; root
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;sending-to-username&quot;&gt;Sending to username&lt;/h3&gt;

&lt;p&gt;Run the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo $(date) | mail -s &quot;test&quot; username
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;sending-an-external-email&quot;&gt;Sending an external email&lt;/h3&gt;

&lt;p&gt;Run the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo $(date) | mail -s &quot;test&quot; user@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;problems&quot;&gt;Problems&lt;/h2&gt;

&lt;p&gt;If email is not working, the following may help.&lt;/p&gt;

&lt;h3 id=&quot;tailing-the-mail-logs&quot;&gt;Tailing the mail logs&lt;/h3&gt;

&lt;p&gt;You can look at and tail the mail log for details of what is happening.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tail -f /var/log/mail.log
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;spool-directory-not-found&quot;&gt;Spool directory not found&lt;/h3&gt;

&lt;p&gt;If you get the following error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sendmail: fatal: chdir /Library/Server/Mail/Data/spool: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run the following commands to fix it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir -p /Library/Server/Mail/Data/spool
sudo gzip /usr/share/man/man1/{postalias.1,postcat.1,postconf.1,postdrop.1,postfix.1,postkick.1,postlock.1,postlog.1,postmap.1,postmulti.1,postqueue.1,postsuper.1,sendmail.1}
sudo gzip /usr/share/man/man5/{access.5,aliases.5,bounce.5,canonical.5,cidr_table.5,generic.5,header_checks.5,ldap_table.5,master.5,mysql_table.5,nisplus_table.5,pcre_table.5,pgsql_table.5,postconf.5,postfix-wrapper.5,regexp_table.5,relocated.5,tcp_table.5,transport.5,virtual.5}
sudo gzip /usr/share/man/man8/{anvil.8,bounce.8,cleanup.8,discard.8,error.8,flush.8,local.8,master.8,oqmgr.8,pickup.8,pipe.8,proxymap.8,qmgr.8,qmqpd.8,scache.8,showq.8,smtp.8,smtpd.8,spawn.8,tlsmgr.8,trivial-rewrite.8,verify.8,virtual.8}
sudo /usr/sbin/postfix set-permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.postfix.org/documentation.html&quot;&gt;Postfix Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.riverturn.com/blog/?p=239&quot;&gt;http://www.riverturn.com/blog/?p=239&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://slashusr.wordpress.com/2012/02/14/enabling-postfix-for-outbound-relay-via-gmail-on-os-x-lion-11/&quot;&gt;http://slashusr.wordpress.com/2012/02/14/enabling-postfix-for-outbound-relay-via-gmail-on-os-x-lion-11/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://apple.stackexchange.com/questions/54051/sendmail-error-on-os-x-mountain-lion&quot;&gt;http://apple.stackexchange.com/questions/54051/sendmail-error-on-os-x-mountain-lion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Send Email on OS X Lion through GMail</title>
   <link href="http://kris.me.uk/2013/02/23/send-email-on-osx-lion-through-gmail.html"/>
   <updated>2013-02-23T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2013/02/23/send-email-on-osx-lion-through-gmail</id>
   <content type="html">&lt;p&gt;This guide covers how to utilise the installed postfix program so that it relays local email through google mail.  I predominately use this for notifications such as logs of cron tasks that have run.  This guide borrows heavily from the references listed at the end.&lt;/p&gt;

&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;/h2&gt;

&lt;h3 id=&quot;launch-configuration&quot;&gt;Launch configuration&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/System/Library/LaunchDaemons/org.postfix.master.plist&lt;/code&gt; to include OnDemand key.  The resulting file should look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple Computer//DTD PLIST 1.0//EN&quot; &quot;http://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&amp;gt;
&amp;lt;plist version=&quot;1.0&quot;&amp;gt;
&amp;lt;dict&amp;gt;
  &amp;lt;key&amp;gt;Label&amp;lt;/key&amp;gt;
  &amp;lt;string&amp;gt;org.postfix.master&amp;lt;/string&amp;gt;
  &amp;lt;key&amp;gt;Program&amp;lt;/key&amp;gt;
  &amp;lt;string&amp;gt;/usr/libexec/postfix/master&amp;lt;/string&amp;gt;
  &amp;lt;key&amp;gt;ProgramArguments&amp;lt;/key&amp;gt;
  &amp;lt;array&amp;gt;
    &amp;lt;string&amp;gt;master&amp;lt;/string&amp;gt;
    &amp;lt;string&amp;gt;-e&amp;lt;/string&amp;gt;
    &amp;lt;string&amp;gt;60&amp;lt;/string&amp;gt;
  &amp;lt;/array&amp;gt;
  &amp;lt;key&amp;gt;QueueDirectories&amp;lt;/key&amp;gt;
  &amp;lt;array&amp;gt;
    &amp;lt;string&amp;gt;/Library/Server/Mail/Data/spool/maildrop&amp;lt;/string&amp;gt;
  &amp;lt;/array&amp;gt;
  &amp;lt;key&amp;gt;AbandonProcessGroup&amp;lt;/key&amp;gt;
  &amp;lt;true/&amp;gt;
  &amp;lt;key&amp;gt;OnDemand&amp;lt;/key&amp;gt;
  &amp;lt;true/&amp;gt;
&amp;lt;/dict&amp;gt;
&amp;lt;/plist&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;postfix-main-configuration&quot;&gt;Postfix main configuration&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/main.cf&lt;/code&gt; to include necessary configuration.  Add the following to the end of the file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;relayhost = smtp.gmail.com:587
smtp_generic_maps = hash:/etc/postfix/generic
smtp_tls_loglevel=1
smtp_tls_security_level=encrypt
smtp_sasl_auth_enable=yes
smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;postfix-aliases&quot;&gt;Postfix aliases&lt;/h3&gt;

&lt;p&gt;First, note the username of the user you wish to receive root’s email.  If logged in as the user, you can check the value by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;whoami
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/aliases&lt;/code&gt; enabling root email to be aliased to your user.  Change the following line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#root:    you
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;by uncommenting and changing you to your username, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root:    username
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You need to then run &lt;code&gt;newaliases&lt;/code&gt; to pick up the modifications:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /etc/postfix
sudo newaliases
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;postfix-local-email-to-gmail-mappings&quot;&gt;Postfix local email to gmail mappings&lt;/h3&gt;

&lt;p&gt;In order to configure correctly, note the user and hostname you want to map:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;whoami
hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/generic&lt;/code&gt; adding mappings of local email to gmail accounts, substituting username, hostname and gmailaccount as appropriate:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;username@hostname gmailaccount
@hostname gmailaccount
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You need to then run &lt;code&gt;postmap&lt;/code&gt; to pick up the modifications:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /etc/postfix
sudo postmap generic
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;smtp-password&quot;&gt;SMTP password&lt;/h3&gt;

&lt;p&gt;Ensure that the password file exists:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /etc/postfix
sudo touch sasl_passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/postfix/sasl_passwd&lt;/code&gt; adding the details for gmail:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;smtp.gmail.com:587 gmailaccount:gmailpassword
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Rebuild the postmap database file and delete the raw file containing the raw password:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo postmap sasl_passwd
sudo rm sasl_passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;forwarding-using-forward&quot;&gt;Forwarding using .forward&lt;/h3&gt;

&lt;p&gt;Individual users can use sendmail forwarding by creating &lt;code&gt;~/.forward&lt;/code&gt; containing only the email address to forward to.  This will override the accounts configured above, allowing someone without sudo permissions to configure their desired email address.&lt;/p&gt;

&lt;h2 id=&quot;run-postfix&quot;&gt;Run postfix&lt;/h2&gt;

&lt;p&gt;Run the following commands to ensure postfix is running with the latest configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo launchctl unload -w /System/Library/LaunchDaemons/org.postfix.master.plist
sudo launchctl load -w /System/Library/LaunchDaemons/org.postfix.master.plist
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;h3 id=&quot;sending-to-root&quot;&gt;Sending to root&lt;/h3&gt;

&lt;p&gt;Try the following at a command prompt, filling in the prompts:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mail root
Subject: Test root
&amp;lt;CTRL+D&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;sending-to-username&quot;&gt;Sending to username&lt;/h3&gt;

&lt;p&gt;Try the following at a command prompt, filling in the prompts:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mail username
Subject: Test username
&amp;lt;CTRL+D&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;sending-an-external-email&quot;&gt;Sending an external email&lt;/h3&gt;

&lt;p&gt;Try the following at a command prompt, filling in the prompts:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mail user@example.com
Subject: Test email
&amp;lt;CTRL+D&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;problems&quot;&gt;Problems&lt;/h2&gt;

&lt;p&gt;If email is not working, the following may help.&lt;/p&gt;

&lt;h3 id=&quot;tailing-the-mail-logs&quot;&gt;Tailing the mail logs&lt;/h3&gt;

&lt;p&gt;You can look at and tail the mail log for details of what is happening.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tail -f /var/log/mail.log
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;spool-directory-not-found&quot;&gt;Spool directory not found&lt;/h3&gt;

&lt;p&gt;If you get the following error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sendmail: fatal: chdir /Library/Server/Mail/Data/spool: No such file or directory
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run the following commands to fix it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir -p /Library/Server/Mail/Data/spool
sudo gzip /usr/share/man/man1/{postalias.1,postcat.1,postconf.1,postdrop.1,postfix.1,postkick.1,postlock.1,postlog.1,postmap.1,postmulti.1,postqueue.1,postsuper.1,sendmail.1}
sudo gzip /usr/share/man/man5/{access.5,aliases.5,bounce.5,canonical.5,cidr_table.5,generic.5,header_checks.5,ldap_table.5,master.5,mysql_table.5,nisplus_table.5,pcre_table.5,pgsql_table.5,postconf.5,postfix-wrapper.5,regexp_table.5,relocated.5,tcp_table.5,transport.5,virtual.5}
sudo gzip /usr/share/man/man8/{anvil.8,bounce.8,cleanup.8,discard.8,error.8,flush.8,local.8,master.8,oqmgr.8,pickup.8,pipe.8,proxymap.8,qmgr.8,qmqpd.8,scache.8,showq.8,smtp.8,smtpd.8,spawn.8,tlsmgr.8,trivial-rewrite.8,verify.8,virtual.8}
sudo /usr/sbin/postfix set-permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.postfix.org/documentation.html&quot;&gt;Postfix Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.riverturn.com/blog/?p=239&quot;&gt;http://www.riverturn.com/blog/?p=239&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://slashusr.wordpress.com/2012/02/14/enabling-postfix-for-outbound-relay-via-gmail-on-os-x-lion-11/&quot;&gt;http://slashusr.wordpress.com/2012/02/14/enabling-postfix-for-outbound-relay-via-gmail-on-os-x-lion-11/&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://apple.stackexchange.com/questions/54051/sendmail-error-on-os-x-mountain-lion&quot;&gt;http://apple.stackexchange.com/questions/54051/sendmail-error-on-os-x-mountain-lion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Mountain Lion with Favourite Apps</title>
   <link href="http://kris.me.uk/2012/09/22/mountain-lion-with-favourite-apps.html"/>
   <updated>2012-09-22T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2012/09/22/mountain-lion-with-favourite-apps</id>
   <content type="html">&lt;p&gt;With mountain lion being out, I decided it was time to do a &lt;a href=&quot;http://eggfreckles.net/notes/installing-mountain-lion-clean/&quot;&gt;clean install&lt;/a&gt; and rid my system of the clutter I’ve accumulated over the last few years.&lt;/p&gt;

&lt;p&gt;When choosing applications to use I am mindful of not only how useable they are but also whether or not they are open source or low cost and can be used on other platforms so the knowledge and skills are transferable where possible.  I’ve tried to loosely group these into sensible themes.  Where these apps are available in the app store I’ve included a link for that also.&lt;/p&gt;

&lt;h2 id=&quot;file-system-browser&quot;&gt;File System Browser&lt;/h2&gt;

&lt;p&gt;Finder does not offer the filesystem visibility that I like, so I use &lt;a href=&quot;http://cocoatech.com/pathfinder/&quot;&gt;PathFinder&lt;/a&gt; when I need a little more power.&lt;/p&gt;

&lt;h2 id=&quot;web-browser&quot;&gt;Web Browser&lt;/h2&gt;

&lt;p&gt;I use &lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Google Chrome&lt;/a&gt; and occasionally &lt;a href=&quot;http://www.mozilla.com/en-US/firefox/&quot;&gt;Firefox&lt;/a&gt; depending on what I’m doing and how well the sites work in the browsers.&lt;/p&gt;

&lt;p&gt;To synchronise browser information, I use &lt;a href=&quot;http://www.xmarks.com&quot;&gt;Xmarks&lt;/a&gt; and &lt;a href=&quot;https://lastpass.com/&quot;&gt;LastPass&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For Chrome I use the following plugins for general use:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add to Amazon Wishlist&lt;/li&gt;
  &lt;li&gt;Google Calendar Checker&lt;/li&gt;
  &lt;li&gt;Google Dictionary&lt;/li&gt;
  &lt;li&gt;Google Mail Checker&lt;/li&gt;
  &lt;li&gt;Google Reader Notifier&lt;/li&gt;
  &lt;li&gt;Google Similar Pages&lt;/li&gt;
  &lt;li&gt;Lastpass&lt;/li&gt;
  &lt;li&gt;Microformats for Google Chrome&lt;/li&gt;
  &lt;li&gt;Pocket&lt;/li&gt;
  &lt;li&gt;RSS Subscriptions Extension&lt;/li&gt;
  &lt;li&gt;Session Buddy&lt;/li&gt;
  &lt;li&gt;The Camelizer&lt;/li&gt;
  &lt;li&gt;Xmarks Bookmarks Sync&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And the follow plugins for development:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Firebug Lite&lt;/li&gt;
  &lt;li&gt;JSONView&lt;/li&gt;
  &lt;li&gt;LiveReload&lt;/li&gt;
  &lt;li&gt;PageSpeed Insights&lt;/li&gt;
  &lt;li&gt;Speed Tracer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;resource-monitoring&quot;&gt;Resource Monitoring&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://bjango.com/mac/istatmenus/&quot;&gt;iStat Menus&lt;/a&gt; provides the slickest resource monitoring for the menubar.  I end up ditching most of the standard menubar icons by holding down  ⌘ and dragging them off.&lt;/p&gt;

&lt;h2 id=&quot;notifications&quot;&gt;Notifications&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.growl.info/&quot;&gt;Growl&lt;/a&gt; was the defacto notification system for OS X, though this may change now that mountain lion has notifications built in.  For now I’m keeping it around till there is more support for native notifications.  Many applications utilise growl if installed.  I use &lt;a href=&quot;http://itunes.apple.com/gb/app/hardwaregrowler/id475260933&quot;&gt;HardwareGrowler&lt;/a&gt; too.&lt;/p&gt;

&lt;h2 id=&quot;instant-messaging&quot;&gt;Instant messaging&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://adium.im/&quot;&gt;Adium&lt;/a&gt; is a generic chat client with support for most chat protocols that also integrates with &lt;a href=&quot;http://www.growl.info/&quot;&gt;Growl&lt;/a&gt;.  &lt;a href=&quot;http://www.skype.com/&quot;&gt;Skype&lt;/a&gt; is also very good and can be used for messaging, voice calls and video calls.&lt;/p&gt;

&lt;h2 id=&quot;ftp&quot;&gt;FTP&lt;/h2&gt;

&lt;h3 id=&quot;ftp-client&quot;&gt;FTP Client&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://filezilla-project.org/&quot;&gt;Filezilla&lt;/a&gt; is a free, open source, cross platform ftp client.  &lt;a href=&quot;http://cyberduck.ch/&quot;&gt;Cyberduck&lt;/a&gt; is a free, open source FTP, SFTP, WebDav and cloud browser for Mac OS-X.  For those happy to spend a few coins, &lt;a href=&quot;http://panic.com/transmit/&quot;&gt;Transit&lt;/a&gt; is highly commended.&lt;/p&gt;

&lt;h2 id=&quot;media&quot;&gt;Media&lt;/h2&gt;

&lt;h3 id=&quot;player&quot;&gt;Player&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.videolan.org/&quot;&gt;VLC&lt;/a&gt; is a really good cross platform media player with support for most formats.&lt;/p&gt;

&lt;h3 id=&quot;transcoder&quot;&gt;Transcoder&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://handbrake.fr/&quot;&gt;Handbrake&lt;/a&gt; is a good cross platform video transcoder.&lt;/p&gt;

&lt;h3 id=&quot;little-app-factory&quot;&gt;Little App Factory&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://thelittleappfactory.com/&quot;&gt;Little App Factory&lt;/a&gt; do a number of cool little apps, such as &lt;a href=&quot;http://thelittleappfactory.com/ripit/&quot;&gt;ripit&lt;/a&gt; and &lt;a href=&quot;http://thelittleappfactory.com/tagalicious/&quot;&gt;tagalicious&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;sync&quot;&gt;Sync&lt;/h2&gt;

&lt;h3 id=&quot;dropbox&quot;&gt;Dropbox&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.dropbox.com/referrals/NTEwNDg0MjI5&quot;&gt;Dropbox&lt;/a&gt; only syncs files you put into it but has the advantage that its software as a service and therefore a backup is stored on a server and you can also access files through the website or mobile phone applications.  Its free for up to 2GB of storage and this can be extended through referrals and rewards through participation in events, and you can pay for larger storage needs.&lt;/p&gt;

&lt;h2 id=&quot;text-editor&quot;&gt;Text Editor&lt;/h2&gt;

&lt;p&gt;There are quite a number of text editors available, however, there is a lot of support for &lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt; on the mac.  If you are happy with the command line, vim is very popular especially when used with tmux.  &lt;a href=&quot;http://www.sublimetext.com/&quot;&gt;Sublime Text&lt;/a&gt; has been gaining a lot of popularity recently also.&lt;/p&gt;

&lt;h2 id=&quot;screen-grabber&quot;&gt;Screen grabber&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.skitch.com&quot;&gt;Skitch&lt;/a&gt; is a really good screen grabber and editor.&lt;/p&gt;

&lt;h2 id=&quot;image-editor&quot;&gt;Image Editor&lt;/h2&gt;

&lt;p&gt;There are numerous image editors available at varying costs.  For most needs, I highly recommend &lt;a href=&quot;http://www.pinta-project.com/&quot;&gt;Pinta&lt;/a&gt; which is based on Paint.NET for windows.&lt;/p&gt;

&lt;h2 id=&quot;launcher&quot;&gt;Launcher&lt;/h2&gt;

&lt;p&gt;Spotlight is pretty good, but &lt;a href=&quot;http://www.alfredapp.com&quot;&gt;Alfred&lt;/a&gt; is even better.  Launch what you want quickly and intuitively with some nice extra features thrown in.&lt;/p&gt;

&lt;h2 id=&quot;general-development&quot;&gt;General Development&lt;/h2&gt;

&lt;h3 id=&quot;terminal&quot;&gt;Terminal&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://iterm2.com/&quot;&gt;iTerm2&lt;/a&gt; is a terminal replacement that supports tmux and panels.  Very useful when working predominately in the terminal.&lt;/p&gt;

&lt;h3 id=&quot;xcode&quot;&gt;XCode&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.apple.com/tools/xcode/&quot;&gt;Xcode&lt;/a&gt; is a suite of development tools used to create Mac and iPhone applications.  It provides a number of building blocks for other applications, such as build tools and compilers.  Make sure you install the command line tools too from the preferences -&amp;gt; downloads dialog once xcode itself is installed.&lt;/p&gt;

&lt;h3 id=&quot;xquartz&quot;&gt;XQuartz&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://xquartz.macosforge.org/&quot;&gt;XQuartz&lt;/a&gt; is a version of X Windows that runs on OS X.  It is used by some cross platform tools.&lt;/p&gt;

&lt;h3 id=&quot;homebrew&quot;&gt;Homebrew&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/mxcl/homebrew&quot;&gt;Homebrew&lt;/a&gt; is the best package manager for OS X.  XCode and XQuartz are prerequisites for some packages (aka formulae in homebrew), providing &lt;code&gt;gcc&lt;/code&gt; and other important tools.  Be sure to run &lt;code&gt;brew doctor&lt;/code&gt; to ensure you have the right configuration.&lt;/p&gt;

&lt;h3 id=&quot;ruby&quot;&gt;Ruby&lt;/h3&gt;

&lt;p&gt;Ruby is a great programming language and has packages that are called gems.  Some gems contain binaries and are therefore executable from the terminal.&lt;/p&gt;

&lt;p&gt;To manage the ruby environment, it is useful to an environment manager.  &lt;a href=&quot;https://github.com/sstephenson/rbenv/&quot;&gt;rbenv&lt;/a&gt; and &lt;a href=&quot;https://github.com/sstephenson/ruby-build&quot;&gt;ruby-build&lt;/a&gt; take a lightweight approach, whereas &lt;a href=&quot;http://rvm.io&quot;&gt;RVM&lt;/a&gt; is a collection of tools for ruby development.&lt;/p&gt;

&lt;h3 id=&quot;java&quot;&gt;Java&lt;/h3&gt;

&lt;p&gt;Java is not installed by default on mountain lion, but simply running &lt;code&gt;java -version&lt;/code&gt; from the terminal will ensure it installs, prompting you as appropriate.  Over time, Oracle will be taking on the responsibility of providing java packages for OS X.&lt;/p&gt;

&lt;h3 id=&quot;base-packages&quot;&gt;Base Packages&lt;/h3&gt;

&lt;p&gt;I use the following script to populate base packages / gems / eggs / npms:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
brew install ack bash-completion curl dos2unix readline rename tmux tree wakeonlan wget zsh
brew install gist git imagemagick subversion xmlstarlet
brew install mongodb mysql postgresql redis riak sqlite
brew install rbenv ruby-build
brew install node
brew install maven
brew install python

# java stuff - this forces install on mountain lion
java -version

# ruby stuff
if [ ! -d ~/.rbenv/versions/1.9.3-p194 ] ; then
  rbenv install 1.9.3-p194
  rbenv global 1.9.3-p194
  gem install --no-rdoc --no-ri bundler yard pry whenever lunchy
  gem install --no-rdoc --no-ri rails cucumber-rails rspec-rails capistrano
  rbenv rehash
fi

# python stuff
pip install jsonpipe pygments

# npm for node
npm install -g coffee-script
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;zsh&quot;&gt;zsh&lt;/h3&gt;

&lt;p&gt;zsh seems to be the way to go these days over bash.  If you want to use the latest version from homebrew, you will need to register it as outlined in the info showed after installing, i.e. adding &lt;code&gt;/usr/local/bin/zsh&lt;/code&gt; to &lt;code&gt;/etc/shells&lt;/code&gt;.  &lt;a href=&quot;https://github.com/robbyrussell/oh-my-zsh/&quot;&gt;oh-my-zsh&lt;/a&gt; is a good collection of zsh goodness to get you started which does most of the hardwork for you, including switching your default shell.&lt;/p&gt;

&lt;h3 id=&quot;git-gui&quot;&gt;Git GUI&lt;/h3&gt;

&lt;p&gt;There are a few good git graphical user interfaces, &lt;a href=&quot;http://www.sourcetreeapp.com/&quot;&gt;SourceTree&lt;/a&gt;, &lt;a href=&quot;http://mac.github.com/&quot;&gt;Github for Mac&lt;/a&gt; and &lt;a href=&quot;http://gitx.laullon.com/&quot;&gt;GitX fork by Laullon&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Rails 3.1 / Rack App Hosting with RVM, Passenger 3, Capistrano, Git and Apache</title>
   <link href="http://kris.me.uk/2011/10/28/rails-rvm-passenger-capistrano-git-apache.html"/>
   <updated>2011-10-28T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2011/10/28/rails-rvm-passenger-capistrano-git-apache</id>
   <content type="html">&lt;p&gt;This guide supersedes a number of &lt;a href=&quot;/2010/08/30/rails3-hosting-all-in-one.html&quot;&gt;earlier&lt;/a&gt; &lt;a href=&quot;/2010/11/15/rails3-rvm-passenger3-apache.html&quot;&gt;guides&lt;/a&gt;, providing the details to get up and running with a rack based application from a basic ubuntu server VPS.  It is a walkthrough of the steps taken, and it is advisable to first read the installation instructions provided by the software authors.&lt;/p&gt;

&lt;p&gt;At the time of writing, the latest versions of the software in use are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;RVM: 1.9.0&lt;/li&gt;
  &lt;li&gt;Ruby: 1.9.2-p290&lt;/li&gt;
  &lt;li&gt;Passenger: 3.0.9&lt;/li&gt;
  &lt;li&gt;Rails: 3.1.1&lt;/li&gt;
  &lt;li&gt;Capistrano: 2.9.0&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may need to alter the versions in the steps below as some commands and paths contain explicit versions.  The server used for hosting in the guide is an &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS&lt;/a&gt;, so tailor the steps to your platform accordingly.  Also, substitute &lt;em&gt;domainname&lt;/em&gt;, &lt;em&gt;hostname&lt;/em&gt; and &lt;em&gt;appname&lt;/em&gt; as appropriate for your environment.&lt;/p&gt;

&lt;h2 id=&quot;rvm-multi-user-install&quot;&gt;RVM Multi User Install&lt;/h2&gt;

&lt;p&gt;RVM can be installed for multiple users by installing as root.  This allows installations to be shared across different users, although different users can use which ever version they wish.&lt;/p&gt;

&lt;p&gt;Log in as root and install using the preferred script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bash &amp;lt; &amp;lt;(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order for a user to use the multi user RVM installation the must belong to the rvm group.  Also check that they do not have a &lt;code&gt;~/.rvm&lt;/code&gt; directory as this takes precedence over the multi user install for that user.&lt;/p&gt;

&lt;h2 id=&quot;create-passenger-user&quot;&gt;Create Passenger User&lt;/h2&gt;

&lt;p&gt;It is a good idea to create a passenger user on the server to install services as so that it is isolated from other users.  You can also deploy your applications using this user.  The passenger user needs sudo rights for installing packages using apt-get and running the passenger install script, and needs to be a member of the rvm group to use the multi user install.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser passenger
sudo usermod -G passenger,www-data,sudo,rvm passenger
su - passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can remove the sudo right after completing the installation using the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo usermod -G passenger,www-data,rvm passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Generate a key pair for ssh too.  On your client machine, create a key and use a string pass phrase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -v -t rsa -f passenger@domainname -C passenger@domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a private key called &lt;code&gt;passenger@domainname&lt;/code&gt; and a public key called &lt;code&gt;passenger@domainname.pub&lt;/code&gt;.  Keep these somewhere safe.&lt;/p&gt;

&lt;p&gt;You can register the public key into authorized_keys to allow key based ssh authentication.  Run the following on your client machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp passenger@domainname.pub passenger@hostname:~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depending on the client and your preference, you can either enter the passphrase for you private key each time you connect, or run &lt;code&gt;ssh-agent&lt;/code&gt; and register the key using &lt;code&gt;ssh-add&lt;/code&gt;.  To register the private key into your ssh agent on your client machine run the following and enter the passphrase when prompted:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-add passenger@domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to ssh to the server without being challenged for the password, e.g:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh passenger@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;passenger-rvm-configuration&quot;&gt;Passenger RVM Configuration&lt;/h2&gt;

&lt;p&gt;Note: if you previously had RVM installed as a single user you need to remove the old source line for &lt;code&gt;$HOME/.rvm/scripts/rvm&lt;/code&gt; and move (or delete) the .rvm directory so that the system wide installation is picked up instead.&lt;/p&gt;

&lt;p&gt;Log out and log in again as passenger to ensure the scripts work as expected.  You can test RVM is available correctly by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;type rvm | head -n1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should then see the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm is a function
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can view the requirements for installing the different rubies by running &lt;code&gt;rvm requirements&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To install the packages (requires sudo):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev ncurses-dev automake libtool bison subversion
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To install ruby 1.9.2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm install 1.9.2
rvm use --default 1.9.2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can can now verify the ruby version and install some gems, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby -v
gem install bundler rails
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;passenger&quot;&gt;Passenger&lt;/h2&gt;

&lt;p&gt;Passenger is very easy to install.  RVM provides some &lt;a href=&quot;http://rvm.beginrescueend.com/integration/passenger/&quot;&gt;instructions&lt;/a&gt; specifically for passenger.&lt;/p&gt;

&lt;p&gt;Install the gem and run the installation script.  It will tell you what dependencies you are missing and how to install them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install passenger
passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Passenger provides some instructions on how to configure apache.  I like to treat passenger as a mod for apache, allowing it to be enabled and disabled as required through the &lt;code&gt;a2enmod&lt;/code&gt; and &lt;code&gt;a2dismod&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;To enable passenger, create &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and &lt;code&gt;/etc/apache2/mods-available/passenger.conf&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9
PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p290/ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then enable the module and restart apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod passenger
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;apache&quot;&gt;Apache&lt;/h2&gt;

&lt;p&gt;Each rack/rails application is made available through a virtual host directive in the apache configuration.  The recommended way to do this is to create a file named after the site, e.g. &lt;code&gt;domainname&lt;/code&gt; in &lt;code&gt;/etc/apache2/sites-available&lt;/code&gt; and then enable and disable the site as required using the &lt;code&gt;a2ensite&lt;/code&gt; and &lt;code&gt;a2dissite&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;I prefer to put all web applications in &lt;code&gt;/var/www&lt;/code&gt; and have users be able to create applications if they are a member of &lt;code&gt;www-data&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo chmod g+w /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;hello-world-rack-app&quot;&gt;Hello World rack app&lt;/h3&gt;

&lt;p&gt;I find it useful to have a simple Hello World rack application to verify the rvm and passenger installation.  The application can be run as a subdomain to allow testing and can be enabled and disabled as desired.&lt;/p&gt;

&lt;p&gt;Create the necessary directory structure for a rack application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir hw.domainname
cd hw.domainname
mkdir public
mkdir tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/var/www/hw.domainname/config.ru&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app = proc do |env|
  [200, { &quot;Content-Type&quot; =&amp;gt; &quot;text/html&quot; }, [&quot;hello, world&quot;]]
end
run app
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/hw.domainname&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName hw.domainname
    DocumentRoot /var/www/hw.domainname/public
    &amp;lt;Directory /var/www/hw.domainname/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, and then view it in your browser:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite hw.domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can then be disabled and reenabled if needed for debugging any issues at a later date:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2dissite hw.domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;rails-app&quot;&gt;Rails app&lt;/h3&gt;

&lt;p&gt;You now need to create a virtual host for the rails app so that apache can handle the requests and pass off to passenger.&lt;/p&gt;

&lt;p&gt;Create the necessary directory structure for a rails application (assuming its running as the domainname):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/domainname&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName domainname
    DocumentRoot /var/www/domainname/current/public
    &amp;lt;Directory /var/www/domainname/current/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, although there is nothing there to view until we have deployed it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;capistrano&quot;&gt;Capistrano&lt;/h2&gt;

&lt;p&gt;The following steps should be performed on your client machine to capify an existing rails application and deploy it.&lt;/p&gt;

&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;/h3&gt;

&lt;p&gt;Make sure you have capistrano installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install capistrano
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initialise the rails application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/dev/appname
capify .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will generate some files, along with a sample &lt;code&gt;config/deploy.rb&lt;/code&gt;.  Replace the file contents with the following, using suitable values where applicable.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# RVM bootstrap
$:.unshift(File.expand_path(&#39;./lib&#39;, ENV[&#39;rvm_path&#39;]))
require &#39;rvm/capistrano&#39;
set :rvm_ruby_string, &#39;1.9.2-p290&#39;

# bundler bootstrap
require &#39;bundler/capistrano&#39;

# main details
set :application, &quot;domainname&quot;
role :web, &quot;domainname&quot;
role :app, &quot;domainname&quot;
role :db,  &quot;domainname&quot;, :primary =&amp;gt; true

# server details
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
set :deploy_to, &quot;/var/www/domainname&quot;
set :deploy_via, :remote_cache
set :user, &quot;passenger&quot;
set :use_sudo, false

# repo details
set :scm, :git
set :scm_username, &quot;passenger&quot;
set :repository, &quot;git@gitserver:domainname.git&quot;
set :branch, &quot;master&quot;
set :git_enable_submodules, 1

# tasks
namespace :deploy do
  task :start, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  task :stop, :roles =&amp;gt; :app do
    # Do nothing.
  end

  desc &quot;Restart Application&quot;
  task :restart, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: the above file supplies the rvm ruby version as &lt;code&gt;1.9.2-p290&lt;/code&gt;.  It is advisable to be specific about the version here as if this were &lt;code&gt;1.9.2&lt;/code&gt; and a newer ruby version is available you may start to receive errors in the capistrano deployment.&lt;/p&gt;

&lt;h3 id=&quot;deployment&quot;&gt;Deployment&lt;/h3&gt;

&lt;p&gt;The first time you deploy to the server you should run the deployment setup task:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thereafter you can deploy using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you have database migrations to run then use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:migrations
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may get some strange errors or failures when deploying.  If you have followed the steps I have mentioned in this guide then hopefully you shouldn’t have many problems.  Common problems are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;wrong permissions of &lt;code&gt;/var/www&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;wrong permissions of passenger user&lt;/li&gt;
  &lt;li&gt;not having rvm installed for passenger user&lt;/li&gt;
  &lt;li&gt;not having the basic gems required to use capistrano on the server, simply install them as the passenger user&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;View your website in your browser and ensure it is loading.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Subversion Autoprops</title>
   <link href="http://kris.me.uk/2010/11/17/subversion-autoprops.html"/>
   <updated>2010-11-17T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/11/17/subversion-autoprops</id>
   <content type="html">&lt;p&gt;I have noticed in particular with Subversion that in an environment with different operating systems, you often end up with mixed line endings in files unless some measures are taken to combat this.  This is a particular issue with using an &lt;a href=&quot;/2010/10/01/svn-master-with-git-mirrors.html&quot;&gt;svn master with git mirrors&lt;/a&gt; as you may see problems with &lt;code&gt;git-svn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Subversion allows metadata to be stored and versioned against any file or directory in the repository using &lt;a href=&quot;http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.advanced.props&quot;&gt;properties&lt;/a&gt;.  Subversion has its own namespace for properties that extend its capabilities to manage the items under source control.  Some of the key properties are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;svn:mime-type&lt;/code&gt; - value is returned as the Content-type HTTP header on GET requests (useful when browsing the repository)&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;svn:keywords&lt;/code&gt; - provides keyword expansion such as Author, Date, Id and Revision, and ensuring that changes to these values do not cause differences&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;svn:eol-style&lt;/code&gt; - handles CR+LF issues in heterogeneous operating system environments&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;svn:executable&lt;/code&gt; - will set execution mask correctly on operating systems that support it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A key part of this is ensuring that properties are set effectively.  Subversion provides a mechanism called &lt;a href=&quot;http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.advanced.props.auto&quot;&gt;autoprops&lt;/a&gt; to set default properties on files and directory based on pattern matching the filename.  Autoprops does not modify existing files as you may need to deviate from the defaults in rare cases, so addition is chosen as a suitable point to consider what these values should be.&lt;/p&gt;

&lt;h2 id=&quot;configuring-autoprops&quot;&gt;Configuring autoprops&lt;/h2&gt;

&lt;p&gt;All subversion clients support autoprops and this is usually configured in the &lt;a href=&quot;http://svnbook.red-bean.com/en/1.5/svn-book.html#svn.advanced.confarea&quot;&gt;runtime configuration area&lt;/a&gt;.  This file is usually located at &lt;code&gt;~/.subversion/config&lt;/code&gt; although this may vary depending on the subversion client and the operating system.&lt;/p&gt;

&lt;p&gt;Modify the subversion configuration file (&lt;code&gt;config&lt;/code&gt;), making the following changes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Ensure &lt;code&gt;enable-auto-props = yes&lt;/code&gt; is present and not commented out&lt;/li&gt;
  &lt;li&gt;Ensure the &lt;code&gt;[auto-props]&lt;/code&gt; section at the end of the file contains at least the following entries:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;text&quot;&gt;*.bat = svn:mime-type=text/plain;svn:eol-style=native;svn:executable=on
*.c = svn:mime-type=text/plain;svn:eol-style=native
*.cmd = svn:mime-type=text/plain;svn:eol-style=native;svn:executable=on
*.cpp = svn:mime-type=text/plain;svn:eol-style=native
*.css = svn:mime-type=text/css;svn:eol-style=native
*.doc = svn:mime-type=application/msword
*.dtd = svn:mime-type=text/plain;svn:eol-style=native
*.erb = svn:mime-type=text/plain;svn:eol-style=native
*.gif = svn:mime-type=image/gif
*.h = svn:mime-type=text/plain;svn:keywords=Author Date Id Revision;svn:eol-style=native
*.html = svn:mime-type=text/html;svn:eol-style=native
*.java = svn:mime-type=text/plain;svn:eol-style=native;svn:keywords=Author Date Id Revision
*.jpg = svn:mime-type=image/jpeg
*.js = svn:mime-type=text/plain;svn:eol-style=native
*.jsp = svn:mime-type=text/plain;svn:eol-style=native
*.png = svn:mime-type=image/png
*.properties = svn:mime-type=text/plain;svn:eol-style=native
*.rb = svn:mime-type=text/plain;svn:eol-style=native;svn:executable=on
*.sh = svn:mime-type=text/plain;svn:eol-style=native;svn:executable=on
*.sql = svn:mime-type=text/plain;svn:eol-style=native
*.tld = svn:mime-type=text/xml;svn:eol-style=native
*.txt = svn:mime-type=text/plain;svn:eol-style=native
*.xls = svn:mime-type=application/msexcel
*.xml = svn:mime-type=text/xml;svn:eol-style=native
*.xsd = svn:mime-type=text/xml;svn:eol-style=native
*.xsl = svn:mime-type=text/xml;svn:eol-style=native
*.yml = svn:mime-type=text/plain;svn:eol-style=native
.checkstyle = svn:mime-type=text/plain;svn:eol-style=native
.classpath = svn:mime-type=text/plain;svn:eol-style=native
.project = svn:mime-type=text/plain;svn:eol-style=native
Makefile = svn:eol-style=native
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The above list is not definitive, so add any file types common to your development process.&lt;/p&gt;

&lt;h2 id=&quot;fixing-existing-autoprops&quot;&gt;Fixing existing autoprops&lt;/h2&gt;

&lt;p&gt;The following script is designed to run in a bash shell and requires ruby.  It reads the subversion config file from &lt;code&gt;~/.subversion/config&lt;/code&gt; and applies the rules to files already added to subversion in the current directory and its children - effectively applying autoprops to the file as if it were a new addition.&lt;/p&gt;

&lt;p&gt;In particular, note that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;the modification will be to the working copy and will therefore need to be committed as required&lt;/li&gt;
  &lt;li&gt;the use of dos2unix and unix2dos gives EOL consistency.  Subversion may complain if you try to change the eol-style on a file with inconsistent line endings.&lt;/li&gt;
  &lt;li&gt;this can generate a lot of changes and cause some major conflicts if people have uncommitted local modifications.  It is advised to do this during a quiet period.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;c1&quot;&gt;#!/usr/bin/env ruby&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;optparse&amp;#39;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;fileutils&amp;#39;&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:dryrun&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;OptionParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;banner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;fix_svn_autoprops&amp;quot;&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-n&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--dry-run&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Show what would happen but don&amp;#39;t actually do anything&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dryrun&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;--fix-eols-windows&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fix eol for windows if eol-style property is set&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:fixeols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:windows&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;--fix-eols-linux&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fix eol for linux (and mac) if eol-style property is set&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:fixeols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:linux&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;on_tail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;-h&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;--help&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Show this message&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;opts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse!&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;autoprops&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;k&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}}&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expand_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;~/.subversion/config&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;r&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gets&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chomp!&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;strip!&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^$/&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^#.*$/&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=~&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/^\[[\w-]*\]$/&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;section&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;[auto-props]&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# parse auto props line&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename_pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;props&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/([^\s=]+)\s*=\s*(.+)$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;;&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;propname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&amp;#39;=&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;autoprops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename_pattern&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;autoprops&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename_pattern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Fixing &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename_pattern&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; with &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{find . -name .svn -prune -o -name target -prune -o -name test-output -prune -o -name &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename_pattern&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&amp;quot; -print0}&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;svn:eol-style&amp;#39;&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:fixeols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:windows&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{ -exec dos2unix &amp;#39;{}&amp;#39; \\;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{ -exec unix2dos &amp;#39;{}&amp;#39; \\;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:linux&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{ -exec unix2dos &amp;#39;{}&amp;#39; \\;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{ -exec dos2unix &amp;#39;{}&amp;#39; \\;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%Q{ -exec svn ps &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propname&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;&amp;quot; &amp;#39;{}&amp;#39; \\;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;puts&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;command&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dryrun&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Ruby Rack App Hosting with RVM, Passenger 3, Capistrano, Git and Apache</title>
   <link href="http://kris.me.uk/2010/11/15/rails3-rvm-passenger3-apache.html"/>
   <updated>2010-11-15T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/11/15/rails3-rvm-passenger3-apache</id>
   <content type="html">&lt;p&gt;This guide supersedes a number of &lt;a href=&quot;/2010/08/30/rails3-hosting-all-in-one.html&quot;&gt;earlier guides&lt;/a&gt;, providing the details to get up and running with a rack based application from a basic ubuntu server VPS.  The notable differences are using passenger 3 and system wide rvm.&lt;/p&gt;

&lt;p&gt;At the time of writing, the latest versions of the software in use are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;RVM: 1.0.21, system wide&lt;/li&gt;
  &lt;li&gt;Ruby: 1.9.2-p0&lt;/li&gt;
  &lt;li&gt;Passenger: 3.0.0&lt;/li&gt;
  &lt;li&gt;Rails: 3.0.2&lt;/li&gt;
  &lt;li&gt;Capistrano: 2.5.19&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may need to alter the versions in the steps below as some commands and paths contain explicit versions.  The server used for hosting in the guide is an &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS&lt;/a&gt;, so tailor the steps to your platform accordingly.  Also, substitute &lt;em&gt;domainname&lt;/em&gt;, &lt;em&gt;hostname&lt;/em&gt; and &lt;em&gt;appname&lt;/em&gt; as appropriate for your environment.&lt;/p&gt;

&lt;h2 id=&quot;rvm-system-wide-install&quot;&gt;RVM System Wide Install&lt;/h2&gt;

&lt;p&gt;rvm is installed system wide as this is now the best practice for deployments.  This allows installations to be shared across different users, although different users can use which ever version they wish.&lt;/p&gt;

&lt;p&gt;Log in as root and install using the preferred script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bash &amp;lt; &amp;lt;( curl -L http://bit.ly/rvm-install-system-wide )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In order for a user to use the system wide rvm installation the following must be setup:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;User must belong to the rvm group - system wide installation requires the correct permissions&lt;/li&gt;
  &lt;li&gt;User must use the rvm load script in profile files - the location of the load script is different to user specific installs&lt;/li&gt;
  &lt;li&gt;User must not have &lt;code&gt;~/.rvm&lt;/code&gt; - a user specific install overrides a system wide one&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;create-passenger-user&quot;&gt;Create Passenger User&lt;/h2&gt;

&lt;p&gt;It is a good idea to create a passenger user on the server to install services as so that it is isolated from other users.  You can also deploy your applications using this user.  The passenger user needs sudo rights for installing packages using apt-get and running the passenger install script, and needs to be a member of the rvm group to use the system wide install.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser passenger
sudo usermod -G passenger,www-data,sudo,rvm passenger
su - passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can remove the sudo right after completing the installation using the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo usermod -G passenger,www-data,rvm passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Generate a key pair for ssh too.  On your client machine, create a key and use a string pass phrase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -v -t rsa -f passenger@domainname -C passenger@domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a private key called &lt;code&gt;passenger@domainname&lt;/code&gt; and a public key called &lt;code&gt;passenger@domainname.pub&lt;/code&gt;.  Keep these somewhere safe.&lt;/p&gt;

&lt;p&gt;You can register the public key into authorized_keys to allow key based ssh authentication.  Run the following on your client machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp passenger@domainname.pub passenger@hostname:~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depending on the client and your preference, you can either enter the passphrase for you private key each time you connect, or run &lt;code&gt;ssh-agent&lt;/code&gt; and register the key using &lt;code&gt;ssh-add&lt;/code&gt;.  To register the private key into your ssh agent on your client machine run the following and enter the passphrase when prompted:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-add passenger@domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to ssh to the server without being challenged for the password, e.g:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh passenger@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;passenger-rvm-configuration&quot;&gt;Passenger RVM Configuration&lt;/h2&gt;

&lt;p&gt;Simply edit &lt;code&gt;.bashrc&lt;/code&gt; and add the following line at the bottom:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[[ -s /usr/local/lib/rvm ]] &amp;amp;&amp;amp; source /usr/local/lib/rvm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: if you previously had rvm installed as a single user you need to remove the old source line for &lt;code&gt;$HOME/.rvm/scripts/rvm&lt;/code&gt; and move (or delete) the .rvm directory so that the system wide installation is picked up instead.&lt;/p&gt;

&lt;p&gt;Log out and log in again as passenger to ensure the scripts work as expected.  You can test rvm is available correctly by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;type rvm | head -n1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should then see the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm is a function
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can view the notes about requirements for installing the different rubies by running &lt;code&gt;rvm notes&lt;/code&gt;.  The list of packages at the time of writing had dependency conflicts which can be circumvented by removing &lt;code&gt;libreadline5-dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To install the packages (requires sudo):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install openssl curl git-core subversion autoconf \
                     build-essential bison zlib1g zlib1g-dev \
                     libssl-dev libxml2-dev libreadline5 libreadline-dev \
                     libreadline6-dev libsqlite3-0 libsqlite3-dev sqlite3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To install ruby 1.9.2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm install 1.9.2
rvm use --default 1.9.2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can can now verify the ruby version and install some gems, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby -v
gem install bundler rails
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;passenger&quot;&gt;Passenger&lt;/h2&gt;

&lt;p&gt;Passenger is very easy to install.  rvm provides some &lt;a href=&quot;http://rvm.beginrescueend.com/integration/passenger/&quot;&gt;instructions&lt;/a&gt; specifically for passenger.&lt;/p&gt;

&lt;p&gt;Install the gem and run the installation script.  It will tell you what dependencies you are missing and how to install them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install passenger
passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Passenger provides some instructions on how to configure apache.  I like to treat passenger as a mod for apache, allowing it to be enabled and disabled as required through the &lt;code&gt;a2enmod&lt;/code&gt; and &lt;code&gt;a2dismod&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;To enable passenger, create &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p0/gems/passenger-3.0.0/ext/apache2/mod_passenger.so
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and &lt;code&gt;/etc/apache2/mods-available/passenger.conf&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p0/gems/passenger-3.0.0
PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p0/ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then enable the module and restart apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod passenger
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;apache&quot;&gt;Apache&lt;/h2&gt;

&lt;p&gt;Each rack/rails application is made available through a virtual host directive in the apache configuration.  The recommended way to do this is to create a file named after the site, e.g. &lt;code&gt;domainname&lt;/code&gt; in &lt;code&gt;/etc/apache2/sites-available&lt;/code&gt; and then enable and disable the site as required using the &lt;code&gt;a2ensite&lt;/code&gt; and &lt;code&gt;a2dissite&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;I prefer to put all web applications in &lt;code&gt;/var/www&lt;/code&gt; and have users be able to create applications if they are a member of &lt;code&gt;www-data&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo chmod g+w /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;hello-world-rack-app&quot;&gt;Hello World rack app&lt;/h3&gt;

&lt;p&gt;I find it useful to have a simple Hello World rack application to verify the rvm and passenger installation.  The application can be run as a subdomain to allow testing and can be enabled and disabled as desired.&lt;/p&gt;

&lt;p&gt;Create the necessary directory structure for a rack application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir hw.domainname
cd hw.domainname
mkdir public
mkdir tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/var/www/hw.domainname/config.ru&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app = proc do |env|
  [200, { &quot;Content-Type&quot; =&amp;gt; &quot;text/html&quot; }, [&quot;hello, world&quot;]]
end
run app
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/hw.domainname&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName hw.domainname
    DocumentRoot /var/www/hw.domainname/public
    &amp;lt;Directory /var/www/hw.domainname/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, and then view it in your browser:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite hw.domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can then be disabled and reenabled if needed for debugging any issues at a later date:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2dissite hw.domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;rails-app&quot;&gt;Rails app&lt;/h3&gt;

&lt;p&gt;You now need to create a virtual host for the rails app so that apache can handle the requests and pass off to passenger.&lt;/p&gt;

&lt;p&gt;Create the necessary directory structure for a rails application (assuming its running as the domainname):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/domainname&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName domainname
    DocumentRoot /var/www/domainname/current/public
    &amp;lt;Directory /var/www/domainname/current/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, although there is nothing there to view until we have deployed it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;capistrano&quot;&gt;Capistrano&lt;/h2&gt;

&lt;p&gt;The following steps should be performed on your client machine to capify an existing rails application and deploy it.&lt;/p&gt;

&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;/h3&gt;

&lt;p&gt;Make sure you have capistrano installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install capistrano
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initialise the rails application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/dev/appname
capify .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will generate some files, along with a sample &lt;code&gt;config/deploy.rb&lt;/code&gt;.  Replace the file contents with the following, using suitable values where applicable.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# RVM bootstrap
$:.unshift(File.expand_path(&quot;~/.rvm/lib&quot;))
require &#39;rvm/capistrano&#39;
set :rvm_ruby_string, &#39;1.9.2-p0&#39;
set :rvm_type, :system

# bundler bootstrap
require &#39;bundler/capistrano&#39;

# main details
set :application, &quot;domainname&quot;
role :web, &quot;domainname&quot;
role :app, &quot;domainname&quot;
role :db,  &quot;domainname&quot;, :primary =&amp;gt; true

# server details
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
set :deploy_to, &quot;/var/www/domainname&quot;
set :deploy_via, :remote_cache
set :user, &quot;passenger&quot;
set :use_sudo, false

# repo details
set :scm, :git
set :scm_username, &quot;passenger&quot;
set :repository, &quot;git@gitserver:domainname.git&quot;
set :branch, &quot;master&quot;
set :git_enable_submodules, 1

# tasks
namespace :deploy do
  task :start, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  task :stop, :roles =&amp;gt; :app do
    # Do nothing.
  end

  desc &quot;Restart Application&quot;
  task :restart, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  desc &quot;Symlink shared resources on each release - not used&quot;
  task :symlink_shared, :roles =&amp;gt; :app do
    #run &quot;ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml&quot;
  end
end

after &#39;deploy:update_code&#39;, &#39;deploy:symlink_shared&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: the above file supplies the rvm ruby version as &lt;code&gt;1.9.2-p0&lt;/code&gt;.  It is advisable to be specific about the version here as if this were &lt;code&gt;1.9.2&lt;/code&gt; and a newer ruby version is available you may start to receive errors in the capistrano deployment.&lt;/p&gt;

&lt;h3 id=&quot;deployment&quot;&gt;Deployment&lt;/h3&gt;

&lt;p&gt;The first time you deploy to the server you should run the deployment setup task:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thereafter you can deploy using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you have database migrations to run then use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:migrations
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may get some strange errors or failures when deploying.  If you have followed the steps I have mentioned in this and previous articles then you shouldn’t have many problems.  Common problems are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;wrong permissions of &lt;code&gt;/var/www&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;wrong permissions of passenger user&lt;/li&gt;
  &lt;li&gt;not having rvm installed for passenger user&lt;/li&gt;
  &lt;li&gt;not having the basic gems required to use capistrano on the server, simply install them as the passenger user&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;View your website in your browser and ensure it is loading.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Subversion Master With Git Mirrors</title>
   <link href="http://kris.me.uk/2010/10/01/svn-master-with-git-mirrors.html"/>
   <updated>2010-10-01T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/10/01/svn-master-with-git-mirrors</id>
   <content type="html">&lt;p&gt;Subversion has proved itself to be a strong centralised version control system, establishing itself as the major corporate version control system.  But the times are changing, people are collaborating with others around the world, often working offline while travelling, wanting something with a little more features locally or just something more performant.  Distributed version control systems (DVCS) address all of these issues and have been proven by the vast numbers of open source developers using them to develop critical software.  Dropping subversion and adopting a DVCS such as git is not an easy step for most corporate organisations, the tool chain is slightly different and there needs to be a change in approach to attain the increase in productivity that can be achieved.&lt;/p&gt;

&lt;p&gt;This article looks at not replacing subversion but continuing to use it as the master source repository and use one or more git mirrors to provide git for those that are familiar or wish to try it.  Having subversion as the master repository can also alleviate management worries around authoritative sources, learning curves and any lost productive during upskilling, and other barriers to change.  Those users using git can interact with both the subversion master and git mirrors, committing any work to be shared with all users back to subversion as and when appropriate.  To reduce any issues, commits should always be pushed back to the subversion repository, creating a circular flow of changes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/svn-git-mirrors.png&quot; alt=&quot;Repositories involved including traffic flow&quot; title=&quot;repositories involved including traffic flow&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Note the use of the fetch repository.  This is the recommended approach to creating a mirror as &lt;code&gt;git svn clone&lt;/code&gt; will create a local working area which we do not want if hosting as a mirror.  Therefore we have to use two repositories, a standard git bare repository for the mirror and a git svn “fetch” repository for updating the mirror.&lt;/p&gt;

&lt;p&gt;This guide makes the following assumptions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;master subversion repository is available at &lt;code&gt;http://servername/svn/reponame/&lt;/code&gt; with standard conventions for trunk, tags and branches&lt;/li&gt;
  &lt;li&gt;you are able to set up access to a remote git repository, ideally using something like &lt;a href=&quot;/2009/12/31/git-repository-server.html&quot;&gt;gitosis&lt;/a&gt; or &lt;a href=&quot;/2010/09/30/git-repository-server-gitolite.html&quot;&gt;gitolite&lt;/a&gt; or even &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;you are able to create cron jobs on the server hosting the fetch repository&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;svn&lt;/code&gt;, &lt;code&gt;git&lt;/code&gt; and &lt;code&gt;git-svn&lt;/code&gt; are installed and available on the command line&lt;/li&gt;
  &lt;li&gt;optional: &lt;code&gt;gitk&lt;/code&gt; is installed and available on the command line&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Updates 2010-10-06:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Fixed a number of mirror issues with the approach using master.  Now uses trunk and HEAD is set to refs/heads/trunk using symbolic ref.&lt;/li&gt;
  &lt;li&gt;sync script is now a standalone script allowing manual and automated (via cron) updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;creating-a-git-mirror&quot;&gt;Creating a git mirror&lt;/h2&gt;

&lt;p&gt;A git mirror can be created on the git repository server of your choice.&lt;/p&gt;

&lt;p&gt;Note: It is important to set &lt;code&gt;HEAD&lt;/code&gt; to &lt;code&gt;refs/heads/trunk&lt;/code&gt;.  &lt;a href=&quot;http://github.com&quot;&gt;github&lt;/a&gt; allows this through the repository admin, and you can do this manually with gitosis or gitolite by running the following command on a bare repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GIT_DIR=/path/to/reponame.git git symbolic-ref HEAD refs/heads/trunk
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For example, using gitolite, clone the admin repo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git@hostname:gitolite-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Modify the &lt;code&gt;conf/gitolite.conf&lt;/code&gt; file to also contain:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@mirrors    = reponame

repo        @mirrors
            R       =   @all
            RW+     =   @admins
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add and commit the changes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add -A
git ci -m &quot;added reponame mirror&quot;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now ssh to the server and run the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GIT_DIR=/home/git/repositories/reponame.git git symbolic-ref HEAD refs/heads/trunk
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The rest of the article assumes that the git mirror is available at &lt;code&gt;git@hostname:reponame.git&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;setting-up-a-fetch-repo-for-the-mirror&quot;&gt;Setting up a fetch repo for the mirror&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;git svn clone&lt;/code&gt; will create a clone of a subversion repository including the entire history.  Unfortunately, for repositories with a lot of history, this can take a long time to run as &lt;code&gt;git-svn&lt;/code&gt; has to replay each revision during the clone.&lt;/p&gt;

&lt;p&gt;Ideally, the fetch repo will be setup on a server so that it cron can be used to provide regular updates.  If you are hosting your own mirror then it is a good idea to also put the fetch repository on the same server.&lt;/p&gt;

&lt;p&gt;To create the fetch repo on the server as the git user from a particular revision (e.g. 12345), run the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh username@hostname
su - git
mkdir -p ~/fetchers
cd ~/fetchers
git svn clone -s --no-minimize-url -r12345:HEAD http://servername/svn/reponame/ reponame-fetch
cd reponame-fetch
git branch -m master trunk
git remote add mirror git@hostname:reponame.git
git config --unset remote.mirror.fetch
git config remote.mirror.push &#39;refs/remotes/*:refs/heads/*&#39;
git push mirror
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a script to sync the repository.  Edit &lt;code&gt;~/bin/sync-reponame&lt;/code&gt; and add the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/fetchers/reponame-fetch
echo Syncing at `date`
git svn rebase
git push mirror
echo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ensure the script can be run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chmod +x ~/bin/sync-reponame
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a suitable crontab by running &lt;code&gt;crontab -e&lt;/code&gt; and entering the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;*/5 * * * * ~/bin/sync-reponame &amp;gt;&amp;gt; ~/sync-reponame.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will run a sync script every 5 minutes as the git user, appending the output to a log file.  Change the timings as appropriate for your setup.&lt;/p&gt;

&lt;h2 id=&quot;git-clone&quot;&gt;Git clone&lt;/h2&gt;

&lt;p&gt;Each user can create a clone using the git mirror and create the necessary svn references:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone -o mirror git@hostname:reponame.git
cd reponame
git svn init --prefix=mirror/ -s http://servername/svn/reponame/
git svn rebase
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A user can keep up to date by pulling from the git mirror:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git pull --rebase
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or they can update directly from subversion:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git svn rebase
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The git mirror may lag behind subversion depending on the timings of any cron jobs to sync repos, although this is not an issue usually.  A user may wish to update from svn if they are waiting on a change that they need quickly for example.  Also, in order to commit to subversion, a user should have the latest version so it is usual to update from subversion just prior to the subversion commit.&lt;/p&gt;

&lt;p&gt;A user can now perform the usual workflows with git, committing any changes and when happy using &lt;code&gt;git svn dcommit&lt;/code&gt; to commit the changes to the subversion master.  For example [comments in square brackets]:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git pull --rebase               [ensure up to date with mirror]
....                            [modify a file]
git add -A                      [add any changes in files to the index]
git ci -m &quot;updated a file&quot;      [commit the changes in the index]
git svn rebase                  [ensure up to date with svn]
git svn dcommit                 [push changes back to subversion]
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;working-with-branches&quot;&gt;Working with branches&lt;/h2&gt;

&lt;p&gt;When adding features it is good practice to use a feature branch.  The master branch can be kept up to date with subversion using &lt;code&gt;git svn rebase&lt;/code&gt; and then the feature branch can be rebased onto master as and when you want to align with the current stream of development.  When you are ready to push back to the subversion master repository, rebase the feature branch from the master branch and merge the branch using a fast forward merge onto the master branch.  You can then dcommit the changes as normal.  A sample workflow would be:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout -b feature         [create a feature branch and checkout]
....                            [modify a file]
git add -A                      [add any changes in files to the index]
git ci -m &quot;updated a file&quot;      [commit the changes in the index]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;occasionally rebase from mirror and rebase branch from master:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout master             [switch back to the master branch]
git pull --rebase               [ensure up to date with mirror]
git checkout feature            [switch back to the feature branch]
git rebase master               [replay branch changes on top of master and fix any problems]
....                            [do some work, until you are ready to commit back to svn]
git checkout master             [switch back to the master branch]
git svn rebase                  [ensure up to date with svn]
git checkout feature            [switch back to the master branch]
git rebase master               [replay branch changes on top of master and fix any problems]
git checkout master             [switch back to the master branch]
git merge feature --ff-only     [merge feature branch ensuring fast forward merge]
git svn dcommit                 [push changes back to subversion]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is important to be careful with merges due to the way &lt;code&gt;git svn&lt;/code&gt; works, see CAVEATS from &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-svn.html&quot;&gt;git svn man page&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;useful-aliases&quot;&gt;Useful aliases&lt;/h2&gt;

&lt;p&gt;Git allows aliases to be created to reduce the amount you have to type for common commands and their options.  Run the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global alias.svnsync &quot;pull --rebase&quot;
git config --global alias.svnup &quot;svn rebase&quot;
git config --global alias.svnci &quot;svn dcommit --rmdir&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can then run the following commands, with an explanation of what they do:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;git svnsync&lt;/code&gt; will do the equivalent of &lt;code&gt;svn up&lt;/code&gt; using the git mirror&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;git svnup&lt;/code&gt; will do the equivalent of &lt;code&gt;svn up&lt;/code&gt; using the svn server&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;git svnci&lt;/code&gt; will do the equivalent of &lt;code&gt;svn ci&lt;/code&gt; using the svn server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;other-tools&quot;&gt;Other tools&lt;/h2&gt;

&lt;p&gt;gitk (and &lt;a href=&quot;http://github.com/brotherbard/gitx&quot;&gt;gitx&lt;/a&gt;, its more beautiful counterpart for OS X) can be used to view the git repository.  Its is a useful gui tool for reviewing commits.  Alternatively, &lt;code&gt;git log&lt;/code&gt; and friends will give you details on the command line.&lt;/p&gt;

&lt;h2 id=&quot;related-reading&quot;&gt;Related reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Apache follows a similar &lt;a href=&quot;http://wiki.apache.org/general/GitAtApache&quot;&gt;git svn workflow&lt;/a&gt;.&lt;/li&gt;
  &lt;li&gt;Why you should use &lt;a href=&quot;http://gitready.com/advanced/2009/02/11/pull-with-rebase.html&quot;&gt;git pull –rebase&lt;/a&gt; as opposed to the default of merge.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/1692935/read-only-git-mirror-of-an-svn-repository&quot;&gt;Other&lt;/a&gt; &lt;a href=&quot;https://git.wiki.kernel.org/index.php/GitFaq#How_do_I_mirror_a_SVN_repository_to_git.3F&quot;&gt;articles&lt;/a&gt; &lt;a href=&quot;http://www.fnokd.com/2008/08/20/mirroring-svn-repository-to-github/&quot;&gt;about&lt;/a&gt; setting up git mirrors of svn repositories.&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Git Repository Server using Gitolite</title>
   <link href="http://kris.me.uk/2010/09/30/git-repository-server-gitolite.html"/>
   <updated>2010-09-30T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/09/30/git-repository-server-gitolite</id>
   <content type="html">&lt;p&gt;Some time ago, I covered setting up a &lt;a href=&quot;/2009/12/31/git-repository-server.html&quot;&gt;git repository server using gitosis&lt;/a&gt;.  Since then, &lt;a href=&quot;http://github.com/sitaramc/gitolite&quot;&gt;gitolite&lt;/a&gt; has entered the arena and has built on gitosis adding features such as branch level access control, gitweb control and improved configuration.  This guide covers installing &lt;a href=&quot;http://github.com/sitaramc/gitolite&quot;&gt;gitolite&lt;/a&gt; using the non-root method and simple administration.&lt;/p&gt;

&lt;p&gt;The documentation for gitolite is pretty comprehensive and I encourage you to read the official &lt;a href=&quot;http://github.com/sitaramc/gitolite/blob/pu/doc/1-INSTALL.mkd&quot;&gt;install&lt;/a&gt; and &lt;a href=&quot;http://github.com/sitaramc/gitolite/blob/pu/doc/2-admin.mkd&quot;&gt;admin&lt;/a&gt; instructions.  In addition to the official instructions, I also setup and authorise the git user as this allows any server sync repositories to use the git user as a system account and be able to interact with git repositories hosted in gitolite.  This is useful for fetch repositories for svn mirrors for example (the topic of a future post).&lt;/p&gt;

&lt;p&gt;The following conventions are used and should be substituted with appropriate values for your environment:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;username&lt;/code&gt; is the username of the person installing gitolite (i.e. you) and is assumed to have an account on the server&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;hostname&lt;/code&gt; is the hostname of the git server - add host entries as appropriate (e.g. &lt;code&gt;172.18.25.102 hostname&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;git&lt;/code&gt; is the username of the user on the git server that will run gitolite and will be created&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;reponame&lt;/code&gt; is the name of a repository you want to host&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post assumes that you have a server following the &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS Base Build&lt;/a&gt; post.&lt;/p&gt;

&lt;h2 id=&quot;git-packages&quot;&gt;Git Packages&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;git-core&lt;/code&gt; package contains all the basic command line for git.  As the server is running headless, there is no point in installing packages such as &lt;code&gt;gitk&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install git-core
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;ssh-keys&quot;&gt;ssh keys&lt;/h2&gt;

&lt;p&gt;If you already have ssh keys then use those, otherwise create some, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~
ssh-keygen -v -t rsa -C username@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;gitolite&quot;&gt;Gitolite&lt;/h2&gt;

&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;/h3&gt;

&lt;p&gt;Copy your public key to the server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp ~/.ssh/id_rsa.pub username@hostname:username.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;SSH to the server:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh username@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the git user that gitolite will run as (i.e. &lt;code&gt;git&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Copy the public key over to the git user:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo chown git:git username.pub
sudo mv username.pub ~git/username.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Log in as the git user:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;su - git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Generate ssh keys for git user with no password and copy the public key to your clipboard for later:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -v -t rsa
cat ~/.ssh/id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install gitolite:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~
git clone git://github.com/sitaramc/gitolite gitolite-source
cd gitolite-source
mkdir -p ~/bin ~/share/gitolite/conf ~/share/gitolite/hooks
src/gl-system-install ~/bin ~/share/gitolite/conf ~/share/gitolite/hooks
cd ..
gl-setup username.pub
rm -f username.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;administration&quot;&gt;Administration&lt;/h3&gt;

&lt;p&gt;You can administer the configuration through git itself on the &lt;code&gt;gitolite-admin&lt;/code&gt; repository by cloning, modifying and push changes back to the server.&lt;/p&gt;

&lt;p&gt;On your client machine, clone the admin repo:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git@hostname:gitolite-admin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Modify the &lt;code&gt;conf/gitolite.conf&lt;/code&gt; file to contain:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@admins     = username git

repo        gitolite-admin
            RW+     =   @admins

repo        testing
            RW+     =   @all
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And ensure that the &lt;code&gt;keydir&lt;/code&gt; directory contains the following files:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git.pub
username.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add and commit the changes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add -A
git ci -m &quot;updated configuration&quot;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;adding-repositories&quot;&gt;Adding repositories&lt;/h3&gt;

&lt;p&gt;As above, clone the admin repo and append the following to &lt;code&gt;conf/gitolite.conf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;repo        reponame
            RW+     =   username
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add and commit the changes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add -A
git ci -m &quot;updated configuration&quot;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can now add create the project (or skip this for an existing project):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir myproject
cd mypyroject
git init
# do some work, git add and commit files
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then add your server as a remote and push:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote add hostname git@hostname:reponame.git
git push hostname master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can track the remote by adding suitable config:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config branch.master.remote hostname
git config branch.master.merge refs/heads/master
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Rails 3 Hosting with RVM, Passenger, Capistrano, Git and Apache</title>
   <link href="http://kris.me.uk/2010/08/30/rails3-hosting-all-in-one.html"/>
   <updated>2010-08-30T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/08/30/rails3-hosting-all-in-one</id>
   <content type="html">&lt;p&gt;Now that Rails 3 and Ruby 1.9.2 are released, I have compiled some of my &lt;a href=&quot;/2010/07/11/rack-app-hosting-with-rvm-and-passenger.html&quot;&gt;earlier&lt;/a&gt; &lt;a href=&quot;/2010/08/05/rails3-rvm-passenger-capistrano.html&quot;&gt;posts&lt;/a&gt; to create this all in one guide to installing and running Rails 3, RVM, Ruby 1.9.2, Passenger and Capistrano for hosting your rack/rails applications.  It assumes that you are using apache and git.&lt;/p&gt;

&lt;p&gt;At the time of writing, the latest versions of the software in use are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;RVM: 1.0.1&lt;/li&gt;
  &lt;li&gt;Ruby: 1.9.2-p0&lt;/li&gt;
  &lt;li&gt;Passenger: 2.2.15&lt;/li&gt;
  &lt;li&gt;Rails: 3.0.0&lt;/li&gt;
  &lt;li&gt;Capistrano: 2.5.19&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You may need to alter the versions in the steps below as some commands and paths contain explicit versions.  The server used for hosting in the guide is an &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS&lt;/a&gt;, so tailor the steps to your platform accordingly.  Also, substitute &lt;em&gt;domainname&lt;/em&gt;, &lt;em&gt;hostname&lt;/em&gt; and &lt;em&gt;appname&lt;/em&gt; as appropriate for your environment.&lt;/p&gt;

&lt;p&gt;Updates:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;2010-09-11: Fixed path to public folder in apache virtual host to include &lt;code&gt;current&lt;/code&gt; if deployed using capistrano&lt;/li&gt;
  &lt;li&gt;2010-09-11: Added note about using &lt;code&gt;cap deploy:migrations&lt;/code&gt; if you have db migrations to run&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;passenger-user&quot;&gt;Passenger User&lt;/h2&gt;

&lt;p&gt;It is a good idea to create a passenger user on the server to install rvm for so that other users do not modify it by accident.  You can also deploy your applications using this user.  The passenger user needs sudo rights for installing packages using apt-get and running the passenger install script.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser passenger
sudo usermod -G passenger,www-data,sudo passenger
su - passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can remove the sudo right after completing the installation using the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo usermod -G passenger,www-data passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Generate a key pair for ssh too.  On your client machine, create a key and use a string pass phrase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -v -t rsa -f passenger@domainname -C passenger@domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a private key called &lt;code&gt;passenger@domainname&lt;/code&gt; and a public key called &lt;code&gt;passenger@domainname.pub&lt;/code&gt;.  Keep these somewhere safe.&lt;/p&gt;

&lt;p&gt;You can register the public key into authorized_keys to allow key based ssh authentication.  Run the following on your client machine:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp passenger@domainname.pub passenger@hostname:~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depending on the client and your preference, you can either enter the passphrase for you private key each time you connect, or run &lt;code&gt;ssh-agent&lt;/code&gt; and register the key using &lt;code&gt;ssh-add&lt;/code&gt;.  To register the private key into your ssh agent on your client machine run the following and enter the passphrase when prompted:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-add passenger@domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to ssh to the server without being challenged for the password, e.g:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh passenger@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;rvm&quot;&gt;RVM&lt;/h2&gt;

&lt;p&gt;rvm is installed locally for each user rather than a single install for the server.  This allows different versions to be used by different users on the server.  Unfortunately, only one ruby version can be used with passenger at the moment due to the way passenger hooks into apache.&lt;/p&gt;

&lt;p&gt;Install using the preferred script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bash &amp;lt; &amp;lt;( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some warnings about issues with &lt;code&gt;return&lt;/code&gt; in &lt;code&gt;.bashrc&lt;/code&gt;.  This appears to be a red herring for Ubuntu as mentioned in this &lt;a href=&quot;http://ubuntuforums.org/showthread.php?t=1392189&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Simply edit &lt;code&gt;.bashrc&lt;/code&gt; and add the following line at the bottom:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[[ -s $HOME/.rvm/scripts/rvm ]] &amp;amp;&amp;amp; source $HOME/.rvm/scripts/rvm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Log out and log in again as passenger to ensure the scripts work as expected.  You can test rvm is available correctly by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;type rvm | head -n1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should then see the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm is a function
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can view the notes about requirements for installing the different rubies by running &lt;code&gt;rvm notes&lt;/code&gt;.  The list of packages at the time of writing had dependency conflicts which can be circumvented by removing &lt;code&gt;libreadline5-dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To install the packages (requires sudo):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install openssl curl git-core subversion autoconf \
                     build-essential bison zlib1g zlib1g-dev \
                     libssl-dev libxml2-dev libreadline5 libreadline-dev \
                     libreadline6-dev libsqlite3-0 libsqlite3-dev sqlite3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To install the rubies, first 1.8.7 as the notes indicate, followed by 1.9.2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm install 1.8.7
rvm use 1.8.7
rvm install 1.9.2
rvm use --default 1.9.2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can can now verify the ruby version and install some gems, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby -v
gem install bundler rails
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;passenger&quot;&gt;Passenger&lt;/h2&gt;

&lt;p&gt;Passenger is very easy to install.  rvm provides some &lt;a href=&quot;http://rvm.beginrescueend.com/integration/passenger/&quot;&gt;instructions&lt;/a&gt; specifically for passenger.&lt;/p&gt;

&lt;p&gt;Tell rvm the desired version of ruby to use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm 1.9.2 --passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install the gem and run the installation script.  It will tell you what dependencies you are missing and how to install them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install passenger
rvmsudo /home/passenger/.rvm/gems/ruby-1.9.2-p0/bin/passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I had to run the following to fix the missing dependencies:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install apache2-prefork-dev libapr1-dev libaprutil1-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Passenger provides some instructions on how to configure apache, although, due to the way rvm works, the value of &lt;code&gt;PassengerRuby&lt;/code&gt; should be different.  I like to treat passenger as a mod for apache, allowing it to be enabled and disabled as required through the &lt;code&gt;a2enmod&lt;/code&gt; and &lt;code&gt;a2dismod&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;To enable passenger, create &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LoadModule passenger_module /home/passenger/.rvm/gems/ruby-1.9.2-p0/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and &lt;code&gt;/etc/apache2/mods-available/passenger.conf&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PassengerRoot /home/passenger/.rvm/gems/ruby-1.9.2-p0/gems/passenger-2.2.15
PassengerRuby /home/passenger/.rvm/bin/passenger_ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then enable the module and restart apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod passenger
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;apache&quot;&gt;Apache&lt;/h2&gt;

&lt;p&gt;Each rack/rails application is made available through a virtual host directive in the apache configuration.  The recommended way to do this is to create a file named after the site, e.g. &lt;code&gt;domainname&lt;/code&gt; in &lt;code&gt;/etc/apache2/sites-available&lt;/code&gt; and then enable and disable the site as required using the &lt;code&gt;a2ensite&lt;/code&gt; and &lt;code&gt;a2dissite&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;I prefer to put all web applications in &lt;code&gt;/var/www&lt;/code&gt; and have users be able to create applications if they are a member of &lt;code&gt;www-data&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mkdir /var/www
sudo chown www-data:www-data /var/www
sudo chmod g+w /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;hello-world-rack-app&quot;&gt;Hello World rack app&lt;/h3&gt;

&lt;p&gt;I find it useful to have a simple Hello World rack application to verify the rvm and passenger installation.  The application can be run as a subdomain to allow testing and can be enabled and disabled as desired.&lt;/p&gt;

&lt;p&gt;Create the necessary directory structure for a rack application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir hw.domainname
cd hw.domainname
mkdir public
mkdir tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/var/www/hw.domainname/config.ru&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app = proc do |env|
  [200, { &quot;Content-Type&quot; =&amp;gt; &quot;text/html&quot; }, [&quot;hello, world&quot;]]
end
run app
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/hw.domainname&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName hw.domainname
    DocumentRoot /var/www/hw.domainname/public
    &amp;lt;Directory /var/www/hw.domainname/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, and then view it in your browser:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite hw.domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can then be disabled and reenabled if needed for debugging any issues at a later date:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2dissite hw.domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;rails-app&quot;&gt;Rails app&lt;/h3&gt;

&lt;p&gt;You now need to create a virtual host for the rails app so that apache can handle the requests and pass off to passenger.&lt;/p&gt;

&lt;p&gt;Create the necessary directory structure for a rails application (assuming its running as the domainname):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/domainname&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName domainname
    DocumentRoot /var/www/domainname/current/public
    &amp;lt;Directory /var/www/domainname/current/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, although there is nothing there to view until we have deployed it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite domainname
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;capistrano&quot;&gt;Capistrano&lt;/h2&gt;

&lt;p&gt;The following steps should be performed on your client machine to capify an existing rails application and deploy it.&lt;/p&gt;

&lt;h3 id=&quot;configuration&quot;&gt;Configuration&lt;/h3&gt;

&lt;p&gt;Make sure you have capistrano installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install capistrano
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initialise the rails application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/dev/appname
capify .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will generate some files, along with a sample &lt;code&gt;config/deploy.rb&lt;/code&gt;.  Replace the file contents with the following, using suitable values where applicable.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# RVM bootstrap
$:.unshift(File.expand_path(&quot;~/.rvm/lib&quot;))
require &#39;rvm/capistrano&#39;
set :rvm_ruby_string, &#39;1.9.2-p0&#39;
set :rvm_type, :user

# bundler bootstrap
require &#39;bundler/capistrano&#39;

# main details
set :application, &quot;domainname&quot;
role :web, &quot;domainname&quot;
role :app, &quot;domainname&quot;
role :db,  &quot;domainname&quot;, :primary =&amp;gt; true

# server details
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
set :deploy_to, &quot;/var/www/domainname&quot;
set :deploy_via, :remote_cache
set :user, &quot;passenger&quot;
set :use_sudo, false

# repo details
set :scm, :git
set :scm_username, &quot;passenger&quot;
set :repository, &quot;git@gitserver:domainname.git&quot;
set :branch, &quot;master&quot;
set :git_enable_submodules, 1

# tasks
namespace :deploy do
  task :start, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  task :stop, :roles =&amp;gt; :app do
    # Do nothing.
  end

  desc &quot;Restart Application&quot;
  task :restart, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  desc &quot;Symlink shared resources on each release - not used&quot;
  task :symlink_shared, :roles =&amp;gt; :app do
    #run &quot;ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml&quot;
  end
end

after &#39;deploy:update_code&#39;, &#39;deploy:symlink_shared&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: the above file supplies the rvm ruby version as &lt;code&gt;1.9.2-p0&lt;/code&gt;.  It is advisable to be specific about the version here as if this were &lt;code&gt;1.9.2&lt;/code&gt; and a newer ruby version is available you may start to receive errors in the capistrano deployment.  Also, capistrano tasks for bundler are now part of bundler so just require them.&lt;/p&gt;

&lt;h3 id=&quot;deployment&quot;&gt;Deployment&lt;/h3&gt;

&lt;p&gt;The first time you deploy to the server you should run the deployment setup task:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thereafter you can deploy using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you have database migrations to run then use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:migrations
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may get some strange errors or failures when deploying.  If you have followed the steps I have mentioned in this and previous articles then you shouldn’t have many problems.  Common problems are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;wrong permissions of &lt;code&gt;/var/www&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;wrong permissions of passenger user&lt;/li&gt;
  &lt;li&gt;not having rvm installed for passenger user&lt;/li&gt;
  &lt;li&gt;not having the basic gems required to use capistrano on the server, simply install them as the passenger user&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;testing&quot;&gt;Testing&lt;/h2&gt;

&lt;p&gt;View your domain in your browser and ensure it is loading.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Sendmail on domain host</title>
   <link href="http://kris.me.uk/2010/08/29/sendmail-on-domain-host.html"/>
   <updated>2010-08-29T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/08/29/sendmail-on-domain-host</id>
   <content type="html">&lt;p&gt;If you followed my guide for &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS Base Build&lt;/a&gt; then &lt;code&gt;/etc/hosts&lt;/code&gt; will have the following DNS entries and aliases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1 localhost.localdomain localhost
127.0.1.1 servername.domainname alias.domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This is ok as the servername and alias are subdomains.  Any email sent to &lt;code&gt;user@domainname&lt;/code&gt; will be delivered as expected by SMTP using the MX entry for the domain.&lt;/p&gt;

&lt;p&gt;However, it is possible to have an alias in the hosts file for the domain itself, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1 localhost.localdomain localhost
127.0.1.1 servername.domainname alias.domainname domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A consequence of this is that email to &lt;code&gt;user@domainname&lt;/code&gt; from that server will be delivered locally instead.&lt;/p&gt;

&lt;p&gt;Of course, this may be the desired behaviour, in which case it would warrant a more complicated setup.  For example; in a single server environment, instead of using aliases, a mail delivery agent (MDA) could deliver the mail to a mailbox that users can interact with accordingly.  Multi-server environments may have a mail server, in which case the other servers may have sendmail configured to use it as a smart host, e.g. the following may be added to &lt;code&gt;/etc/mail/sendmail.mc&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;define(`SMART_HOST&#39;, `mail.domainname&#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Getting back to a simple setup where email should be relayed, e.g. where email is provided by an external party such as gmail, the following lines can be added to the end of &lt;code&gt;/etc/mail/sendmail.mc&lt;/code&gt; to effectively disable local delivery:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;define(`MAIL_HUB&#39;, `domainname.&#39;)dnl
define(`LOCAL_RELAY&#39;, `domainname.&#39;)dnl
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note the dot after the domainname.  This allows the local routing to be circumvented.  You can also make the email addresses a little nicer by adding the following lines before the &lt;code&gt;MAILER_DEFINITIONS&lt;/code&gt; section:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;MASQUERADE_AS(`domainname&#39;)
FEATURE(`allmasquerade&#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When making modifications to &lt;code&gt;/etc/mail/sendmail.mc&lt;/code&gt;, be sure to run &lt;code&gt;sendmailconfig&lt;/code&gt; afterwards to update the compiled configuration and restart sendmail to use the new configuration.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>sshd and cron on Windows Using Cygwin</title>
   <link href="http://kris.me.uk/2010/08/27/sshd-and-cron-on-windows-using-cygwin.html"/>
   <updated>2010-08-27T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/08/27/sshd-and-cron-on-windows-using-cygwin</id>
   <content type="html">&lt;p&gt;For those working on windows who miss their linux command line friends, there is hope.  &lt;a href=&quot;http://www.cygwin.com/&quot;&gt;Cygwin&lt;/a&gt; is a great tool to allow you to use your favourite linux tools on your windows machine.  Installing and running cygwin is very simple, this guide presumes that you are familiar with linux and running cygwin shells.  This guide focuses on running linux daemons for ssh and cron.  The following instructions work on Windows 7 so your milage may vary on different versions.&lt;/p&gt;

&lt;p&gt;Note: on Windows Vista or Windows 7, you need to &lt;a href=&quot;http://support.microsoft.com/kb/305780&quot;&gt;run as administrator&lt;/a&gt; when launching the cygwin shell to allow the registry changes required in some of the steps below.  You can &lt;a href=&quot;http://technet.microsoft.com/en-us/magazine/ff431742.aspx&quot;&gt;configure&lt;/a&gt; cygwin to always launch with admin privileges if you wish.&lt;/p&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;/h2&gt;

&lt;p&gt;The following packages are required:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;cygrunsrv&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;openssh&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;cron&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;nano&lt;/code&gt; or &lt;code&gt;vim&lt;/code&gt; or another editor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ensure that the &lt;code&gt;$EDITOR&lt;/code&gt; environment property is set for your preferred editor, ideally in one of the profile files (e.g. &lt;code&gt;.bashrc&lt;/code&gt; or &lt;code&gt;.bash_profile&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id=&quot;windows-security&quot;&gt;Windows Security&lt;/h2&gt;

&lt;p&gt;As outlined in &lt;a href=&quot;http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1&quot;&gt;windows security in cygwin&lt;/a&gt;, there are 3 methods to allow the user context to switch without passwords.  The most appropriate choice is to use the LSA authentication package by running the &lt;code&gt;cyglsa-config&lt;/code&gt; script.  Simply run it and answer the questions posed.  The following is a typical log output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cyglsa-config

Warning: Registering the Cygwin LSA authentication package requires
administrator privileges!  You also have to reboot the machine to
activate the change.

Are you sure you want to continue? (yes/no) yes

Cygwin LSA authentication package registered.

Activating Cygwin&#39;s LSA authentication package requires to reboot.
Do you want to do this immediately? (yes/no) no
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now reboot when its safe.&lt;/p&gt;

&lt;p&gt;Alternatively, &lt;code&gt;passwd -R&lt;/code&gt; can be used to install a given users password into the registry but this may pose a security risk in some environments.&lt;/p&gt;

&lt;h2 id=&quot;openssh&quot;&gt;OpenSSH&lt;/h2&gt;

&lt;p&gt;Cygwin takes all the pain out of setting up sshd by providing a setup script called &lt;code&gt;ssh-host-config&lt;/code&gt;.  Simply run it and answer the questions posed.  The following is a typical log output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ ssh-host-config
*** Query: Overwrite existing /etc/ssh_config file? (yes/no) yes
*** Info: Creating default /etc/ssh_config file
*** Query: Overwrite existing /etc/sshd_config file? (yes/no) yes
*** Info: Creating default /etc/sshd_config file
*** Info: Privilege separation is set to yes by default since OpenSSH 3.3.
*** Info: However, this requires a non-privileged account called &#39;sshd&#39;.
*** Info: For more info on privilege separation read /usr/share/doc/openssh/README.privsep.
*** Query: Should privilege separation be used? (yes/no) yes
*** Info: Note that creating a new user requires that the current account have
*** Info: Administrator privileges.  Should this script attempt to create a
*** Query: new local account &#39;sshd&#39;? (yes/no) yes
*** Info: Updating /etc/sshd_config file

*** Warning: The following functions require administrator privileges!

*** Query: Do you want to install sshd as a service?
*** Query: (Say &quot;no&quot; if it is already installed as a service) (yes/no) yes
*** Query: Enter the value of CYGWIN for the daemon: [] ntsec tty
*** Info: On Windows Server 2003, Windows Vista, and above, the
*** Info: SYSTEM account cannot setuid to other users -- a capability
*** Info: sshd requires.  You need to have or to create a privileged
*** Info: account.  This script will help you do so.

*** Info: You appear to be running Windows 2003 Server or later.  On 2003
*** Info: and later systems, it&#39;s not possible to use the LocalSystem
*** Info: account for services that can change the user id without an
*** Info: explicit password (such as passwordless logins [e.g. public key
*** Info: authentication] via sshd).

*** Info: If you want to enable that functionality, it&#39;s required to create
*** Info: a new account with special privileges (unless a similar account
*** Info: already exists). This account is then used to run these special
*** Info: servers.

*** Info: Note that creating a new user requires that the current account
*** Info: have Administrator privileges itself.

*** Info: No privileged account could be found.

*** Info: This script plans to use &#39;cyg_server&#39;.
*** Info: &#39;cyg_server&#39; will only be used by registered services.
*** Query: Do you want to use a different name? (yes/no) no
*** Query: Create new privileged user account &#39;cyg_server&#39;? (yes/no) yes
*** Info: Please enter a password for new user cyg_server.  Please be sure
*** Info: that this password matches the password rules given on your system.
*** Info: Entering no password will exit the configuration.
*** Query: Please enter the password:
*** Query: Reenter:

*** Info: User &#39;cyg_server&#39; has been created with password &#39;xxxxxxxx&#39;.
*** Info: If you change the password, please remember also to change the
*** Info: password for the installed services which use (or will soon use)
*** Info: the &#39;cyg_server&#39; account.

*** Info: Also keep in mind that the user &#39;cyg_server&#39; needs read permissions
*** Info: on all users&#39; relevant files for the services running as &#39;cyg_server&#39;.
*** Info: In particular, for the sshd server all users&#39; .ssh/authorized_keys
*** Info: files must have appropriate permissions to allow public key
*** Info: authentication. (Re-)running ssh-user-config for each user will set
*** Info: these permissions corrently. [Similary restrictions apply, for
*** Info: instance, for .rhosts files if the rshd server is running, etc].

*** Info: The sshd service has been installed under the &#39;cyg_server&#39;
*** Info: account.  To start the service now, call `net start sshd&#39; or
*** Info: `cygrunsrv -S sshd&#39;.  Otherwise, it will start automatically
*** Info: after the next reboot.

*** Info: Host configuration finished. Have fun!
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As the instructions state, the sshd service can be started using either &lt;code&gt;net start sshd&lt;/code&gt;, &lt;code&gt;cygrunsrv -S sshd&lt;/code&gt; or even using the services management console.  Test the connection by sshing to localhost.  If you experience any problems try running in verbose mode, e.g:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh localhost
ssh username@localhost
ssh -vvv username@machinename
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Windows likes to title case usernames and allows spaces, therefore make sure the username is correct if this is the case, e.g. &lt;code&gt;ssh John\ Smith@localhost&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;cron&quot;&gt;Cron&lt;/h2&gt;

&lt;p&gt;Once again, Cygwin provides a script to install cron called &lt;code&gt;cron-config&lt;/code&gt;.  Simply run it and answer the questions posed.  Even if using &lt;code&gt;passwd -R&lt;/code&gt; or &lt;code&gt;cyglsa&lt;/code&gt; package, answer no to install the service under the &lt;code&gt;cyg_server&lt;/code&gt; user.  The following is a typical log output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ cron-config
Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec

You must decide under what account the cron daemon will run.
If you are the only user on this machine, the daemon can run as yourself.
   This gives access to all network drives but only allows you as user.
To run multiple users, cron must change user context without knowing
  the passwords. There are three methods to do that, as explained in
  http://cygwin.com/cygwin-ug-net/ntsec.html#ntsec-nopasswd1
If all the cron users have executed &quot;passwd -R&quot; (see man passwd),
  which provides access to network drives, or if you are using the
  cyglsa package, then cron should run under the local system account.
Otherwise you need to have or to create a privileged account.
  This script will help you do so.
Do you want the cron daemon to run as yourself? (yes/no) no

Were the passwords of all cron users saved with &quot;passwd -R&quot;, or
are you using the cyglsa package ? (yes/no) no

Attempting to find or create a privileged user.
The following accounts were found: &#39;cyg_server&#39; .
This script plans to use the name cyg_server for the new user,
which will only be able to run as a service.
Do you want to use another name (not an interactive account)? (yes/no) no

Please enter the password for user &#39;cyg_server&#39;:
Reenter:

Running cron_diagnose ...
WARNING: Your computer does not appear to have a cron table for username.
Please generate a cron table for username using &#39;crontab -e&#39;

... no problem found.

Do you want to start the cron daemon as a service now? (yes/no) yes
OK. The cron daemon is now running.

In case of problem, examine the log file for cron,
/var/log/cron.log, and the Windows event log (using /usr/bin/cronevents)
for information about the problem cron is having.

Examine also any cron.log file in the HOME directory
(or the file specified in MAILTO) and cron related files in /tmp.

If you cannot fix the problem, then report it to cygwin@cygwin.com.
Please run the script /usr/bin/cronbug and ATTACH its output
(the file cronbug.txt) to your e-mail.

WARNING: PATH may be set differently under cron than in interactive shells.
         Names such as &quot;find&quot; and &quot;date&quot; may refer to Windows programs.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I prefer to reinstall the cron service so that it is similarly named to the sshd service.  The following commands will remove the service and recreate it as desired:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cygrunsrv -R cron
cygrunsrv -I cron -d &quot;CYGWIN cron&quot; -u cyg_server -p /usr/sbin/cron -a -n
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Like any service, the cron service can be started using either &lt;code&gt;net start cron&lt;/code&gt;, &lt;code&gt;cygrunsrv -S cron&lt;/code&gt; or even using the services management console.&lt;/p&gt;

&lt;p&gt;Crontab entries can be made for a given user by logging in as that user and running &lt;code&gt;crontab -e&lt;/code&gt;.  This will use the &lt;code&gt;$EDITOR&lt;/code&gt; environment variable to determine which editor to use, and will also validate the file afterwards.  Essentially, using &lt;code&gt;crontab&lt;/code&gt; creates a file named after the user in &lt;code&gt;/var/cron/tabs&lt;/code&gt; with the correct permissions and ownership.&lt;/p&gt;

&lt;p&gt;For example, run &lt;code&gt;crontab -e&lt;/code&gt; and enter the following then save:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PATH=/usr/bin:/usr/sbin:.
*/10 * * * * echo `date` &amp;gt; /home/username/test-crontab.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will output the date every 10 minutes into the &lt;code&gt;/home/username/test-crontab.txt&lt;/code&gt; file.  Using the crontab command also informs cron to re-read the crontabs without having to restart the service.  Note that it is a good idea to supply the PATH environment variable to ensure that the execution path is correct for any commands.  HOME is set to the home of the user.&lt;/p&gt;

&lt;p&gt;Cron also checks for files in the system directory &lt;code&gt;/etc/cron.d&lt;/code&gt;.  By default this does not exist in cygwin so run the following commands to set this up with the required permissions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir /etc/cron.d
chmod 754 /etc/cron.d
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Additionally, any crontabs must be owned and only writable by SYSTEM.  You can ensure that crontabs have the correct permissions and ownership by running the following (after creating the crontab):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chmod 644 /etc/cron.d/*
chown SYSTEM:SYSTEM /etc/cron.d/*
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;System crontabs differ slightly from normal crontabs in that the first argument after the time and date fields is the username of the user to execute the command.  For example, create &lt;code&gt;/etc/cron.d/example&lt;/code&gt; with the following contents:&lt;/p&gt;

  	PATH=/usr/bin:/usr/sbin:.
  	HOME=/home/username
  	*/10 * * * * username echo &lt;code&gt;date&lt;/code&gt; &amp;gt; /home/username/test-cron.d.txt

&lt;h2 id=&quot;other-considerations&quot;&gt;Other Considerations&lt;/h2&gt;

&lt;h3 id=&quot;cron-problems&quot;&gt;Cron problems&lt;/h3&gt;

&lt;p&gt;If you are having problems then look at &lt;code&gt;C:\tools\cygwin\usr\share\doc\Cygwin\cron-*.README&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For example, you can install the service with some debug options for cron:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cygrunsrv -I cron -d &quot;CYGWIN cron&quot; -u cyg_server -p /usr/sbin/cron -a &quot;-x sch,proc,pars,load,misc&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;View the logs with something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cat /var/log/cron.log
cat /home/username/cron.log
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is lots of information in the man pages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;man crontab
man cron
man 5 crontab
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;bash-prompt-here&quot;&gt;Bash Prompt Here&lt;/h3&gt;

&lt;p&gt;This isn’t strictly part of this guide, but I think its so useful that I have to mention it.  The &lt;code&gt;chere&lt;/code&gt; package is a tool that creates a “bash prompt here” entry in windows explorer context menus.  To install it simply run the following (with admin rights):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chere -i
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;updates&quot;&gt;Updates&lt;/h3&gt;

&lt;p&gt;Sometimes when updating cygwin there are modifications to major binaries that require services to be stopped and possibly kill any cygwin processes that are running to allow the update to overwrite the files.  Simply restart the services after completion.  If there are updates to the LSA then you will need a reboot also.&lt;/p&gt;

&lt;h3 id=&quot;registering-users-in-passwd&quot;&gt;Registering users in passwd&lt;/h3&gt;

&lt;p&gt;Sometimes you need to register the user in passwd to allow ssh and cron to use the user.  This can be acheived using &lt;code&gt;mkpasswd&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check if the user is already registered:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cat /etc/passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If the user is a domain account then run the following to add them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkpasswd -d domain_name -u domain_username &amp;gt;&amp;gt; /etc/passwd
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If the user is a local account then run the following to add them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkpasswd -l -u local_username &amp;gt;&amp;gt; /etc/passwd
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Rails 3, RVM, Passenger and Capistrano</title>
   <link href="http://kris.me.uk/2010/08/05/rails3-rvm-passenger-capistrano.html"/>
   <updated>2010-08-05T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/08/05/rails3-rvm-passenger-capistrano</id>
   <content type="html">&lt;p&gt;This post builds on my previous posts on &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS Base Build&lt;/a&gt; and &lt;a href=&quot;/2010/07/11/rack-app-hosting-with-rvm-and-passenger.html&quot;&gt;RVM and Passenger&lt;/a&gt; to create a suitable &lt;a href=&quot;http://www.capify.org/&quot;&gt;capistrano&lt;/a&gt; config file for deploying rails 3 applications.&lt;/p&gt;

&lt;p&gt;Assuming you have followed the previous posts, you should be able to run simple rack applications and have a passenger user setup with ssh access.  You should also have a rails 3 application that you would like to deploy and ideally this should be using git for source control.&lt;/p&gt;

&lt;h2 id=&quot;capistrano-configuration&quot;&gt;Capistrano configuration&lt;/h2&gt;

&lt;p&gt;Make sure you have capistrano install:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install capistrano
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initialise the rails application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/dev/mywebsite
capify .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will generate some files, along with a sample &lt;code&gt;config/deploy.rb&lt;/code&gt;.  Replace the file contents with the following, using suitable values where applicable.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# RVM bootstrap
$:.unshift(File.expand_path(&quot;~/.rvm/lib&quot;))
require &#39;rvm/capistrano&#39;
set :rvm_ruby_string, &#39;1.9.2&#39;
set :rvm_type, :user

# main details
set :application, &quot;mywebsite&quot;
role :web, &quot;mywebsite.com&quot;
role :app, &quot;mywebsite.com&quot;
role :db,  &quot;mywebsite.com&quot;, :primary =&amp;gt; true

# server details
default_run_options[:pty] = true
ssh_options[:forward_agent] = true
set :deploy_to, &quot;/var/www/mywebsite&quot;
set :deploy_via, :remote_cache
set :user, &quot;passenger&quot;
set :use_sudo, false

# repo details
set :scm, :git
set :scm_username, &quot;passenger&quot;
set :repository, &quot;git@gitserver:mywebsite.git&quot;
set :branch, &quot;master&quot;
set :git_enable_submodules, 1

# runtime dependencies
depend :remote, :gem, &quot;bundler&quot;, &quot;&amp;gt;=1.0.0.rc.2&quot;

# tasks
namespace :deploy do
  task :start, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  task :stop, :roles =&amp;gt; :app do
    # Do nothing.
  end

  desc &quot;Restart Application&quot;
  task :restart, :roles =&amp;gt; :app do
    run &quot;touch #{current_path}/tmp/restart.txt&quot;
  end

  desc &quot;Symlink shared resources on each release&quot;
  task :symlink_shared, :roles =&amp;gt; :app do
    #run &quot;ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml&quot;
  end
end

after &#39;deploy:update_code&#39;, &#39;deploy:symlink_shared&#39;

namespace :bundler do
  desc &quot;Symlink bundled gems on each release&quot;
  task :symlink_bundled_gems, :roles =&amp;gt; :app do
    run &quot;mkdir -p #{shared_path}/bundled_gems&quot;
    run &quot;ln -nfs #{shared_path}/bundled_gems #{release_path}/vendor/bundle&quot;
  end

  desc &quot;Install for production&quot;
  task :install, :roles =&amp;gt; :app do
    run &quot;cd #{release_path} &amp;amp;&amp;amp; bundle install --production&quot;
  end

end

after &#39;deploy:update_code&#39;, &#39;bundler:symlink_bundled_gems&#39;
after &#39;deploy:update_code&#39;, &#39;bundler:install&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;capistrano-deployment&quot;&gt;Capistrano deployment&lt;/h2&gt;

&lt;p&gt;The first time you deploy to the server you should run the deployment setup task:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:setup
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thereafter you can deploy using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you have database migrations to run then use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cap deploy:migrations
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may get some strange errors or failures when deploying.  If you have followed the steps I have mentioned in this and previous articles then you shouldn’t have many problems.  Common problems are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;wrong permissions of &lt;code&gt;/var/www&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;wrong permissions of passenger user&lt;/li&gt;
  &lt;li&gt;not having rvm installed for passenger users&lt;/li&gt;
  &lt;li&gt;not having the basic gems required to use capistrano on the server, simply install them as the passenger user&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;apache-configuration&quot;&gt;Apache configuration&lt;/h2&gt;

&lt;p&gt;You now need to create a virtual host for the website so that apache can handle the requests and pass off to passenger.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/mywebsite.com&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName mywebsite.com
    DocumentRoot /var/www/mywebsite/public
    &amp;lt;Directory /var/www/mywebsite/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, and then view it in your browser:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite mywebsite.com
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Rack Application Hosting on Ubuntu Lucid using RVM and Passenger</title>
   <link href="http://kris.me.uk/2010/07/11/rack-app-hosting-with-rvm-and-passenger.html"/>
   <updated>2010-07-11T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/07/11/rack-app-hosting-with-rvm-and-passenger</id>
   <content type="html">&lt;p&gt;Thanks to &lt;a href=&quot;http://rvm.beginrescueend.com/&quot;&gt;Ruby Version Manager (rvm)&lt;/a&gt; and &lt;a href=&quot;http://www.phusion.nl/&quot;&gt;Phusion&lt;/a&gt; &lt;a href=&quot;http://www.modrails.com/&quot;&gt;Passenger&lt;/a&gt; setting up a server to run rack (and therefore rails or sinatra) applications is very simple.&lt;/p&gt;

&lt;p&gt;This post is an update to my &lt;a href=&quot;/2010/01/02/rack-app-hosting.html&quot;&gt;earlier post&lt;/a&gt; that used &lt;a href=&quot;http://www.rubyenterpriseedition.com/&quot;&gt;Ruby Enterprise Edition&lt;/a&gt; directly rather than allowing a choice of ruby versions through &lt;a href=&quot;http://rvm.beginrescueend.com/&quot;&gt;rvm&lt;/a&gt;.  It also assumes that you have a server following the &lt;a href=&quot;/2010/07/10/ubuntu-lucid-vps-base-build.html&quot;&gt;Ubuntu Lucid VPS Base Build&lt;/a&gt; post.&lt;/p&gt;

&lt;p&gt;With the impending release of Rails 3, this post will cover the installation of Ruby 1.9.2, although the steps are applicable for other rubies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated 2010-08-01&lt;/strong&gt;: Ruby 1.9.2 rc2 is now available so updated to use correct paths.  Application config now sets up an example Hello World rack application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updated 2010-08-30&lt;/strong&gt;: Rails 3, Ruby 1.9.2, Bundler 1.0 released - &lt;a href=&quot;/2010/08/30/rails3-hosting-all-in-one.html&quot;&gt;see rails 3 hosting all in one&lt;/a&gt; for updated instructions.&lt;/p&gt;

&lt;h2 id=&quot;user&quot;&gt;User&lt;/h2&gt;

&lt;p&gt;It is a good idea to create a passenger user to install rvm for so that other users do not modify it by accident.  You can also deploy your applications using this user.  The passenger user needs sudo rights for installing packages using apt-get and running the passenger install script.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser passenger
sudo usermod -G passenger,www-data,sudo passenger
su - passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can remove the sudo right after completing the installation using the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo usermod -G passenger,www-data passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Its also a good idea to generate a key pair for ssh too.  The public key can be stored in &lt;code&gt;~passenger/.ssh/authorized_keys&lt;/code&gt; and if you use ssh agent forwarding you do not need to store the private key on the server.  This is very useful if you use something like capistrano to handle your deployments.&lt;/p&gt;

&lt;h2 id=&quot;rvm&quot;&gt;RVM&lt;/h2&gt;

&lt;p&gt;rvm is installed locally for each user rather than a single install for the server.  This allows different versions to be used by different users on the server.  Unfortunately, only one ruby version can be used with passenger at the moment due to the way passenger hooks into apache.&lt;/p&gt;

&lt;p&gt;Install using the preferred script:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bash &amp;lt; &amp;lt;( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some warnings about issues with &lt;code&gt;return&lt;/code&gt; in &lt;code&gt;.bashrc&lt;/code&gt;.  This appears to be a red herring for Ubuntu as mentioned in this &lt;a href=&quot;http://ubuntuforums.org/showthread.php?t=1392189&quot;&gt;post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Simply edit &lt;code&gt;.bashrc&lt;/code&gt; and add the following line at the bottom:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[[ -s $HOME/.rvm/scripts/rvm ]] &amp;amp;&amp;amp; source $HOME/.rvm/scripts/rvm
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Log out and log in again as passenger to ensure the scripts work as expected.  You can test rvm is available correctly by running:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;type rvm | head -n1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should then see the following output:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm is a function
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can view the notes about requirements for installing the different rubies by running &lt;code&gt;rvm notes&lt;/code&gt;.  The list of packages at the time of writing had dependency conflicts which can be circumvented by removing &lt;code&gt;libreadline5-dev&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To install the packages (requires sudo):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install openssl curl git-core subversion autoconf \
                     build-essential bison zlib1g zlib1g-dev \
                     libssl-dev libxml2-dev libreadline5 libreadline-dev \
                     libreadline6-dev libsqlite3-0 libsqlite3-dev sqlite3
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To install the rubies, first 1.8.7 as the notes indicate, followed by 1.9.2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm install 1.8.7
rvm use 1.8.7
rvm install 1.9.2
rvm use --default 1.9.2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can can now verify the ruby version and install some gems, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby -v
gem install rails --pre
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;passenger&quot;&gt;Passenger&lt;/h2&gt;

&lt;p&gt;Passenger is very easy to install.  rvm provides some &lt;a href=&quot;http://rvm.beginrescueend.com/integration/passenger/&quot;&gt;instructions&lt;/a&gt; specifically for passenger.&lt;/p&gt;

&lt;p&gt;Tell rvm the desired version of ruby to use:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm 1.9.2 --passenger
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install the gem and run the installation script.  It will tell you what dependencies you are missing and how to install them:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install passenger
rvmsudo /home/passenger/.rvm/gems/ruby-1.9.2-rc2/bin/passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I had to run the following to fix the missing dependencies:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install apache2-prefork-dev libapr1-dev libaprutil1-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Passenger provides some instructions on how to configure apache, although, due to the way rvm works, the value of &lt;code&gt;PassengerRuby&lt;/code&gt; should be different.  I like to treat passenger as a mod for apache, allowing it to be enabled and disabled as required through the &lt;code&gt;a2enmod&lt;/code&gt; and &lt;code&gt;a2dismod&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;To enable passenger, create &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LoadModule passenger_module /home/passenger/.rvm/gems/ruby-1.9.2-rc2/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and &lt;code&gt;/etc/apache2/mods-available/passenger.conf&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PassengerRoot /home/passenger/.rvm/gems/ruby-1.9.2-rc2/gems/passenger-2.2.15
PassengerRuby /home/passenger/.rvm/bin/passenger_ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then enable the module and restart apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod passenger
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;application-config&quot;&gt;Application config&lt;/h2&gt;

&lt;p&gt;Each rack/rails application is made available through a virtual host directive in the apache configuration.  The recommended way to do this is to create a file named after the site, e.g. &lt;code&gt;example.com&lt;/code&gt; in &lt;code&gt;/etc/apache2/sites-available&lt;/code&gt; and then enable and disable the site as required using the &lt;code&gt;a2ensite&lt;/code&gt; and &lt;code&gt;a2dissite&lt;/code&gt; commands respectively.&lt;/p&gt;

&lt;p&gt;I find it useful to have a simple Hello World rack application to verify the installation.  The application can be run as a subdomain to allow testing and can be enabled and disabled as desired.&lt;/p&gt;

&lt;p&gt;I prefer to put all web applications in &lt;code&gt;/var/www&lt;/code&gt; and have users be able to create applications if they are a member of &lt;code&gt;www-data&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo chown www-data:www-data /var/www
sudo chmod g+w /var/www
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, create the necessary directory structure for an application:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www
mkdir hw.example.com
cd hw.example.com
mkdir public
mkdir tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/var/www/hw.example.com/config.ru&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app = proc do |env|
  [200, { &quot;Content-Type&quot; =&amp;gt; &quot;text/html&quot; }, [&quot;hello, world&quot;]]
end
run app
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create &lt;code&gt;/etc/apache2/sites-available/hw.example.com&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName hw.example.com
    DocumentRoot /var/www/hw.example.com/public
    &amp;lt;Directory /var/www/hw.example.com/public&amp;gt;
        AllowOverride all
        Options -MultiViews
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site, and then view it in your browser:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite hw.example.com
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can then be disabled and reenabled if needed for debugging any issues at a later date:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2dissite hw.example.com
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Ubuntu Lucid VPS Base Build</title>
   <link href="http://kris.me.uk/2010/07/10/ubuntu-lucid-vps-base-build.html"/>
   <updated>2010-07-10T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/07/10/ubuntu-lucid-vps-base-build</id>
   <content type="html">&lt;p&gt;This post is an update to &lt;a href=&quot;/2009/12/30/ubuntu-base-server-build.html&quot;&gt;Ubuntu Jaunty Base Server Build&lt;/a&gt;, but focuses on Ubuntu Server 10.04 (Lucid).  Unfortunately, I was planning on just updating using &lt;a href=&quot;http://www.ubuntu.com/desktop/get-ubuntu/upgrade&quot;&gt;do-release-upgrade&lt;/a&gt;, however, after what seemed like a successful upgrade the VPS never came back to life and as it was remote I could not attempt to fix it.  I had planned for failure, so I had a backup of all my instructions on this blog and the data too.&lt;/p&gt;

&lt;p&gt;The aim is to provide a basic build that is secure for living out on the internet, has a basic web server stack (i.e. LAMP: Apache HTTP Server, MySql, PHP) and any other useful basic utilities.  Future posts will rely on this build when covering additional application installations.&lt;/p&gt;

&lt;h2 id=&quot;base-install&quot;&gt;Base install&lt;/h2&gt;

&lt;p&gt;The initial image I was given was Ubuntu Server 10.04 with root being the only interactive user (i.e. able to log on).  ssh was available using passwords.  Apache2 and PHP packages were installed in addition to the essentials.  The following command can be run to provide information about the installation, which may be of use when asking for help on forums:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;lsb_release -a
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: It is best practice to log into the server as a non-root user and when necessary use elevated permissions through the &lt;code&gt;sudo&lt;/code&gt; command.  The standard Ubuntu installation does not expose the root user, instead you create a user during the installation and login using that user.  Setting up the user is covered in a later section called Users and Sudoers.  Regardless of this, all commands that require sudo have been prefixed with it as it is good practice to get use to this.&lt;/p&gt;

&lt;h2 id=&quot;getting-up-to-date&quot;&gt;Getting up-to-date&lt;/h2&gt;

&lt;p&gt;Ubuntu uses &lt;code&gt;apt&lt;/code&gt; as its default package manager. Run the following commands to upgrade the installed packages to the latest version.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more information visit the &lt;a href=&quot;https://help.ubuntu.com/community/AptGet/Howto&quot;&gt;Ubuntu Community Documentation AptGet HowTo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The server can also be configured to apply automatic updates for certain categories of updates, e.g. all, security.  Alternatively, the &lt;code&gt;apticron&lt;/code&gt; package can be used for notification of any updates that are available.  See &lt;a href=&quot;https://help.ubuntu.com/10.04/serverguide/C/automatic-updates.html&quot;&gt;automatic updates&lt;/a&gt; in the server guide for more details.&lt;/p&gt;

&lt;h2 id=&quot;additional-util-packages&quot;&gt;Additional util packages&lt;/h2&gt;

&lt;p&gt;The following packages are also useful to have installed, so run the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install nano bash-completion aptitude curl
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;configure-hostname&quot;&gt;Configure hostname&lt;/h2&gt;

&lt;p&gt;Its a good idea to give your machine the correct hostname as early as possible.  Some packages may use the hostname during installation and therefore if you change it later you may encounter some issues.&lt;/p&gt;

&lt;p&gt;The simplest way to set the host name permanently is to modify (or create if not present) the &lt;code&gt;/etc/hostname&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo servername.domainname | sudo tee /etc/hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above command will take effect after a reboot.  You can also change the hostname for the current boot of the VPS using the &lt;code&gt;hostname&lt;/code&gt; command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo hostname servername.domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You also need to update &lt;code&gt;/etc/hosts&lt;/code&gt; with DNS entries and aliases like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1 localhost.localdomain localhost
127.0.1.1 servername.domainname alias.domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following commands should respond suitably:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;uname -n
hostname -a
hostname -s
hostname -d
hostname -f
hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;correcting-the-server-time&quot;&gt;Correcting the server time&lt;/h2&gt;

&lt;p&gt;Depending on the image used, the server may be in the wrong timezone.  Run the following commands to reconfigure and utilise NTP to sync the clock:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo dpkg-reconfigure tzdata
sudo apt-get install ntpdate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that it may require a change by the VPS provider to fix the host machines clock if the time is still incorrect but the server is in the correct timezone.&lt;/p&gt;

&lt;p&gt;For more information visit the &lt;a href=&quot;https://help.ubuntu.com/community/UbuntuTime&quot;&gt;Ubuntu Community Time&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h2 id=&quot;users-and-sudoers&quot;&gt;Users and Sudoers&lt;/h2&gt;

&lt;p&gt;Sudoers controls who can run what commands as which users on which machines.  Therefore, it is good practice to create an administrator with the appropriate permissions and use &lt;code&gt;sudo&lt;/code&gt; as required.&lt;/p&gt;

&lt;p&gt;Run the following command to add a user:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add the user to additional groups as required, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo usermod -a -G sudo,adm,www-data &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By adding the user to the sudo group the user should be granted full sudo priviledges.  If this is not the case, or you wish to modify the priviledges, then modify &lt;code&gt;/etc/sudoers&lt;/code&gt; accordingly using &lt;code&gt;visudo&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo visudo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adding the following entry would give the user the same rights as root:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;username ALL=(ALL) ALL
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more information visit the &lt;a href=&quot;https://help.ubuntu.com/community/Sudoers&quot;&gt;Ubuntu Community Documentation Sudoers Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note: now that you have a user, it would be a good idea to log out as root and log in as the new user in line with best practices.&lt;/p&gt;

&lt;h2 id=&quot;email-forwarding&quot;&gt;Email forwarding&lt;/h2&gt;

&lt;p&gt;Email is used as a primary notification mechanism for linux, however, by default, email is stored on the server.  If you do not intend to set the server up as an email server (e.g. POP3 or IMAP), it is useful to forward email to an appropriate external email address.  There are two main approaches to this (with sendmail which is the default MTA):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;root maintains email addresses in &lt;code&gt;/etc/aliases&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;each user maintains their email address in &lt;code&gt;~/.forward&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is possible to also combined the two approaches, by aliasing root to a given user and then the user being able to allocate the email address as they see fit.&lt;/p&gt;

&lt;p&gt;This is covered in the man pages for aliases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;man aliases
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;modifying-aliases&quot;&gt;Modifying aliases&lt;/h3&gt;

&lt;p&gt;e.g. alias root to another user, edit &lt;code&gt;/etc/aliases&lt;/code&gt;, adding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root:           &amp;lt;otheruser&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;e.g. alias root to external email addresses (comma separated), edit &lt;code&gt;/etc/aliases&lt;/code&gt;, adding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root:           user1@example.com, user2@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: after modifying &lt;code&gt;/etc/aliases&lt;/code&gt; you must run &lt;code&gt;newaliases&lt;/code&gt; to refresh the alias database for the changes to take affect, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo newaliases
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;creating-forward&quot;&gt;Creating .forward&lt;/h3&gt;

&lt;p&gt;The simplest way to do this is to log in as the user required and run the following command (replacing the email address as appropriate):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo username@example.com &amp;gt; ~/.forward
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;secure-shell-ssh&quot;&gt;Secure Shell (SSH)&lt;/h2&gt;

&lt;p&gt;Secure shell (ssh) is the defacto standard for remote shell access.&lt;/p&gt;

&lt;h3 id=&quot;client&quot;&gt;Client&lt;/h3&gt;

&lt;p&gt;You can connect to a remote machine using the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh username@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will usually be prompted for your password.  &lt;/p&gt;

&lt;p&gt;Rather than using a password you can use key based authentication.  On your client machine, create a key and use a string pass phrase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -v -t rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a &lt;code&gt;~/.ssh&lt;/code&gt; directory containing &lt;code&gt;id_rsa&lt;/code&gt; which is your private key and &lt;code&gt;id_rsa.pub&lt;/code&gt; which is your public key.  Its important to have the correct permissions, so check the output of &lt;code&gt;ls -la ~/.ssh&lt;/code&gt; is similar for the following entries:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;drwx------   5 user  group   170 22 Mar 07:04 .
-rwx------   1 user  group  1743 22 Mar 07:04 id_rsa
-rwxr--r--   1 user  group   397 22 Mar 07:04 id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can copy you public key up to a server using the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp ~/.ssh/id_rsa.pub username@hostname:~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to ssh to the server without being challenged for a password, e.g:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh username@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depending on the client and your preference, you can either enter the passphrase for you private key each time you connect, or run &lt;code&gt;ssh-agent&lt;/code&gt; and register the key using &lt;code&gt;ssh-add&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;server&quot;&gt;Server&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;sshd&lt;/code&gt; is the ssh daemon and is responsible for providing ssh access to the server.  Its important to ensure that this is secure as possible.  There are a number of articles out there about changing the configuration of sshd to make it more secure, in particular I like to turn off password authentication (forcing the use of public/private key pairs) and disable root login.  &lt;strong&gt;Of course, you should ensure that you have a suitable user able to log in using a key that you have tested before you lock yourself out permanently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The configuration for sshd is found at &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;.  Modify it to have the following lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PasswordAuthentication no
PermitRootLogin no
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Restart sshd for your changes to take effect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo /etc/init.d/ssh restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;basic-web-server-stack&quot;&gt;Basic web server stack&lt;/h2&gt;

&lt;p&gt;The basic stack of Apache HTTP Server (A), MySQL (M) and PHP (P) is known as AMP due to the initials, or LAMP on Linux.&lt;/p&gt;

&lt;p&gt;Apache HTTP Server and PHP were already installed and available on the VPS, however, you can make sure by running the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install apache2 php5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As part of the MySQL installation, I like to install phpMyAdmin as this is a really useful admin application.  Install mysql server and phpMyAdmin packages, entering suitable values when prompted:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install mysql-server phpMyAdmin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Check connectivity by accessing the site using &lt;code&gt;http://servername/phpmyadmin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;phpmyadmin could be used by hackers to brute force attack your databases as it provides a form on the web to attempt log ons.  As always, you should use suitably strong passwords to ensure that this is not easily done, and also use suitable permissions for the database users to minimise external access.  The best way to avoid attack is to only have phpmyadmin available when you are using it.  This can be achieved by removing the symlink in &lt;code&gt;/etc/apache2/conf.d&lt;/code&gt; and managing phpmyadmin’s availability using the &lt;code&gt;a2ensite&lt;/code&gt; and &lt;code&gt;a2dissite&lt;/code&gt; commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo rm /etc/apache2/conf.d/phpmyadmin.conf
sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/sites-available/phpmyadmin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can then enable it using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite phpmyadmin
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And disable it using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2dissite phpmyadmin
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;system-monitoring&quot;&gt;System Monitoring&lt;/h2&gt;

&lt;h3 id=&quot;keeping-an-eye-on-utilisation&quot;&gt;Keeping an eye on utilisation&lt;/h3&gt;

&lt;p&gt;Disk space can be checked using &lt;code&gt;df&lt;/code&gt;.  Memory usage can be checked using &lt;code&gt;free&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;issues&quot;&gt;Issues&lt;/h2&gt;

&lt;h3 id=&quot;something-went-wrong&quot;&gt;Something went wrong&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://help.ubuntu.com/10.04/serverguide/C/index.html&quot;&gt;Ubuntu Server Guide&lt;/a&gt; should be able to help you.  If not then try to post on a suitable forum or mailing list with as much detail as possible.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Favourite Mac OS-X Apps</title>
   <link href="http://kris.me.uk/2010/06/01/favourite-mac-osx-apps.html"/>
   <updated>2010-06-01T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/06/01/favourite-mac-osx-apps</id>
   <content type="html">&lt;p&gt;This guide covers applications that I like to run on the mac.  I work on multiple platforms so where possible I prefer to use cross platform software.&lt;/p&gt;

&lt;h2 id=&quot;power-tools&quot;&gt;Power Tools&lt;/h2&gt;

&lt;p&gt;I find the following collection of power tools useful:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.ragingmenace.com/software/menumeters/index.html&quot;&gt;MenuMeters&lt;/a&gt; provides resource monitoring on the menubar&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://wakaba.c3.cx/s/apps/unarchiver.html&quot;&gt;The Unarchiver&lt;/a&gt; is a replacement basic unarchiver that supports more formats&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;preference-panes&quot;&gt;Preference Panes&lt;/h2&gt;

&lt;p&gt;The following preference pane snap-ins can be very helpful:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.rubicode.com/Software/RCDefaultApp/&quot;&gt;RCDefaultApp&lt;/a&gt; allows default applications to be configured more easily&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;browser&quot;&gt;Browser&lt;/h2&gt;

&lt;p&gt;I use a mixture of &lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Google Chrome&lt;/a&gt; and &lt;a href=&quot;http://www.mozilla.com/en-US/firefox/&quot;&gt;Firefox&lt;/a&gt; depending on what I’m doing and how well the sites work in the browsers.  I’m tending to use Chrome most of the time and falling back to Firefox these days - they both have good plugin support these days.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.xmarks.com&quot;&gt;Xmarks&lt;/a&gt;, formerly known as Foxmarks, is what I use to sync bookmarks between platforms and browsers.  Firefox and Chrome both have plugins for this.&lt;/p&gt;

&lt;p&gt;For Chrome I use the following plugins:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Google Dictionary&lt;/li&gt;
  &lt;li&gt;RSS Subscriptions Extension (by Google)&lt;/li&gt;
  &lt;li&gt;Xmarks Bookmarks Sync&lt;/li&gt;
  &lt;li&gt;Google Mail Checker&lt;/li&gt;
  &lt;li&gt;Google Reader Notifier&lt;/li&gt;
  &lt;li&gt;Notifier for Google Wave&lt;/li&gt;
  &lt;li&gt;Google Calendar Checker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Firefox I use the following plugins:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Better Gmail 2 - bundle of user scripts for gmail&lt;/li&gt;
  &lt;li&gt;Better Flickr - bundle of user scripts for flickr&lt;/li&gt;
  &lt;li&gt;DownloadHelper - downloading images and video&lt;/li&gt;
  &lt;li&gt;DownThemAll! - mass downloader&lt;/li&gt;
  &lt;li&gt;FiddlerHook - tie in for fiddler (windows)&lt;/li&gt;
  &lt;li&gt;Firebug - dev tools&lt;/li&gt;
  &lt;li&gt;Fission - progress bar (mac)&lt;/li&gt;
  &lt;li&gt;FlashGot - download manager integrator&lt;/li&gt;
  &lt;li&gt;Greasemonkey - user scripts&lt;/li&gt;
  &lt;li&gt;IETab - allows sites to be viewed in firefox using IE (windows)&lt;/li&gt;
  &lt;li&gt;Refractor for Prism - allows creation of dockable apps from websites&lt;/li&gt;
  &lt;li&gt;Web Developer - dev tools&lt;/li&gt;
  &lt;li&gt;Xmarks - cross platform and browser bookmark sync&lt;/li&gt;
  &lt;li&gt;YSlow - extends Firebug to provide suggested improvements for better sites&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;notifications&quot;&gt;Notifications&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.growl.info/&quot;&gt;Growl&lt;/a&gt; is the notification system for the mac.  Many other applications, including apple ones, utilise growl if installed.&lt;/p&gt;

&lt;h2 id=&quot;instant-messaging&quot;&gt;Instant messaging&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://adium.im/&quot;&gt;Adium&lt;/a&gt; is a generic chat client with support for most chat protocols that also integrates with &lt;a href=&quot;http://www.growl.info/&quot;&gt;Growl&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;ftp&quot;&gt;FTP&lt;/h2&gt;

&lt;h3 id=&quot;ftp-client&quot;&gt;FTP Client&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://filezilla-project.org/&quot;&gt;Filezilla&lt;/a&gt; is a free, open source, cross platform ftp client.  &lt;a href=&quot;http://cyberduck.ch/&quot;&gt;Cyberduck&lt;/a&gt; is a free, open source FTP, SFTP, WebDav and cloud browser for Mac OS-X.&lt;/p&gt;

&lt;h3 id=&quot;ftp-server&quot;&gt;FTP Server&lt;/h3&gt;

&lt;p&gt;FTP is available as part of OS-X, if enabled.&lt;/p&gt;

&lt;h2 id=&quot;media&quot;&gt;Media&lt;/h2&gt;

&lt;h3 id=&quot;codec&quot;&gt;Codec&lt;/h3&gt;

&lt;p&gt;Whilst OS-X comes with QuickTime, it only supports a few codecs.  Additional codecs can be supported via plugins.  I have used the following:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.telestream.net/flip4mac-wmv/overview.htm&quot;&gt;flip4mac&lt;/a&gt; - plays WMV, pro version allows conversion to mac formats for use in iMovie&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://perian.org/&quot;&gt;Perian&lt;/a&gt; - many other codecs&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.apple.com/quicktime/mpeg2/&quot;&gt;MPEG2&lt;/a&gt; - apple’s quicktime MPEG2 playback codec (needs to be purchased)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;video-conversion&quot;&gt;Video Conversion&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.squared5.com/svideo/mpeg-streamclip-mac.html&quot;&gt;MPEG Streamclip&lt;/a&gt; is a conversion tool that supports the codecs installed.&lt;/p&gt;

&lt;h3 id=&quot;player&quot;&gt;Player&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.videolan.org/&quot;&gt;VLC&lt;/a&gt; is a really good cross platform media player with support for most formats.&lt;/p&gt;

&lt;p&gt;If you need to play real media then there is a &lt;a href=&quot;http://www.real.com/mac/realplayer&quot;&gt;RealPlayer&lt;/a&gt; for the mac also.&lt;/p&gt;

&lt;h3 id=&quot;transcoder&quot;&gt;Transcoder&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://handbrake.fr/&quot;&gt;Handbrake&lt;/a&gt; is a good cross platform video transcoder.&lt;/p&gt;

&lt;h2 id=&quot;uninstaller&quot;&gt;Uninstaller&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.appzapper.com/&quot;&gt;AppZapper&lt;/a&gt; is a commercial tool for removing all traces of an installed application.  I’ve not used it but may help if there is a really pesky app that needs removing.&lt;/p&gt;

&lt;h2 id=&quot;sync&quot;&gt;Sync&lt;/h2&gt;

&lt;h3 id=&quot;isync&quot;&gt;iSync&lt;/h3&gt;

&lt;p&gt;iSync can be used to sync to your mobile if its supported.  My work one (Nokia 3109 Classic - euk) isn’t supported, but there are &lt;a href=&quot;http://www.james-lloyd.com/scripts/nokia-series-40-isync-plugin/&quot;&gt;ways to get it working&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;file&quot;&gt;File&lt;/h3&gt;

&lt;p&gt;There are two main applications in this area; &lt;a href=&quot;http://www.cis.upenn.edu/~bcpierce/unison/&quot;&gt;Unison&lt;/a&gt; is an open source project that is powerful but requires a fair amount of user knowledge, &lt;a href=&quot;http://www.econtechnologies.com/pages/cs/chrono_overview.html&quot;&gt;ChronoSync&lt;/a&gt; is a commercial application with a much richer user interface.&lt;/p&gt;

&lt;h3 id=&quot;dropbox&quot;&gt;Dropbox&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;https://www.dropbox.com/referrals/NTEwNDg0MjI5&quot;&gt;Dropbox&lt;/a&gt; only syncs files you put into it but has the advantage that its software as a service and therefore a backup is stored on a server and you can also access files through the website or mobile phone applications.  Its free for up to 2GB of storage.&lt;/p&gt;

&lt;h2 id=&quot;text-editor&quot;&gt;Text Editor&lt;/h2&gt;

&lt;p&gt;There are quite a number of text editors available, however, there is a lot of support for &lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt; on the mac.  This is one of the few applications that is not free in this guide, but I have to say that I think its one of the best I’ve used.&lt;/p&gt;

&lt;h3 id=&quot;bundles-and-extension&quot;&gt;Bundles and Extension&lt;/h3&gt;

&lt;p&gt;TextMate comes with a large set of “Bundles” for most languages or tasks which can be modified to suit although they are great just out of the box.  Open source projects often create bundles to ease adoption and use of their products and libraries, some of my favourites include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;http://github.com/aslakhellesoy/cucumber-tmbundle&lt;/li&gt;
  &lt;li&gt;http://github.com/rspec/rspec-tmbundle&lt;/li&gt;
  &lt;li&gt;http://github.com/kuroir/SCSS.tmbundle&lt;/li&gt;
  &lt;li&gt;http://github.com/glennr/uber-glory-tmbundle&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These can be installed using a command prompt, for example to install the rspec bundle:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/Library/Application\ Support/TextMate/Bundles/
git clone git://github.com/rspec/rspec-tmbundle.git RSpec.tmbundle
osascript -e &#39;tell app &quot;TextMate&quot; to reload bundles&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;tips&quot;&gt;Tips&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;http://blogobaggins.com/2009/03/31/waging-war-on-whitespace.html&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;shortcuts&quot;&gt;Shortcuts&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Toggle comments - ⌘ /&lt;/li&gt;
  &lt;li&gt;Drawer - ⌃ ⌥ ⌘ D&lt;/li&gt;
  &lt;li&gt;Bracket Select - ⇧ ⌘ B&lt;/li&gt;
  &lt;li&gt;Select Item - ⌃ ⌘ T&lt;/li&gt;
  &lt;li&gt;Amend Lines - ⌥ ⌘ A&lt;/li&gt;
  &lt;li&gt;Delete to EOL - ⌃ D&lt;/li&gt;
  &lt;li&gt;Next Line - ⌘ ↩&lt;/li&gt;
  &lt;li&gt;Goto file - ⌘ T&lt;/li&gt;
  &lt;li&gt;Goto Symbol - ⇧ ⌘ T&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;remote-desktop&quot;&gt;Remote Desktop&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.microsoft.com/mac/products/remote-desktop/default.mspx&quot;&gt;Remote Desktop for Mac&lt;/a&gt; allows a windows machine to be controlled from your mac.&lt;/p&gt;

&lt;h2 id=&quot;cisco-vpn-client&quot;&gt;Cisco VPN Client&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.macupdate.com/info.php/id/10317&quot;&gt;Cisco VPN Client&lt;/a&gt; can be used to connect to a Cisco VPN.&lt;/p&gt;

&lt;h2 id=&quot;mac-development&quot;&gt;Mac Development&lt;/h2&gt;

&lt;h3 id=&quot;xcode&quot;&gt;XCode&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.apple.com/tools/xcode/&quot;&gt;Xcode&lt;/a&gt; is a suite of development tools used to create Mac and iPhone applications.  It provides a number of building blocks for other applications, such as build tools and compilers.&lt;/p&gt;

&lt;h2 id=&quot;command-line&quot;&gt;Command Line&lt;/h2&gt;

&lt;h3 id=&quot;homebrew&quot;&gt;Homebrew&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://github.com/mxcl/homebrew&quot;&gt;Homebrew&lt;/a&gt; is the latest package manager to hit OS-X and is gaining a large following.  I was using &lt;a href=&quot;http://www.macports.org/&quot;&gt;Macports&lt;/a&gt; but I’ve just switched and &lt;a href=&quot;http://guide.macports.org/chunked/installing.macports.uninstalling.html&quot;&gt;uninstalled it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.apple.com/tools/xcode/&quot;&gt;Xcode&lt;/a&gt; is a prerequisite for some packages (aka formulae in homebrew), providing &lt;code&gt;gcc&lt;/code&gt; and other important tools.&lt;/p&gt;

&lt;p&gt;To install homebrew (as per the &lt;a href=&quot;http://wiki.github.com/mxcl/homebrew/installation&quot;&gt;instructions&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo chown -R $USER /usr/local
curl -L http://github.com/mxcl/homebrew/tarball/master | tar xz --strip 1 -C /usr/local
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I have installed the following formulae (and their dependencies):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ack
bash-completion
dos2unix
gist
git
imagemagick
ncursesw
node
rename
sl
sqlite
subversion
tree
v8
wakeonlan
wget
xmlstarlet
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;macports&quot;&gt;Macports&lt;/h3&gt;

&lt;p&gt;I’m no longer using macports but I’ve listed it here as homebrew might be too fresh for some people.  &lt;a href=&quot;http://www.macports.org/&quot;&gt;Macports&lt;/a&gt; is a collection of common ports from unix / linux, most of which are very useful for command line use.  &lt;a href=&quot;http://www.finkproject.org/&quot;&gt;Fink&lt;/a&gt; is an alternative that has a larger number of packages but seems to be less frequently updated.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.apple.com/tools/xcode/&quot;&gt;Xcode&lt;/a&gt; is a prerequisite, providing &lt;code&gt;gcc&lt;/code&gt; and other important tools.&lt;/p&gt;

&lt;p&gt;When I was using macports I installed the following ports (and their dependencies):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bzip2
curl
git-core +svn +bash_completion
gzip
meld
ncurses
python_select
python26
py26-markdown
py26-pygments
ruby
rb-rubygems
sqlite3
subversion +bash_completion
unison
wget
xmlstarlet
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Some handy commands:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;sudo port -u install &amp;lt;package&amp;gt;&lt;/code&gt; : install the supplied package, uninstalling the old version&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port uninstall &amp;lt;package&amp;gt;&lt;/code&gt; : uninstall the supplied package&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port selfupdate&lt;/code&gt; : update port itself&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port -u upgrade installed&lt;/code&gt; : upgrade the installed packages&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port clean --all installed&lt;/code&gt; : cleans installation files for all installed packages&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port deactivate &amp;lt;package&amp;gt; @&amp;lt;version&amp;gt;+&amp;lt;variant&amp;gt;&lt;/code&gt; : deactivate a package&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port activate &amp;lt;package&amp;gt; @&amp;lt;version&amp;gt;+&amp;lt;variant&amp;gt;&lt;/code&gt; : activate a package&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;sudo port uninstall inactive&lt;/code&gt; : uninstall inactive packages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need to switch versions, or variants, you need to deactivate the current version and then activate the one you want.&lt;/p&gt;

&lt;h3 id=&quot;bash-init-scripts&quot;&gt;Bash init scripts&lt;/h3&gt;

&lt;h4 id=&quot;bashrc&quot;&gt;.bashrc&lt;/h4&gt;

&lt;p&gt;This tends to be run for bash scripts so should contain path vars and such.  This is a good place to add a &lt;code&gt;bin&lt;/code&gt; directory to the path for housing your custom scripts.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# non-login shells
# echo &quot;calling .bashrc&quot;

# set PATH so it includes user&#39;s private bin if it exists
if [ -d ~/bin ] ; then
  PATH=~/bin:&quot;${PATH}&quot;
  export PATH
fi

# enable bash completion
if [ -f `brew --prefix`/etc/bash_completion ]; then
  . `brew --prefix`/etc/bash_completion
fi

# editor
export EDITOR=nano

# java
export JAVA14_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.4/Home
export JAVA15_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.5/Home
export JAVA16_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home
export JAVA_HOME=$JAVA16_HOME

# maven
export M2_HOME=~/tools/maven/2.2.1
export M2=$M2_HOME/bin
export PATH=$M2:$PATH
export MAVEN_OPTS=&quot;-Xms256m -Xmx512m -XX:MaxPermSize=256m&quot;

# prompt format
PS1=&#39;[\u@\h \W$(__git_ps1 &quot; (%s)&quot;)]\$ &#39;

# bash history niceness
export HISTIGNORE=&quot;&amp;amp;:ls:[bf]g:exit&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;bashprofile&quot;&gt;.bash_profile&lt;/h4&gt;

&lt;p&gt;This is run when logging in or creating a new bash session, so its not used as much.  Its a good idea to call &lt;code&gt;.bashrc&lt;/code&gt; to setup the environment in a DRY fashion.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# login shells
# echo &quot;calling .bash_profile&quot;

if [ -f ~/.bashrc ]; then
  source ~/.bashrc
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;visual-diff&quot;&gt;Visual Diff&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.apple.com/tools/xcode/&quot;&gt;Xcode&lt;/a&gt; contains an application called &lt;code&gt;FileMerge&lt;/code&gt; but its very lightweight.  &lt;a href=&quot;http://sourcegear.com/diffmerge/&quot;&gt;DiffMerge&lt;/a&gt; is a free cross platform visual diff application that is worth trying out.&lt;/p&gt;

&lt;h2 id=&quot;gitx&quot;&gt;GitX&lt;/h2&gt;

&lt;p&gt;A gitk like repository viewer designed for OS X.  &lt;a href=&quot;http://github.com/brotherbard/gitx&quot;&gt;brotherbard’s fork&lt;/a&gt; is worth looking at.&lt;/p&gt;

&lt;h2 id=&quot;java-development&quot;&gt;Java Development&lt;/h2&gt;

&lt;p&gt;The tools I use for java development are covered in a &lt;a href=&quot;/java-development-tools.html&quot;&gt;recent article&lt;/a&gt;, however, there are some specifics that are needed to get older versions of java installed if you don’t happen to be working with the latest versions.&lt;/p&gt;

&lt;h3 id=&quot;jdks&quot;&gt;JDKs&lt;/h3&gt;

&lt;p&gt;OS-X Leopard comes with JDK 1.4, 1.5 and 1.6 pre installed.  The java tools are available on the command line (e.g. java, javac, jconsole, etc).&lt;/p&gt;

&lt;p&gt;Note: Snow Leopard removed JDK 1.4 and 1.5, so there are some steps you can take to reinstall them:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;download the &lt;a href=&quot;http://support.apple.com/downloads/Java_for_Mac_OS_X_10_5_Update_4&quot;&gt;last release&lt;/a&gt; from leopard.&lt;/li&gt;
  &lt;li&gt;use &lt;a href=&quot;http://www.charlessoft.com/&quot;&gt;pacifist&lt;/a&gt; to copy the following to the same location on your machine:
    * &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.4&lt;/code&gt;
    * &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.4.2&lt;/code&gt;
    * &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.5&lt;/code&gt;
    * &lt;code&gt;/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can then verify by accessing the java preferences app in &lt;code&gt;Applications -&amp;gt; Utilities -&amp;gt; Java Preferences&lt;/code&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Command Line Tips</title>
   <link href="http://kris.me.uk/2010/05/03/command-line-tips.html"/>
   <updated>2010-05-03T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/05/03/command-line-tips</id>
   <content type="html">&lt;h2 id=&quot;bash&quot;&gt;Bash&lt;/h2&gt;

&lt;p&gt;There are some nice shortcuts to typing everything all the time.  These are called event designators, word designators and modifiers.  There is plenty of info on these in the bash man pages, but some real world examples follow:&lt;/p&gt;

&lt;p&gt;Download, expand and change directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;wget http://rubyforge.org/frs/download.php/68719/ruby-enterprise-1.8.7-2010.01.tar.gz
tar xvf !$:t
cd !$:r:r
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Repackaging:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cat myfile-1.0.1.tar.gz | gunzip | bzip2 | !#:1:s/gz/bz2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Forgot to sudo, rerun the previous event with sudo using &lt;code&gt;!!&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nano /etc/hosts
sudo !!
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;copying&quot;&gt;Copying&lt;/h2&gt;

&lt;p&gt;Copy files merging and preserving permissions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;tar cf - * | ( cd /target; tar xfp -)
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;find&quot;&gt;Find&lt;/h2&gt;

&lt;p&gt;Find is a very powerful command and can save a lot of time.  Here are a few of my favourite uses:&lt;/p&gt;

&lt;h3 id=&quot;finding-in-files&quot;&gt;Finding in files&lt;/h3&gt;

&lt;p&gt;I have the following script in &lt;code&gt;~/bin/find_all&lt;/code&gt; to find all files excluding some common metadata and generated locations:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
# has support for null separator due to usage of spaces in paths
if [ &quot;-0&quot; = &quot;$1&quot; ]; then
	print=&quot;-print0&quot;
else
	print=&quot;-print&quot;
fi
prune=&quot;( -name target -o -name .svn -o -name .git ) -prune&quot;
match=&quot;-type f&quot;
find . $prune -o $match $print
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can then be used to search through the files using grep, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;find_all | xargs grep TODO
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;search-and-replace&quot;&gt;Search and Replace&lt;/h3&gt;

&lt;p&gt;Find that execs sed on each matched file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;find . -type f -exec sed -i &#39;&#39; &#39;s/FROM/TO/g&#39; {} \;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;xmlstarlet&quot;&gt;xmlstarlet&lt;/h2&gt;

&lt;h3 id=&quot;reformatting-xml-files&quot;&gt;Reformatting xml files&lt;/h3&gt;

&lt;p&gt;Also known as pretty printing, this makes use of &lt;a href=&quot;http://xmlstar.sourceforge.net/&quot;&gt;xmlstarlet&lt;/a&gt; and I have this script in &lt;code&gt;~/bin/xmlpp&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
files=`find . -type d -name target -prune -o -name *.xml -print`
for file in $files
do
   mv $file $file.bak
   xml fo $file.bak &amp;gt; $file
   rm $file.bak
done
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;xml-queries&quot;&gt;XML Queries&lt;/h3&gt;

&lt;p&gt;Query xml for particular elements:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl http://feeds.feedburner.com/railscasts -o rss.xml
xml sel -t -m &quot;/rss/channel/item&quot; -v &quot;title&quot; -n rss.xml &amp;gt; episode-list.txt
xml sel -t -m &quot;/rss/channel/item&quot; -v &quot;enclosure/@url&quot; -n rss.xml &amp;gt; episode-media-urls.txt
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Java Development Tools</title>
   <link href="http://kris.me.uk/2010/05/02/java-development-tools.html"/>
   <updated>2010-05-02T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/05/02/java-development-tools</id>
   <content type="html">&lt;p&gt;This article has now moved to its &lt;a href=&quot;/java-development-tools.html&quot;&gt;own page&lt;/a&gt; and been significantly extended.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mac File System tips</title>
   <link href="http://kris.me.uk/2010/05/01/mac-file-system-tips.html"/>
   <updated>2010-05-01T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/05/01/mac-file-system-tips</id>
   <content type="html">&lt;h2 id=&quot;home-directory-conventions&quot;&gt;Home directory conventions&lt;/h2&gt;

&lt;p&gt;I like to add the following directories to my home directory:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;bin&lt;/code&gt; - contains scripts and is put on path by &lt;code&gt;.bashrc&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;dev&lt;/code&gt; - contains development work, such as project working directories&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;tools&lt;/code&gt; - contains custom tools for a particular user, e.g. eclipse, maven.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the following lines to your &lt;code&gt;.bashrc&lt;/code&gt; or appropriate script to put the bin directory on the system path:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# set PATH so it includes user&#39;s private bin if it exists
if [ -d ~/bin ] ; then
  PATH=~/bin:&quot;${PATH}&quot;
  export PATH
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;multi-user-setup&quot;&gt;Multi-User setup&lt;/h2&gt;

&lt;p&gt;In order to share various files around users on a single machine it is useful to put shared files under &lt;code&gt;/Users/Shared&lt;/code&gt; and then add symbolic links in each user’s home directory to pass through to those locations.  For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ln -s /Users/Shared/documents ~/Documents/shared
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;prevent-dsstore-file-creation-over-network-connections&quot;&gt;Prevent .DS_Store file creation over network connections&lt;/h2&gt;

&lt;p&gt;This is covered by &lt;a href=&quot;http://support.apple.com/kb/HT1629&quot;&gt;Apple knowledge base article&lt;/a&gt; but I’ve given the command here also (just run it in a terminal window):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;defaults write com.apple.desktopservices DSDontWriteNetworkStores true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will keep your windows friends and file system purist happier :)&lt;/p&gt;

&lt;h2 id=&quot;synchronisation-between-machines&quot;&gt;Synchronisation between machines&lt;/h2&gt;

&lt;p&gt;Its good practice to ensure that operating system specific files are not synchronised.  Often these files are localised cache structures or permission related so they could cause more problems if sychronised.&lt;/p&gt;

&lt;p&gt;The following operating system files should not be transferred between machines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;.DS_Store
Thumbs.db
ehthumbs_vista.db
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following app specific files should not be transferred between machines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ZbThumbnail.info
*.onetoc2
Picasa.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;startup-items&quot;&gt;Startup items&lt;/h2&gt;

&lt;p&gt;Startup items for the system can be added to &lt;code&gt;/Library/StartupItems&lt;/code&gt; or configured through the preference pane.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Upgrading to Rails 3 Beta 3</title>
   <link href="http://kris.me.uk/2010/04/15/upgrading-to-rails-3-beta-3.html"/>
   <updated>2010-04-15T00:00:00+01:00</updated>
   <id>http://kris.me.uk/2010/04/15/upgrading-to-rails-3-beta-3</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://weblog.rubyonrails.org/2010/4/13/rails-3-0-third-beta-release&quot;&gt;Rails 3 Beta 3&lt;/a&gt; hit the streets a few days ago and I was able to upgrade with only a few issues to sort out.  This post covers the issues I had and how I overcame them.&lt;/p&gt;

&lt;p&gt;First off I updated my &lt;a href=&quot;http://rvm.beginrescueend.com/&quot;&gt;rvm&lt;/a&gt; to the latest 1.9.2-head:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rvm install 1.9.2-head
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can be a little risky as head is constantly changing so if you have a revision of 1.9.2 that you are happy with then stick with it unless you are getting some strange problems and an update might help.&lt;/p&gt;

&lt;p&gt;Next I installed the latest rails prerelease using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install rails --pre
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And updated my &lt;code&gt;Gemfile&lt;/code&gt; to reference beta 3:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem &#39;rails&#39;, &#39;&amp;gt;=3.0.0.beta3&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When I tried to start up the server I got the following error:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ rails s
/Users/kris/.rvm/gems/ruby-1.9.2-head/gems/rails-3.0.0.beta3/bin/rails:1:in `require&#39;: no such file to load -- rails/cli (LoadError)
	from /Users/kris/.rvm/gems/ruby-1.9.2-head/gems/rails-3.0.0.beta3/bin/rails:1:in `&amp;lt;top (required)&amp;gt;&#39;
	from /Users/kris/.rvm/gems/ruby-1.9.2-head/bin/rails:19:in `load&#39;
	from /Users/kris/.rvm/gems/ruby-1.9.2-head/bin/rails:19:in `&amp;lt;main&amp;gt;&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The error turned out to due to a  &lt;a href=&quot;http://github.com/rails/rails/commit/a64bfc3c8e2a62b39f3cf8497c2a5a82272bd27a&quot;&gt;change&lt;/a&gt; that moved the rails binary file to a different location.  This meant that older versions of the gem were conflicting due to incorrect paths.  A simple &lt;code&gt;gem clean&lt;/code&gt; fixed it and the server was able to start.  Note that &lt;code&gt;gem clean&lt;/code&gt; will remove all old versions of installed gems - you may be able to remove the specific old version of rails to fix the issue.&lt;/p&gt;

&lt;p&gt;The next error was the deprecation warning for the &lt;code&gt;error_messages&lt;/code&gt; helper method.  I strongly &lt;a href=&quot;http://news.ycombinator.com/item?id=1263775&quot;&gt;agree&lt;/a&gt; with the removal of this, but it did worry me at first as I often use it when putting together a quick sample app.  Not to worry as the generators now generate the HTML into the view directly rather than using the helper so I simply generated another resource and copied and pasted the markup around.  You can copy and past the following snippet if it helps, or even put it into a partial and reuse it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;% if @comment.errors.any? %&amp;gt;
  &amp;lt;div id=&quot;error_explanation&quot;&amp;gt;
    &amp;lt;h2&amp;gt;&amp;lt;%= pluralize(@comment.errors.count, &quot;error&quot;) %&amp;gt; prohibited this comment from being saved:&amp;lt;/h2&amp;gt;
    &amp;lt;ul&amp;gt;
    &amp;lt;% @comment.errors.full_messages.each do |msg| %&amp;gt;
      &amp;lt;li&amp;gt;&amp;lt;%= msg %&amp;gt;&amp;lt;/li&amp;gt;
    &amp;lt;% end %&amp;gt;
    &amp;lt;/ul&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;% end %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Perhaps generating the partials would have made the transition a little easier and DRYer.  However, in a real app the likelihood is that you would want to create a more awesome error highlighting look ‘n’ feel and therefore this is a minimalist starting point that is still functional.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Jekyll 0.5.7</title>
   <link href="http://kris.me.uk/2010/03/04/jekyll-0.5.7.html"/>
   <updated>2010-03-04T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/03/04/jekyll-0.5.7</id>
   <content type="html">&lt;p&gt;This site is using &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;jekyll&lt;/a&gt;, a static site generator.  The &lt;a href=&quot;http://wiki.github.com/mojombo/jekyll&quot;&gt;documentation&lt;/a&gt; for &lt;a href=&quot;http://jekyllrb.com/&quot;&gt;jekyll&lt;/a&gt; is very good.  I originally intended this to be my first post on the blog covering what I had to work around, however, I ended up fixing some of the issues and managed to get quite a few commits in and jekyll has moved from 0.5.4 through to 0.5.7 during that time.&lt;/p&gt;

&lt;p&gt;Overall I’m quite happy with jekyll although I think it needs to move forward with a good extensions framework to make it more useful to those not running on github pages.  I guess jekyll does what github needs so in some respects there isn’t any great motivation in moving it forwards officially, hence the large number of forks to customise it to peoples needs.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Google on Mac OS X</title>
   <link href="http://kris.me.uk/2010/02/18/google-on-mac-osx.html"/>
   <updated>2010-02-18T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/02/18/google-on-mac-osx</id>
   <content type="html">&lt;p&gt;There are a number of applications and services that I regard as important and having them readily available is vital for me.  I don’t want to be responsible for administering the data or the applications.  With HTML5 in varying degrees of implementation in a number of browsers, it is becoming more the case that web applications can be desktop applications too.&lt;/p&gt;

&lt;p&gt;There are of course always good candidates for native applications and ideally they should help to faciliate web applications or integrate to the web or the cloud.&lt;/p&gt;

&lt;p&gt;As you would expect, &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt; provides many services and a large majority are web orientated.  This post focuses on &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt; services and applications and how they can be utilised on Mac OS-X.  &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt; have a landing site for &lt;a href=&quot;http://www.google.com/mac/&quot;&gt;mac applications&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/mac/&quot;&gt;mac code&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;browser&quot;&gt;Browser&lt;/h2&gt;

&lt;p&gt;Given that the web is critical to the success of &lt;a href=&quot;http://www.google.com/&quot;&gt;Google&lt;/a&gt; its not surprising that they created a browser too.  &lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Google Chrome&lt;/a&gt; has moved the browser market forward ensuring that focus is put on security, performance and reliability, making the browser more suitable than ever before for applications.  Its adoption of HTML5 and the offline capabilities in the specification has made the case for web applications that can be desktop applications a reality.&lt;/p&gt;

&lt;p&gt;Prior to HTML5, there was &lt;a href=&quot;http://gears.google.com/&quot;&gt;Google gears&lt;/a&gt; which provided extensions to browsers to facilitate offline web applications.  As with HTML5, there is a reliance on the web application to utilise the available resources.&lt;/p&gt;

&lt;p&gt;Now that &lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Google Chrome&lt;/a&gt; supports extensions (plugins) on Mac OS-X I have made it my default browser.&lt;/p&gt;

&lt;h2 id=&quot;web-applications&quot;&gt;Web Applications&lt;/h2&gt;

&lt;p&gt;On a regular basis I use &lt;a href=&quot;http://mail.google.com/mail&quot;&gt;Google Mail&lt;/a&gt;, &lt;a href=&quot;http://www.google.com/reader&quot;&gt;Google Reader&lt;/a&gt; and &lt;a href=&quot;http://www.google.com/calendar&quot;&gt;Google Calendar&lt;/a&gt;.  All of these applications make use of offline capabilites, either through &lt;a href=&quot;http://gears.google.com/&quot;&gt;Google gears&lt;/a&gt; or HTML5.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://mail.google.com/mail&quot;&gt;Google Mail&lt;/a&gt; also has other services embedded in it, such as contacts, chat and tasks.&lt;/p&gt;

&lt;h2 id=&quot;launcher&quot;&gt;Launcher&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.google.com/quicksearchbox/&quot;&gt;Google Quick Search Box&lt;/a&gt; (QSB) is a great search and launcher replacement for spotlight by the guy who wrote &lt;a href=&quot;http://docs.blacktree.com/quicksilver/&quot;&gt;Quicksilver&lt;/a&gt;.  I turned off the spotlight menu keyboard shortcut in the spotlight preferences so I can bind &lt;code&gt;Command + Space&lt;/code&gt; to QSB.&lt;/p&gt;

&lt;h2 id=&quot;notifications&quot;&gt;Notifications&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://toolbar.google.com/gmail-helper/notifier_mac.html&quot;&gt;Google Notifier&lt;/a&gt; sits on the menubar and provides notifications for email and calendar.  It also provides quick options to open emails, compose emails and add calendar entries amongst others.  There are a number of extensions for &lt;a href=&quot;http://www.google.com/chrome&quot;&gt;Google Chrome&lt;/a&gt; that provide similar notifications, however, the browser must be open to see them.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://toolbar.google.com/gmail-helper/notifier_mac.html&quot;&gt;Google Notifier&lt;/a&gt; allows plugins, and &lt;a href=&quot;http://wafflesoftware.net/&quot;&gt;wafflesoftware&lt;/a&gt; have created a plugin called &lt;a href=&quot;http://wafflesoftware.net/googlegrowl/&quot;&gt;Google Growl&lt;/a&gt; to make use of &lt;a href=&quot;http://growl.info/&quot;&gt;Growl&lt;/a&gt;.  Its pretty simple to set up, you just need to change the Google Notifier Preferences to not show popups or play sounds and therefore rely on the configuration in growl.&lt;/p&gt;

&lt;h2 id=&quot;google-earth&quot;&gt;Google Earth&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://earth.google.co.uk/&quot;&gt;Google Earth&lt;/a&gt; is great.  I’m sure there lots of great uses for it but I just love flying around and looking at interesting things.&lt;/p&gt;

&lt;h2 id=&quot;desktop-application-integration&quot;&gt;Desktop Application Integration&lt;/h2&gt;

&lt;h3 id=&quot;mail&quot;&gt;Mail&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://mail.google.com/mail&quot;&gt;Google Mail&lt;/a&gt; supports IMAP (and POP but that is not bidirectional), allowing good integration with pretty much any mail program with IMAP support.  &lt;a href=&quot;http://mail.google.com/support/bin/answer.py?answer=13275&quot;&gt;Using POP with Apple Mail&lt;/a&gt; covers the details for Apple Mail integration.&lt;/p&gt;

&lt;h3 id=&quot;ical&quot;&gt;iCal&lt;/h3&gt;

&lt;p&gt;Google provide a setup program called &lt;a href=&quot;http://code.google.com/p/calaboration/&quot;&gt;calaboration&lt;/a&gt; to initialise the calDAV settings for iCal.  I’m not fond of the way the calDAV integrated calendars are shown in iCal, so I’m looking for alternative solutions.  &lt;/p&gt;

&lt;p&gt;I like the look of &lt;a href=&quot;http://spanningsync.com/&quot;&gt;Spanning Sync&lt;/a&gt; which can sync using the native iCal files as well as contacts, however, it costs money and data is passed through their servers.  The licence is also linked to a single account and I want to be able to sync multiple accounts, although this can be worked around by having a master account and sharing your other calendars with it (e.g. from your work or home accounts).&lt;/p&gt;

&lt;h3 id=&quot;chat&quot;&gt;Chat&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.adiumx.com/&quot;&gt;Adium&lt;/a&gt; is a generic chat client with support for google chat that also integrates with &lt;a href=&quot;http://growl.info/&quot;&gt;Growl&lt;/a&gt;.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Using git for sync and backup to a NAS</title>
   <link href="http://kris.me.uk/2010/02/16/git-backup-workflow.html"/>
   <updated>2010-02-16T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/02/16/git-backup-workflow</id>
   <content type="html">&lt;p&gt;&lt;code&gt;git&lt;/code&gt; can be the ideal choice for some sync and backups tasks where maintaining the history is important.  Even if the history becomes less important over time, you can simply blow the repository away and recreate it from your local working copy without any history, or even use some interesting commands to do this.  Hopefully soon someone will create something that uses gits concepts to do this and allow history rewriting / squashing although this does go against the immutability concepts in git.&lt;/p&gt;

&lt;p&gt;For this example, I have a local photos repository (&lt;code&gt;/Users/kris/Pictures/shared/.git&lt;/code&gt;) that I want to make available on the nas (mounted at &lt;code&gt;/Volumes/share/&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone --bare --no-hardlinks /Users/kris/Pictures/shared/.git /Volumes/share/shared/photos.git
git remote add share /Volumes/share/shared/photos.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This first does a bare clone of the local repo to the nas, then sets the remote for the local repo to the clone on the nas.&lt;/p&gt;

&lt;p&gt;Provided the nas is mounted, the git repository can be used under normal workflows.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Git Tips</title>
   <link href="http://kris.me.uk/2010/02/15/git-tips.html"/>
   <updated>2010-02-15T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/02/15/git-tips</id>
   <content type="html">&lt;p&gt;This is a collection of git tips from various sources and tailored to my needs.  The tips are known to work under git 1.7.3.&lt;/p&gt;

&lt;p&gt;Updates 2010-10-20:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Updated git version known to work against to 1.7.3 as I’ve not tested any new features on old versions&lt;/li&gt;
  &lt;li&gt;Improved some aliases based on &lt;a href=&quot;http://mislav.uniqpath.com/2010/07/git-tips/&quot;&gt;Mislav’s post&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;I no longer use &lt;code&gt;core.autocrlf&lt;/code&gt; setting, so set to false&lt;/li&gt;
  &lt;li&gt;Covered &lt;code&gt;push -u&lt;/code&gt; for setting up remote tracking&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;read-the-community-documentation&quot;&gt;Read the community documentation&lt;/h2&gt;

&lt;p&gt;There is a lot of really good community documentation out there.  The primary &lt;a href=&quot;http://git-scm.com/&quot;&gt;git-scm&lt;/a&gt; site is a good start, as well as &lt;a href=&quot;http://gitready.com/&quot;&gt;git ready&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;useful-global-config&quot;&gt;Useful global config&lt;/h2&gt;

&lt;p&gt;To show who you are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global user.name &quot;Kris Brown&quot;
git config --global user.email kris@kris.me.uk
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To colourise the outputs:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To add some useful aliases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global alias.ci commit
git config --global alias.st &quot;status -sb&quot;
git config --global alias.qlog &quot;log --oneline -n 10 --decorate&quot;
git config --global alias.glog &quot;log --oneline -n 10 --decorate --graph&quot;
git config --global alias.co checkout
git config --global alias.svnup &quot;svn rebase&quot;
git config --global alias.svnci &quot;svn dcommit --rmdir&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Github goodies:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global github.user krisb
git config --global github.token $tokenhash
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Handling CR+LF issues:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global core.autocrlf false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Defaulting to rebase pulls to reduce merge commits:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config branch.master.rebase true
git config --global branch.autosetuprebase always
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;System wide ignores (mac + windows):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global core.excludesfile ~/.gitignore
echo .DS_Store &amp;gt;&amp;gt; ~/.gitignore
echo Thumbs.db &amp;gt;&amp;gt; ~/.gitignore
echo ehthumbs_vista.db &amp;gt;&amp;gt; ~/.gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In git version 1.6.3, pushing no longer defaults to anything (it did default to &lt;code&gt;matching&lt;/code&gt; previously).  To set the default to &lt;code&gt;current&lt;/code&gt; (i.e. just the current branch), modify the config:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config --global push.default current
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;project-setup&quot;&gt;Project setup&lt;/h2&gt;

&lt;h3 id=&quot;cloning-an-existing-repository&quot;&gt;Cloning an existing repository&lt;/h3&gt;

&lt;p&gt;Cloning an existing repository tracks that remote repository by default:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git://github.com/$username/$project.git
cd $project
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;creating-a-new-project&quot;&gt;Creating a new project&lt;/h3&gt;

&lt;p&gt;Creating a new project, touching the readme and then performing the initial commit:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir $project
cd $project
git init
touch README
git add README
git commit -m &quot;first commit&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;modifying-code-and-committing&quot;&gt;Modifying code and committing&lt;/h2&gt;

&lt;p&gt;In git, changes can be in one of 3 locations:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;working tree&lt;/em&gt; which contains your local modifications on the file system&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;index&lt;/em&gt; or &lt;em&gt;staging area&lt;/em&gt; which contains your local modifications on the file system and indexes changes that are staged ready for committing&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;repository&lt;/em&gt; which contains your committed modifications.  This can be local or remote.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic work flow is to check your status, diff your changes and review them, add to the index and then commit to the repository.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;modify some files&amp;gt;
git status
git diff
git add -A
git commit -m &quot;a suitably good description of the change&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are many variations on the above, commands in git are very powerful and can be used in a variety of ways.  &lt;code&gt;git add -A&lt;/code&gt; will ensure that any deletions or new files are also indexed.&lt;/p&gt;

&lt;p&gt;Once commits are in repositories can then be fetched, pushed, pulled, merged, rebased and many other things.  Technically there is another location, the &lt;em&gt;stash&lt;/em&gt;, think of this as a modifiable local branch.&lt;/p&gt;

&lt;h3 id=&quot;adding-a-remote&quot;&gt;Adding a remote&lt;/h3&gt;

&lt;p&gt;If you created a new project, or you want to add another remote to an existing project:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote add origin git@github.com:$username/$project.git
git push -u origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;-u&lt;/code&gt; option is optional and sets up tracking if present.&lt;/p&gt;

&lt;h3 id=&quot;tracking-a-remote&quot;&gt;Tracking a remote&lt;/h3&gt;

&lt;p&gt;If you did not branch/clone from a repository initially or use the &lt;code&gt;push -u&lt;/code&gt; option then you can add the tracking manually.
This is also applicable if you wish to change the remote being tracked.  For example, to track origin from master:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config branch.master.remote origin
git config branch.master.merge refs/heads/master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This then allows you to pull and push without specifying the local and remote branches:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git pull
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;git status&lt;/code&gt; also plays nicely with tracked remotes, showing if you are ahead or behind and by how many commits.&lt;/p&gt;

&lt;h2 id=&quot;patching&quot;&gt;Patching&lt;/h2&gt;

&lt;p&gt;The following examples assume that the &lt;code&gt;master&lt;/code&gt; is the main development branch and &lt;code&gt;feature_branch&lt;/code&gt; is the feature branch.&lt;/p&gt;

&lt;h3 id=&quot;preparation&quot;&gt;Preparation&lt;/h3&gt;

&lt;p&gt;To create clean patches, the modifications should be made on a branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout master
git branch feature_branch
git checkout feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The last 2 commands could be done in a single command using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout -b feature_branch
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;updating&quot;&gt;Updating&lt;/h3&gt;

&lt;p&gt;Before submitting a patch it is good practice to pull in the latest changes and rebase the branch to ensure the patch will work against the latest version:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git checkout master
git pull
git checkout feature_branch
git rebase master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The 1st and 2nd commands ensure that master is up to date, the 3rd and 4th commands rebase the feature branch to master.  If the feature branch has been remoted already then you’ll have to merge instead, i.e. &lt;code&gt;git merge master&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;email-style-patches&quot;&gt;Email style patches&lt;/h3&gt;

&lt;p&gt;This method is the recommended way of doing patches in git.  The author is still credited with the changes and it is easy to commit.  Run the following from the feature branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git format-patch master --stdout &amp;gt; patch.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The committer can then apply the patch using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git am &amp;lt; patch.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The commiter may choose to use &lt;code&gt;git apply&lt;/code&gt; if they wish to make alterations.&lt;/p&gt;

&lt;h3 id=&quot;traditional-style-patches&quot;&gt;Traditional style patches&lt;/h3&gt;

&lt;p&gt;Git also allows the traditional way of patching using a diff but this does not preserve the commit history of the author.  Run the following from the feature branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git diff &amp;gt; patch.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The committer can then apply the patch using:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;patch -p1 &amp;lt; patch.diff
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;-p1&lt;/code&gt; is needed rather than the usual &lt;code&gt;-p0&lt;/code&gt; due to the extra &lt;code&gt;a/&lt;/code&gt; and &lt;code&gt;b/&lt;/code&gt; prefixes in the git diff output.  Alternatively, git diff can be supplied the &lt;code&gt;--no-prefix&lt;/code&gt; option and patch supplied the &lt;code&gt;-p0&lt;/code&gt; option.&lt;/p&gt;

&lt;h2 id=&quot;tidying-up&quot;&gt;Tidying up&lt;/h2&gt;

&lt;h3 id=&quot;checking-if-a-branch-contains-commits-or-other-branches&quot;&gt;Checking if a branch contains commits or other branches&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;git branch --contains branch-to-delete
git branch --merged
git branch --no-merged
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;deleting-a-remote-branch&quot;&gt;Deleting a remote branch&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;git push origin :branch
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;finding-duplicates&quot;&gt;Finding duplicates&lt;/h3&gt;

&lt;p&gt;This is a really handy little script I use a lot of my photo archive to find and remove duplicates.  Its based on the script from &lt;a href=&quot;http://stackoverflow.com/questions/224687/git-find-duplicate-blobs-files-in-this-tree&quot;&gt;StackOverflow&lt;/a&gt; but I had to modify the regex to allow any characters in the filename as I have spaces in there.  I create two scripts, one called &lt;code&gt;gitdup&lt;/code&gt; that handles the usage comment in the second script, called &lt;code&gt;gitdup_collate&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/perl
# usage: git ls-tree -r HEAD | gitdup_collate

use strict;
use warnings;

my $sha1_path = {};

while (my $line = &amp;lt;STDIN&amp;gt;) {
    chomp $line;
    if ($line =~ m{ \A \d+ \s+ \w+ \s+ (\w+) \s+ (.+)}xms) {
        my $sha1 = $1;
        my $path = $2;
        push @{$sha1_path-&amp;gt;{$sha1}}, $path;
    }
}

foreach my $sha1 (keys %$sha1_path) {
    if (scalar @{$sha1_path-&amp;gt;{$sha1}} &amp;gt; 1) {
        foreach my $path (@{$sha1_path-&amp;gt;{$sha1}}) {
            print &quot;$sha1  $path\n&quot;;
        }
        print &#39;-&#39; x 40, &quot;\n&quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Enabling sshd for Buffalo Linkstation Live (LS-CHL)</title>
   <link href="http://kris.me.uk/2010/01/03/enabling-sshd-for-buffalo-linkstation-live.html"/>
   <updated>2010-01-03T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/01/03/enabling-sshd-for-buffalo-linkstation-live</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;THIS GUIDE IS FOR THE LS-CHL MODEL ONLY.  ANY MODIFICATIONS ARE MADE AT YOUR OWN RISK.  A MISTAKE CAN BRICK YOUR NAS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://buffalo.nas-central.org/&quot;&gt;Buffalo @ nas-central.org&lt;/a&gt; is a good site for information on customising your linkstation live.&lt;/p&gt;

&lt;p&gt;If unfamiliar with &lt;code&gt;vi&lt;/code&gt; then find a &lt;a href=&quot;http://www.astrohandbook.com/ch20/vi_guide.html&quot;&gt;Quick Guide&lt;/a&gt; to help you get by as &lt;code&gt;vi&lt;/code&gt; is the main editor available to you.&lt;/p&gt;

&lt;p&gt;Also, note that most of the commands are using &lt;a href=&quot;http://www.busybox.net/&quot;&gt;BusyBox&lt;/a&gt; so may have limited functionality.&lt;/p&gt;

&lt;p&gt;This guide is largely taken from &lt;a href=&quot;http://buffalo.nas-central.org/index.php/Open_Stock_Firmware&quot;&gt;Open Stock Firmware Guide&lt;/a&gt; with my commentary on how I overcame any problems.  &lt;code&gt;sshd&lt;/code&gt; is already available on the linkstation, it just needs switching on.  &lt;code&gt;ACP_Commander&lt;/code&gt; is the key to opening the initial access allowing you to make the necessary modifications.  &lt;/p&gt;

&lt;h3 id=&quot;prerequesites&quot;&gt;Prerequesites&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Java installed&lt;/li&gt;
  &lt;li&gt;Download &lt;a href=&quot;http://downloads.nas-central.org/TOOLS/ALL_LS_KB_ARM9/ACP_COMMANDER/acp_commander.jar&quot;&gt;ACP_Commander&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Ensure you have read the &lt;a href=&quot;http://downloads.buffalo.nas-central.org/TOOLS/ALL_LS_KB_ARM9/ACP_COMMANDER/README&quot;&gt;ACP_Commander readme&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;steps&quot;&gt;Steps&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Connect using &lt;code&gt;acp_commander&lt;/code&gt; to reset the root password and open telnet:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;$ java -jar acp_commander.jar -t 192.168.xxx.xxx -o
there seems to be no existing prefs, write default values
ACP_commander out of the nas-central.org (linkstationwiki.net) project.
Used to send ACP-commands to Buffalo linkstation(R) LS-PRO.

WARNING: This is experimental software that might brick your linkstation!


Using random connID value = BE442C00xxxx
Using target:	192.168.xxx.xxx/192.168.xxx.xxx
Starting authentication procedure...
Sending Discover packet...	
Found:	NAS (/192.168.xxx.xxx) 	LS-CHL(HANZEI) (ID=00016) 	mac: 00:1D:73:A3:xx:xx	Firmware=  1.20	Key=xxxxxxx
Trying to authenticate EnOneCmd...	ACP_STATE_OK
start telnetd...	OK (ACP_STATE_OK)
Reset root pwd...	Password changed.


You can now telnet to your box as user &#39;root&#39; providing no / an empty password.
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Now telnet to your box with username ‘root’ and no password:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;$ telnet 192.168.xxx.xxx
Trying 192.168.xxx.xxx...
Connected to 192.168.xxx.xxx.
Escape character is &#39;^]&#39;.

NAS login: root
No mail.
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Change the password to protect the box:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;# passwd
Changing password for root
Enter the new password (minimum of 5, maximum of 127 characters)
Please use a combination of upper and lower case letters and numbers.
New password: 
Re-enter new password: 
Password changed.
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ensure there is a script to control &lt;code&gt;sshd&lt;/code&gt; and that it has the correct permissions.  My linkstation already had a script at &lt;code&gt;/etc/init.d/sshd.sh&lt;/code&gt;.  If not, find a suitable script from &lt;a href=&quot;http://buffalo.nas-central.org/index.php/Open_Stock_Firmware&quot;&gt;Open Stock Firmware Guide&lt;/a&gt;.  To ensure the correct permissions:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;# chmod 0755 /etc/init.d/sshd.sh
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Ensure suitable configuration for &lt;code&gt;sshd&lt;/code&gt; in &lt;code&gt;/etc/sshd_config&lt;/code&gt;.  I had to change &lt;code&gt;UsePrivilegeSeparation&lt;/code&gt; from the default of &lt;code&gt;yes&lt;/code&gt; to &lt;code&gt;no&lt;/code&gt; as I was getting an error for users other than root &lt;code&gt;ssh&lt;/code&gt;ing to the box.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Backup the start up script and modify, adding &lt;code&gt;telnetd&lt;/code&gt; between step 2 and 3 and &lt;code&gt;sshd&lt;/code&gt; to step 3:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;# cp /etc/init.d/rcS /etc/init.d/rcS.bak
# vi /etc/init.d/rcS
&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;Before (snippet starts on line 81):&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;echo &quot;** step2 **&quot;                                                                                     
for cmd in EnablingAutoip.sh usb.sh hotplug.sh networking.sh syslog.sh network_control.sh inetd.sh errormon.sh kernelmon.sh miconmon.sh checkSysMd.sh start_data_array.sh
do                                                                                                                                                                       
        exec_sh ${cmd}                                                                                                                                                   
done                                                                                                                                                                                                                                                                                                                          

echo &quot;** step3 **&quot;                                                                                                                                                       
for cmd in diskmon.sh drivecheck.sh ftpd.sh atalk.sh httpd.sh smb.sh clientUtil_servd.sh bonjour.sh lsprcvd.sh daemonwatch.sh cron.sh checkconfig.sh ups.sh pwrmgr.sh
do                                                                                                                                                                           
        exec_sh ${cmd}                                                                                                                                                       
done                                                                                                                                                                         
&lt;/code&gt;&lt;/pre&gt;

    &lt;p&gt;After:&lt;/p&gt;

    &lt;pre&gt;&lt;code&gt;echo &quot;** step2 **&quot;                                                                                     
for cmd in EnablingAutoip.sh usb.sh hotplug.sh networking.sh syslog.sh network_control.sh inetd.sh errormon.sh kernelmon.sh miconmon.sh checkSysMd.sh start_data_array.sh
do                                                                                                                                                                       
        exec_sh ${cmd}                                                                                                                                                   
done                                                                                                                                                                     

# telnetd for debug                                                                                                                                                      
/usr/sbin/telnetd                                                                                                                                                        

echo &quot;** step3 **&quot;                                                                                                                                                       
for cmd in diskmon.sh drivecheck.sh ftpd.sh atalk.sh httpd.sh smb.sh clientUtil_servd.sh bonjour.sh lsprcvd.sh daemonwatch.sh cron.sh checkconfig.sh ups.sh pwrmgr.sh sshd.sh
do                                                                                                                                                                           
        exec_sh ${cmd}                                                                                                                                                       
done
&lt;/code&gt;&lt;/pre&gt;
  &lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 <entry>
   <title>Rack Application Hosting on Ubuntu Jaunty</title>
   <link href="http://kris.me.uk/2010/01/02/rack-app-hosting.html"/>
   <updated>2010-01-02T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/01/02/rack-app-hosting</id>
   <content type="html">&lt;p&gt;Thanks to &lt;a href=&quot;http://www.phusion.nl/&quot;&gt;Phusion&lt;/a&gt;, setting up a server to run rack and rails applications is very simple.&lt;/p&gt;

&lt;h2 id=&quot;ruby&quot;&gt;Ruby&lt;/h2&gt;

&lt;p&gt;Ruby is an obvious requirement and I’ve covered doing this with standard ruby packages for Ubuntu and &lt;a href=&quot;http://www.rubyenterpriseedition.com/&quot;&gt;Ruby Enterprise Edition&lt;/a&gt;, the later of which is recommended for a &lt;a href=&quot;http://www.modrails.com/&quot;&gt;Passenger&lt;/a&gt; based rack application server.  You can also use &lt;a href=&quot;http://rvm.beginrescueend.com/&quot;&gt;rvm&lt;/a&gt; for user accounts.&lt;/p&gt;

&lt;h3 id=&quot;standard-ruby&quot;&gt;Standard Ruby&lt;/h3&gt;

&lt;p&gt;Ubuntu comes with an old fixed version of ruby gems so you need to do the following to get the standard ruby tools installed via packages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install ruby irb ri rdoc libruby-extras rubygems ruby1.8-dev
sudo gem install rake
sudo gem install rubygems-update
cd /var/lib/gems/1.8/bin
sudo ./update_rubygems
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will give you the usual ruby commands executed from &lt;code&gt;/usr/bin&lt;/code&gt;.  You can install and switch between &lt;a href=&quot;http://blog.michaelgreenly.com/2009/04/multiple-versions-of-ruby-on-ubuntu-3.html&quot;&gt;multiple versions of ruby&lt;/a&gt; if you so wish.&lt;/p&gt;

&lt;h3 id=&quot;ruby-enterprise-edition&quot;&gt;Ruby Enterprise Edition&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.rubyenterpriseedition.com/&quot;&gt;Ruby Enterprise Edition&lt;/a&gt; is a specific build of ruby by &lt;a href=&quot;http://www.phusion.nl/&quot;&gt;Phusion&lt;/a&gt; purposefully designed to perform well in a server environment.  This is optional so if you want to run on standard ruby simply skip this section.&lt;/p&gt;

&lt;p&gt;I ran the following commands and followed the information given as detailed on the &lt;a href=&quot;http://www.rubyenterpriseedition.com/download.html&quot;&gt;installation page&lt;/a&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /opt
wget http://rubyforge.org/frs/download.php/68719/ruby-enterprise-1.8.7-2010.01.tar.gz
tar xzvf ruby-enterprise-1.8.7-2010.01.tar.gz
sudo ./ruby-enterprise-1.8.7-2010.01/installer
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Accept the defaults and at the end, the following note is given regarding using with passenger:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Ruby Enterprise Edition is successfully installed!
If want to use Phusion Passenger (http://www.modrails.com) in combination
with Ruby Enterprise Edition, then you must reinstall Phusion Passenger against
Ruby Enterprise Edition, as follows:

  /opt/ruby-enterprise-1.8.7-2010.01/bin/passenger-install-apache2-module

Make sure you don&#39;t forget to paste the Apache configuration directives that
the installer gives you.

If you ever want to uninstall Ruby Enterprise Edition, simply remove this
directory:

  /opt/ruby-enterprise-1.8.7-2010.01

If you have any questions, feel free to visit our website:

  http://www.rubyenterpriseedition.com

Enjoy Ruby Enterprise Edition, a product of Phusion (www.phusion.nl) :-)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I like to symlink the version I want to use, so run the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ln -s ruby-enterprise-1.8.7-2010.01 ruby-enterprise
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To avoid any path issues, I make the modifications outlined in section 3.3 of the  &lt;a href=&quot;http://www.rubyenterpriseedition.com/documentation.html&quot;&gt;documentation&lt;/a&gt; by modifying the path in &lt;code&gt;/etc/environment&lt;/code&gt;, i.e.:&lt;/p&gt;

&lt;p&gt;PATH=”/opt/ruby-enterprise/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games”&lt;/p&gt;

&lt;h2 id=&quot;passenger&quot;&gt;Passenger&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.modrails.com/&quot;&gt;Passenger&lt;/a&gt; is very easy to install.  There are two sets of instructions depending on whether you want to use the standard ruby installation or ruby enterprise edition.&lt;/p&gt;

&lt;h3 id=&quot;using-standard-ruby&quot;&gt;Using standard ruby&lt;/h3&gt;

&lt;p&gt;Install the gem and run the installation script.  It will tell you what dependencies you are missing and how to install them.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install passenger
cd /var/lib/gems/1.8/bin
sudo ./passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To enable passenger, create &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and &lt;code&gt;/etc/apache2/mods-available/passenger.conf&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PassengerRoot /var/lib/gems/1.8/gems/passenger-2.2.9
PassengerRuby /usr/bin/ruby1.8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then enable the module and restart apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod passenger
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The virtual host should point the document root to the public directory of the rails app.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName www.yourhost.com
    DocumentRoot /somewhere/public    # &amp;lt;-- be sure to point to &#39;public&#39;!
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;using-ruby-enterprise-edition&quot;&gt;Using ruby enterprise edition&lt;/h3&gt;

&lt;p&gt;Install the gem and run the installation script.  It will tell you what dependencies you are missing and how to install them.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install passenger
sudo /opt/ruby-enterprise/bin/passenger-install-apache2-module
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To enable passenger, create &lt;code&gt;/etc/apache2/mods-available/passenger.load&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LoadModule passenger_module /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/passenger-2.2.9/ext/apache2/mod_passenger.so
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and &lt;code&gt;/etc/apache2/mods-available/passenger.conf&lt;/code&gt; with the following contents:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PassengerRoot /opt/ruby-enterprise/lib/ruby/gems/1.8/gems/passenger-2.2.9
PassengerRuby /opt/ruby-enterprise/bin/ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;then enable the module and restart apache:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod passenger
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The virtual host should point the document root to the public directory of the rails app.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
   ServerName www.yourhost.com
   DocumentRoot /somewhere/public    # &amp;lt;-- be sure to point to &#39;public&#39;!
   &amp;lt;Directory /somewhere/public&amp;gt;
      AllowOverride all              # &amp;lt;-- relax Apache security settings
      Options -MultiViews            # &amp;lt;-- MultiViews must be turned off
   &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Wordpress Installation on Ubuntu Jaunty</title>
   <link href="http://kris.me.uk/2010/01/01/wordpress-installation.html"/>
   <updated>2010-01-01T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2010/01/01/wordpress-installation</id>
   <content type="html">&lt;p&gt;A &lt;a href=&quot;https://help.ubuntu.com/community/WordPress&quot;&gt;community article&lt;/a&gt; covers installation via an official package, however, I found this to be problematic with modifications and upgrades.  I’ve included instructions for both package installation and manual installation.&lt;/p&gt;

&lt;p&gt;I’ve made the following assumptions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;you want to be able to run multiple sites (or at least have the possibility of)&lt;/li&gt;
  &lt;li&gt;site document roots exist at &lt;code&gt;/var/www/&amp;lt;sitename&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h2&gt;

&lt;p&gt;Ensure any major dependencies are installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install apache2 php5-gd mysql-server
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;apache2-virtual-hosts&quot;&gt;Apache2 Virtual Hosts&lt;/h2&gt;

&lt;p&gt;Create a suitable virtual host entry for the site, e.g. &lt;code&gt;/etc/apache2/sites-available/example.com&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerAdmin admin@example.com
    ServerName example:80
    DocumentRoot /var/www/example.com

    &amp;lt;Directory /var/www/example.com&amp;gt;
        Options FollowSymLinks
        AllowOverride Limit Options FileInfo
        DirectoryIndex index.php
    &amp;lt;/Directory&amp;gt;

    # Possible values include: debug, info, notice, warn, error, crit,
    # alert, emerg.
    LogLevel warn
    ErrorLog /var/log/apache2/example.com-error.log
    CustomLog /var/log/apache2/example.com-access.log combined
&amp;lt;/VirtualHost&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Enable the site and restart apache2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2ensite example.com
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;h3 id=&quot;by-package&quot;&gt;By Package&lt;/h3&gt;

&lt;p&gt;Install using apt-get:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install wordpress
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The application is installed to &lt;code&gt;/usr/share/wordpress&lt;/code&gt;, so if you wish to use a sub url (i.e. &lt;code&gt;http://example.com/wordpress&lt;/code&gt;) then simply symbolic link to this, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ln -s /usr/share/wordpress /var/www/example.com/wordpress
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or if you want to run as the root url (i.e. &lt;code&gt;http://example.com/&lt;/code&gt;) then use the install location directly in the DocumentRoot and Directory directives in the httpd config.&lt;/p&gt;

&lt;p&gt;You need to have a config file for the domain name wordpress is being accessed by, and make symbolic links for any aliases too, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo cp /usr/share/wordpress/wp-config-sample.php config-example.com.php
sudo ln -s config-example.com.php config-blog.example.com.php
sudo ln -s config-example.com.php config-www.example.com.php
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;manually&quot;&gt;Manually&lt;/h3&gt;

&lt;p&gt;Install using the following commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /var/www/example.com
sudo wget http://wordpress.org/latest.tar.gz
sudo tar xvf latest.tar.gz
sudo rm latest.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create an instance of wordpress at &lt;code&gt;/var/www/example.com/wordpress&lt;/code&gt; which will be serviceable at &lt;code&gt;http://example.com/wordpress&lt;/code&gt;.  To service as the root url, run the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mv wordpress/* .
sudo rmdir wordpress
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a default configuration from the sample config:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo cp wp-config-sample.php wp-config.php
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a .htaccess file for any url mappings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo touch .htaccess
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ensure the correct permissions are given:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo chown -R www-data:www-data .
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;mysql-setup&quot;&gt;MySQL setup&lt;/h2&gt;

&lt;p&gt;Create a suitable database, user and permissions.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CREATE DATABASE IF NOT EXISTS `wordpress`;
CREATE USER &#39;wordpressuser&#39;@&#39;localhost&#39; IDENTIFIED BY &#39;wordpresspassword&#39;;
GRANT USAGE ON *.* TO &#39;wordpressuser&#39;@&#39;localhost&#39; IDENTIFIED BY &#39;wordpresspassword&#39;;
GRANT ALL PRIVILEGES ON `wordpress`.* TO &#39;wordpressuser&#39;@&#39;localhost&#39;;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use a suitable database name, username and password - not the above!&lt;/p&gt;

&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;/h2&gt;

&lt;h3 id=&quot;database-credentials&quot;&gt;Database credentials&lt;/h3&gt;

&lt;p&gt;Modify the configuration file to supply the credentials for the database.&lt;/p&gt;

&lt;h3 id=&quot;securing-logins-and-admin-site&quot;&gt;Securing logins and admin site&lt;/h3&gt;

&lt;p&gt;As described in the &lt;a href=&quot;http://codex.wordpress.org/Administration_Over_SSL&quot;&gt;Administration Over SSL&lt;/a&gt; in the Wordpress Codex, modify the configuration file by adding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/** Enable SSL */
define(&#39;FORCE_SSL_ADMIN&#39;, true);
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Git Repository Server using Gitosis</title>
   <link href="http://kris.me.uk/2009/12/31/git-repository-server.html"/>
   <updated>2009-12-31T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2009/12/31/git-repository-server</id>
   <content type="html">&lt;p&gt;This post assumes that you have a server following the &lt;a href=&quot;/2009/12/30/ubuntu-base-server-build.html&quot;&gt;Ubuntu Jaunty Base Server Build&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;git-packages&quot;&gt;Git Packages&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;git-core&lt;/code&gt; package contains all the basic command line for git.  As the server is running headless, there is no point in installing packages such as &lt;code&gt;gitk&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install git-core
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;gitosis&quot;&gt;Gitosis&lt;/h2&gt;

&lt;p&gt;Gitosis is a useful tool for managing git repositories using ssh.  Gitosis can be obtained using git:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir ~/src
cd ~/src
git clone git://eagain.net/gitosis.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;README.rst&lt;/code&gt; contains instructions for setting up and managing gitosis.  &lt;/p&gt;

&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;/h3&gt;

&lt;p&gt;The following outlines the steps I took.&lt;/p&gt;

&lt;p&gt;Ensure you have &lt;code&gt;python-setuptools&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install python-setuptools
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Install gitosis:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd gitosis
sudo python setup.py install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the git user that gitosis will run as (i.e. &lt;code&gt;git&lt;/code&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo adduser \
    --system \
    --shell /bin/bash \
    --gecos &#39;git version control&#39; \
    --group \
    --disabled-password \
    --home /home/git \
    git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Initialise gitosis with your ssh key so you can administer the configuration (assuming you have already setup ssh via certification):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo -H -u git gitosis-init &amp;lt; /home/username/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also make sure the &lt;code&gt;post-update&lt;/code&gt; hook script is executable:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo chmod 755 /home/git/repositories/gitosis-admin.git/hooks/post-update
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;administration&quot;&gt;Administration&lt;/h3&gt;

&lt;p&gt;You can administer the configuration through git itself on the &lt;code&gt;gitosis-admin&lt;/code&gt; repository by cloning, modifying and push changes back to the server.&lt;/p&gt;

&lt;p&gt;Clone the &lt;code&gt;gitosis-admin&lt;/code&gt; repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git clone git@hostname:gitosis-admin.git
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Modify &lt;code&gt;gitosis.conf&lt;/code&gt; adding a group for the new repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[group groupname]
writable = reponame
members = username
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that you can reuse a group for other repositories should you want to.  Generally I use the same &lt;code&gt;groupname&lt;/code&gt; as the &lt;code&gt;reponame&lt;/code&gt;.  members and writable are comma separated lists.&lt;/p&gt;

&lt;p&gt;Add, commit and push your changes to the repository:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git add -A
git ci -m &quot;added reponame&quot;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can now add create the project (or skip this for an existing project):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir myproject
cd mypyroject
git init
# do some work, git add and commit files
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then add your server as a remote and push:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git remote add serveralias git@hostname:reponame.git
git push serveralias master
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can track the remote by adding suitable config:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git config branch.master.remote serveralias
git config branch.master.merge refs/heads/master
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;related-reading&quot;&gt;Related Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://git-scm.com/&quot;&gt;Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://book.git-scm.com/&quot;&gt;Git Community Book&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://eagain.net/gitweb/?p=gitosis.git;a=blob;f=README.rst&quot;&gt;Gitosis Readme&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://scie.nti.st/2007/11/14/hosting-git-repositories-the-easy-and-secure-way&quot;&gt;Another guide to setting up gitosis&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content>
 </entry>
 
 <entry>
   <title>Ubuntu Jaunty Base Server Build</title>
   <link href="http://kris.me.uk/2009/12/30/ubuntu-base-server-build.html"/>
   <updated>2009-12-30T00:00:00+00:00</updated>
   <id>http://kris.me.uk/2009/12/30/ubuntu-base-server-build</id>
   <content type="html">&lt;p&gt;This is a guide to the basic setup of a VPS on Ubuntu Server 9.04 (Jaunty).  The aim is to provide a basic build that is secure for living out on the internet, has a basic web server stack (i.e. LAMP: Apache HTTP Server, MySql, PHP) and any other useful utilities.  Future posts will rely on this build when covering additional application installations.&lt;/p&gt;

&lt;p&gt;The VPS provider I chose was &lt;a href=&quot;http://www.cheapvps.co.uk&quot;&gt;CheapVPS&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;base-install&quot;&gt;Base install&lt;/h2&gt;

&lt;p&gt;The initial image I was given was Ubuntu Server 9.04 with root being the only interactive user (i.e. able to log on).  ssh was available using passwords.  Apache2 and PHP packages were installed in addition to the essentials.  The following commands can be run to provide information about the installation, which may be of use when asking for help on forums:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nuser -a
lsb_release -a
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;getting-up-to-date&quot;&gt;Getting up-to-date&lt;/h2&gt;

&lt;p&gt;Ubuntu uses &lt;code&gt;apt&lt;/code&gt; as its default package manager. Run the following commands to upgrade the installed packages to the latest version.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;apt-get update
apt-get upgrade
apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more information visit the &lt;a href=&quot;https://help.ubuntu.com/community/AptGet/Howto&quot;&gt;Ubuntu Community Documentation AptGet HowTo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt&lt;/code&gt; has the concept of manually installed packages.  A manually installed package is one which is passed to the &lt;code&gt;apt-get install&lt;/code&gt; command.  These packages are assumed to be required and will not be marked as unused dependency for commands such as &lt;code&gt;apt-get autoremove&lt;/code&gt;.  It would be nice if there were a command to see the list of manually installed packages (excluding the essential packages), however, as &lt;a href=&quot;http://ubuntuforums.org/showthread.php?t=947865&quot;&gt;this discussion explains&lt;/a&gt;, there isn’t one that works as expected.&lt;/p&gt;

&lt;h2 id=&quot;keeping-an-eye-on-utilisation&quot;&gt;Keeping an eye on utilisation&lt;/h2&gt;

&lt;p&gt;Disk space can be checked using &lt;code&gt;df&lt;/code&gt;.  Memory usage can be checked using &lt;code&gt;free&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;additional-util-packages&quot;&gt;Additional util packages&lt;/h2&gt;

&lt;p&gt;The following packages are also useful to have installed, so run the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;apt-get install nano
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;configure-hostname&quot;&gt;Configure hostname&lt;/h2&gt;

&lt;p&gt;The hostname is set using the &lt;code&gt;hostname&lt;/code&gt; command and updating entries in &lt;code&gt;/etc/hosts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To set the hostname:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;hostname servername.domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Update &lt;code&gt;/etc/hosts&lt;/code&gt; with DNS entries and aliases like the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;127.0.0.1 localhost.localdomain localhost
127.0.1.1 servername.domainname alias.domainname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following commands should respond suitably:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;uname -n
hostname -a
hostname -s
hostname -d
hostname -f
hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I also had to create the &lt;code&gt;/etc/hostname&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo servername.domainname &amp;gt; /etc/hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;correcting-the-server-time&quot;&gt;Correcting the server time&lt;/h2&gt;

&lt;p&gt;Depending on the image used, the server may be in the wrong timezone.  Run the following commands to reconfigure and utilise NTP to sync the clock:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dpkg-reconfigure tzdata
apt-get install ntpdate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that it may require a change by the VPS provider to fix the host machines clock if the time is still incorrect but the server is in the correct timezone.&lt;/p&gt;

&lt;p&gt;For more information visit the &lt;a href=&quot;https://help.ubuntu.com/community/UbuntuTime&quot;&gt;Ubuntu Community Time&lt;/a&gt; documentation.&lt;/p&gt;

&lt;h2 id=&quot;sudoers&quot;&gt;Sudoers&lt;/h2&gt;

&lt;p&gt;Sudoers controls who can run what commands as which users on which machines.  The standard Ubuntu installation does not expose the root user, instead you create an admin user during the installation and can execute commands.  The VPS image did not conform to this and had root access available with no additional users.  Therefore, it is good practice to create an administrator with the appropriate permissions and use &lt;code&gt;sudo&lt;/code&gt; as required.&lt;/p&gt;

&lt;p&gt;Run the following command to add a user:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;adduser &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add the user to additional groups as required, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;usermod -a -G sudo,adm,www-data &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Modify &lt;code&gt;/etc/sudoers&lt;/code&gt; to allow a given user root privileges using &lt;code&gt;visudo&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;visudo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Adding the following entry:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;username&amp;gt; ALL=(ALL) ALL
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For more information visit the &lt;a href=&quot;https://help.ubuntu.com/community/Sudoers&quot;&gt;Ubuntu Community Documentation Sudoers Guide&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;email-forwarding&quot;&gt;Email forwarding&lt;/h2&gt;

&lt;p&gt;Email is used as a primary notification mechanism for linux, however, by default, email is stored on the server.  If you do not intend to set the server up as an email server (e.g. POP3 or IMAP), it is useful to forward email to an appropriate external email address.  There are two main approaches to this (with sendmail which is the default MTA):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;root maintains email addresses in &lt;code&gt;/etc/aliases&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;each user maintains their email address in &lt;code&gt;~/.forward&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is possible to also combined the two approaches, by aliasing root to a given user and then the user being able to allocate the email address as they see fit.&lt;/p&gt;

&lt;p&gt;This is covered in the man pages for aliases:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;man aliases
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;modifying-aliases&quot;&gt;Modifying aliases&lt;/h3&gt;

&lt;p&gt;e.g. alias root to another user, edit &lt;code&gt;/etc/aliases&lt;/code&gt;, adding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root:           &amp;lt;otheruser&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;e.g. alias root to external email addresses (comma separated), edit &lt;code&gt;/etc/aliases&lt;/code&gt;, adding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;root:           user1@example.com, user2@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: after modifying &lt;code&gt;/etc/aliases&lt;/code&gt; you must run &lt;code&gt;newaliases&lt;/code&gt; to refresh the alias database for the changes to take affect, e.g.:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo newaliases
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;creating-forward&quot;&gt;Creating .forward&lt;/h3&gt;

&lt;p&gt;The simplest way to do this is to log in as the user required and run the following command (replacing the email address as appropriate):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo username@example.com &amp;gt; ~/.forward
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;secure-shell-ssh&quot;&gt;Secure Shell (SSH)&lt;/h2&gt;

&lt;p&gt;Secure shell (ssh) is the defacto standard for remote shell access.&lt;/p&gt;

&lt;h3 id=&quot;client&quot;&gt;Client&lt;/h3&gt;

&lt;p&gt;You can connect to a remote machine using the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh username@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will usually be prompted for your password.  &lt;/p&gt;

&lt;p&gt;Rather than using a password you can use key based authentication.  On your client machine, create a key and use a string pass phrase:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh-keygen -v -t rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a &lt;code&gt;~/.ssh&lt;/code&gt; directory containing &lt;code&gt;id_rsa&lt;/code&gt; which is your private key and &lt;code&gt;id_rsa.pub&lt;/code&gt; which is your public key.  Its important to have the correct permissions, so check the output of &lt;code&gt;ls -la ~/.ssh&lt;/code&gt; is similar for the following entries:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;drwx------   5 user  group   170 22 Mar 07:04 .
-rwx------   1 user  group  1743 22 Mar 07:04 id_rsa
-rwxr--r--   1 user  group   397 22 Mar 07:04 id_rsa.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can copy you public key up to a server using the following command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp ~/.ssh/id_rsa.pub username@hostname:~/.ssh/authorized_keys
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You should now be able to ssh to the server without being challenged for a password, e.g:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh username@hostname
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depending on the client and your preference, you can either enter the passphrase for you private key each time you connect, or run &lt;code&gt;ssh-agent&lt;/code&gt; and register the key using &lt;code&gt;ssh-add&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&quot;server&quot;&gt;Server&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;sshd&lt;/code&gt; is the ssh daemon and is responsible for providing ssh access to the server.  Its important to ensure that this is secure as possible.  There are a number of articles out there about changing the configuration of sshd to make it more secure, in particular I like to turn off password authentication (forcing the use of public/private key pairs) and disable root login.  &lt;strong&gt;Of course, you should ensure that you have a suitable user able to log in using a key that you have tested before you lock yourself out permanently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The configuration for sshd is found at &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;.  Modify it to have the following lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PasswordAuthentication no
PermitRootLogin no
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Restart sshd for your changes to take effect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo /etc/init.d/ssh restart
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;basic-web-server-stack&quot;&gt;Basic web server stack&lt;/h2&gt;

&lt;p&gt;The basic stack of Apache HTTP Server (A), MySQL (M) and PHP (P) is known as AMP due to the initials, or LAMP on Linux.&lt;/p&gt;

&lt;p&gt;Apache HTTP Server and PHP were already installed and available on the VPS, however, you can make sure by running the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install apache2 php5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As part of the MySQL installation, I like to install phpMyAdmin as this is a really useful admin application.  Install mysql server and phpMyAdmin packages, entering suitable values when prompted:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install mysql-server phpMyAdmin
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To enable phpMyAdmin, symlink the apache conf as a site and enable it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/sites-available/phpmyadmin
sudo a2ensite phpmyadmin
sudo /etc/init.d/apache2 reload
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Check connectivity by accessing the site using &lt;code&gt;http://servername/phpmyadmin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note that phpmyadmin could be used by hackers to brute force attack your databases.  As always, you should use suitably strong passwords to ensure that this is not easily done, and also use suitable permissions for the database users to minimise external access.  I also tend to disable the site (using the &lt;code&gt;a2dissite&lt;/code&gt; command) when its not in active use.&lt;/p&gt;

&lt;h2 id=&quot;issues&quot;&gt;Issues&lt;/h2&gt;

&lt;h3 id=&quot;opening-devnull-failed-permission-denied&quot;&gt;opening /dev/null failed (Permission denied)&lt;/h3&gt;

&lt;p&gt;This is mentioned in &lt;a href=&quot;https://launchpad.net/ubuntu/+bug/63031&quot;&gt;63031&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a reboot the permissions on &lt;code&gt;/dev/null&lt;/code&gt; are incorrect:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ls -l /dev/null
crw------- 1 root root 1, 3 Sep  5 14:26 /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can be fixed by running the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo rm /dev/null
sudo mknod -m 0666 /dev/null c 1 3
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 

</feed>
