Git repositories with Slicehost

December 1st, 2009 No comments »

No doubt I am really happy with my Slicehost VPS, it has been so hassle free!  The best part about Slicehost is all the amazing articles they provide to help you get going with your slice.

I’ve setup my slice to host my private git repositories, particularly since I wanted to use them with Rails and Capistrano.  This article provide to be just what I needed:

http://articles.slicehost.com/2009/5/13/capistrano-series-setting-up-git

The article even shows you how to secure the shell that the git user has to avoid anyone SSHing into your box with their ID.  However, it doesn’t tell you what to do when you want to create another repository as you cannot switch to the git user while ever it is using the git-shell as opposed to a normal shell.  The trick is you need to switch with the root user as only they are allowed to provide an alternative shell.  Here are the commands once you have logged into your slice with a user that is able to sudo:

$ sudo su --shell /bin/bash git
$ cd /home/git
$ mkdir project2
$ cd project2
$ git --bare init
$ exit

Now your repository is good to go and you can follow the steps from “Making your first commit” section.

Installing MySQL, Apache2, PHP, and WordPress with MacPorts

November 17th, 2009 1 comment »

I’ve recently started working on a website project using WordPress.  I’ve got a production environment where I run this blog on my ubuntu server (VPS) hosted by slicehost.  But because I’m going to muck around with themes and plugins I decided that I’m better off doing that locally on my Mac.  So this is the first of a series of blog posts for getting WordPress up and running on my local machine.

I have macports already installed and I prefer its packages over the packages shipped with OSX.  Mostly because they are more up to date and there is more variety.  Plus it feels more native to working with my VPS.  Before we get started, lets ensure that our MacPorts is up to date:

$ sudo port selfupdate
--->  Updating the ports tree
--->  Updating MacPorts base sources using rsync
MacPorts base version 1.8.1 installed,
MacPorts base version 1.8.1 downloaded.
--->  MacPorts base is already the latest version

There will be four parts to this series:

  1. Installing MySQL
  2. Installing Apache2
  3. Installing PHP along with MySQL support
  4. Installing WordPress

I like to chunk these up rather than merge them all into one article as the temptation is to mix information together and then its harder to see where one step stops and the next one starts.  Also it means that you can look at the entries in isolation and they should still make sense.

Installing MySQL

I had a binary distribution of MySQL on machine which I needed to remove before installing the macports distro, this thread was useful as it isn’t particularly clear what to do:

http://forums.mysql.com/read.php?11,75256,255851#msg-255851

The following article was my main source of inspiration, I’ve pretty much followed these steps:

http://2tbsp.com/content/install_and_configure_mysql_5_macports

Install the port and setup the mysql system database

$ sudo port install mysql5-server
$ sudo -u mysql mysql_install_db5

Setup some handy aliases in your shell

$ mate ~/.profile
alias mysqlstart='sudo /opt/local/bin/mysqld_safe5 &'
alias mysqlstop='/opt/local/bin/mysqladmin5 -u root -p shutdown'
$ source ~/.profile

Start the server and set the root password

$ mysqlstart
$ /opt/local/lib/mysql5/bin/mysqladmin -u root password 'root'
$ /opt/local/lib/mysql5/bin/mysqladmin -u root -p -h localhost password 'root'

(Not sure what this second step is for!)

Now we can use the mysqlstop alias because the password has been set.

And we’re all done!

Installing Apache2

Source of inspiration for this entry is from here:

http://2tbsp.com/content/install_apache_2_and_php_5_macports

$ sudo port install apache2

Enabled virtual hosts in main config

$ sudo mate /opt/loca/apache2/conf/httpd.conf
# Virtual hosts
Include conf/extra/httpd-vhosts.conf

Updated virtual hosts config

$ sudo mate /opt/local/apache2/conf/extra/httpd-vhosts.conf

The directory part is important as Apache 2.2 directories are by default not browsable so ensure that you enable them!

<VirtualHost *:80>
    ServerAdmin webmaster@myapp.local
    DocumentRoot "/Users/tgmcclen/workspace/myapp/htdocs/site"
    ServerName myapp.local
    ServerAlias www.myapp.local
    ErrorLog "/Users/tgmcclen/workspace/myapp/logs/error_log"
    CustomLog "/Users/tgmcclen/workspace/myapp/logs/access_log" common
 
    <Directory "/Users/tgmcclen/workspace/myapp/htdocs/site">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>    
</VirtualHost>

Setup an alias for controlling apache and start

$ mate ~/.profile
alias apache2ctl='sudo /opt/local/apache2/bin/apachectl'
$ source ~/.profile
$ apache2ctl start

Add an entry in the hosts file for the virtual host

$ mate /etc/hosts
127.0.0.1 myapp.local

Now place files in the htdocs directory and browse to them in a browser:

http://myapp.local/hello.html

Installing PHP along with MySQL support

$ sudo port install php5 +apache2 +pear
...
Note: php5 installs files outside the common directory structure.
--->  Installing php5 @5.3.0_3+apache2+darwin_10+macosx+mysql5+pear+sqlite
--->  Activating php5 @5.3.0_3+apache2+darwin_10+macosx+mysql5+pear+sqlite
To customize php, copy
/opt/local/etc/php5/php.ini-development (if this is a development server) or
/opt/local/etc/php5/php.ini-production (if this is a production server) to
/opt/local/etc/php5/php.ini and then make changes.
$ sudo cp /opt/local/etc/php5/php.ini-development /opt/local/etc/php5/php.ini

Now enable PHP module with apache2

$ cd /opt/local/apache2/modules
$ sudo /opt/local/apache2/bin/apxs -a -e -n "php5" libphp5.so

and add directives for mime_module and dir_module in the virtual host entry:

<VirtualHost *:80>
    ServerAdmin webmaster@myapp.local
    DocumentRoot "/Users/tgmcclen/workspace/myapp/htdocs"
    ServerName myapp.local
    ServerAlias www.myapp.local
    ErrorLog "/Users/tgmcclen/workspace/myapp/logs/error_log"
    CustomLog "/Users/tgmcclen/workspace/myapp/logs/access_log" common
 
    <Directory "/Users/tgmcclen/workspace/myapp/htdocs">
        Options Indexes FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>
 
    <IfModule mime_module>
      AddType application/x-httpd-php .php
      AddType application/x-httpd-php-source .phps
    </IfModule>
 
    <IfModule dir_module>
        DirectoryIndex index.html index.php
    </IfModule>
</VirtualHost>

And then restart Apache to get going…

$ apache2ctl restart

Installing MySQL support for PHP

$ sudo port install php5-mysql
--->  Computing dependencies for php5-mysql
--->  Fetching php5-mysql
--->  Verifying checksum(s) for php5-mysql
--->  Extracting php5-mysql
--->  Configuring php5-mysql
--->  Building php5-mysql
--->  Staging php5-mysql into destroot
--->  Installing php5-mysql @5.3.0_0+mysqlnd
To use mysqlnd with a local MySQL server, edit /opt/local/etc/php5/php.ini and set
mysql.default_socket, mysqli.default_socket and pdo_mysql.default_socket
to /opt/local/var/run/mysql5/mysqld.sock
--->  Activating php5-mysql @5.3.0_0+mysqlnd
--->  Cleaning php5-mysql
$ sudo mate /opt/local/etc/php5/php.ini
; Default socket name for local MySQL connects.  If empty, uses the built-in
; MySQL defaults.
; http://php.net/pdo_mysql.default-socket
pdo_mysql.default_socket=/opt/local/var/run/mysql5/mysqld.sock
 
; Default socket name for local MySQL connects.  If empty, uses the built-in
; MySQL defaults.
; http://php.net/mysql.default-socket
mysql.default_socket = /opt/local/var/run/mysql5/mysqld.sock
 
; Default socket name for local MySQL connects.  If empty, uses the built-in
; MySQL defaults.
; http://php.net/mysqli.default-socket
mysqli.default_socket = /opt/local/var/run/mysql5/mysqld.sock

Installing WordPress

Inspiration for instructions from here:

http://codex.wordpress.org/Installing/Updating_WordPress_with_Subversion
http://codex.wordpress.org/Installing_WordPress

Inside your htdocs directory:

$ svn co http://core.svn.wordpress.org/tags/2.8.6 .

(Latest tag will in URL on page, otherwise just browse to tags dir in folder to determine)

Create the database in MySQL

$ /opt/local/bin/mysql5 -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.40 Source distribution
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql&gt; CREATE DATABASE mydb;
Query OK, 1 row affected (0.05 sec)
 
mysql&gt; GRANT ALL PRIVILEGES ON myname.* TO "mydb"@"localhost" IDENTIFIED BY "mypassword";
Query OK, 0 rows affected (0.58 sec)
 
mysql&gt; FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
 
mysql&gt; EXIT
Bye

Now setup configuration

$ cp wp-config-sample.php wp-config.php
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'mydb');
 
/** MySQL database username */
define('DB_USER', 'myname');
 
/** MySQL database password */
define('DB_PASSWORD', 'mypassword');
 
/** MySQL hostname */
define('DB_HOST', 'localhost');
 
/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');
 
/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

Open a browser and continue the install:

http://myapp.local/wp-admin/install.php

You’ll most likely notice that you’re getting lots of errors and warnings on the pages, these can be turned off:

$ sudo mate /opt/local/etc/php5/php.ini
; Default Value: On
; Development Value: On
; Production Value: Off
; http://php.net/display-errors
display_errors = Off
$ apache2ctl restart

Now you’re good to WordPress away!

Making your Rails app work on Java

September 26th, 2009 No comments »

So you’ve written a Rails app and you want to show it off to your boss at work because you know that it will impress them. Problem is that your company only uses Java and won’t consider it for their production environment if it can’t be deployed under a JVM. Let’s go:

  1. Install JRuby http://jruby.org
  2. Install the required gems for Ruby on Rails to work with JRuby
  3. jgem install mongrel activerecord-jdbcsqlite3-adapter rails
  4. Install the gems particular to your application
  5. jruby -S rake gems:install
  6. Update your database.xml file, prefixing your adapter with jdbc
  7. development:
      adapter: jdbcsqlite3
      database: db/development.sqlite3
      pool: 5
      timeout: 5000
  8. Start your JVM
  9. jruby script/server
  10. Demonstrate
  11. Sit back and wait for promotion

Some notes on whats going on above:

Getting Oracle XE to work with SpringFramework JDBC Template

July 30th, 2009 No comments »

Ever get this error when using Oracle XE with SpringFramework JDBC Template?

SORA-12519, TNS:no appropriate service handler found

You can get around it by executing the following commands:

ALTER SYSTEM SET PROCESSES=150 SCOPE=SPFILE;
ALTER SYSTEM SET SESSIONS=100 SCOPE=SPFILE;

Then stop and start database (Oracle XE service) and you’re good to go!

Remember:

  • needs to be capitals,
  • needs to have both entries
  • stop and start the database (oracle XE service)

Got this from the following two resources:

http://en.newinstance.it/2007/06/01/ora-12519-tnsno-appropriate-service-handler-found/
http://forum.springsource.org/showthread.php?p=133267

Setting up scheduled jobs with Rails

June 8th, 2009 No comments »

I’ve seen lots of different approaches to scheduling jobs with Rails, including a great run down by Ryan Bates’ Rails Casts Episode 129, however the most elegant solution I’ve seen so far is what was outlined in Episode 164 using the cool Whenever gem and good ol’ Cron.

Within a couple of hours I had a weekly scheduled job running all nicely managed entirely through my Rails application code base. The incorporation into Capistrano makes it killer. The only thing that caught me out was that my script/runner file was not set as executable when capistrano was deploying it, therefore runner commands failed to execute through Cron with a “permission denied” error.

Found that all I needed to do was set it to executable within svn:

svn propset svn:executable on script/runner

All good!

Git for dummies

January 31st, 2009 1 comment »

Only just started to finally get stuck into learning git. It certainly seems to be revolutionising the way we do version control. I’m pretty hooked on subversion and I have to admit, I thought that was as good as it gets! But the hype around git to much to ignore.

Here’s some resources I’ve found really useful to get (git) going:

Resources

  • GitCasts by Scott Chacon. Screencasts are for me one of the best ways to learn things, these casts, although very quick, give you that good leg up.
  • Git from the bottom up by John Wiegley. There is a link from his blog entry to a paper he has put together on his understanding of Git. Always good to read some theory!
  • Git – SVN crash course from the offical git site. A great place to start if like me, you’re already familiar with svn.
  • Github’s Git Cheat Sheet is a good resource too!

Getting Ruby to talk to Oracle with Cygwin

January 7th, 2009 No comments »

I need to be able to use Ruby to talk to Oracle databases to help us easily build scripts for maintenance and support. So, I started doing some googling and found ruby-oci8. Excellent!

I’m also mainly PC bound so I needed to get this working on my cygwin installation. My entire Ruby environment is running through cygwin.

So I started through the installation instructions on the ruby-oci8 site but started to find it pretty confusing to follow for the cygwin-specific installation. Finally, after a bit of trial and error, here are the steps I followed to get this baby humming:

  1. Download and unzip the Oracle Instant Client Basic and SDK packages. I successfully did this with version 11.1.0.7.0. The path I chose was:
    C:\oracle\instantclient_11_1
  2. Add the instant client to the front of your system path (through Control Panel –> System)
  3. Launch cygwin
  4. Install the gem
    $ gem install ruby-oci8
    Building native extensions.  This could take a while...
    Successfully installed ruby-oci8-1.0.3
    1 gem installed
    Installing ri documentation for ruby-oci8-1.0.3...
    Installing RDoc documentation for ruby-oci8-1.0.3...

That’s it! You’re now all installed! You’ll notice that the gem compiles some native extensions, this is why you need the instant client to be available in your path.

Now to give it a test run, open up and irb session and give it a go:

irb(main):001:0> require 'oci8'
=> true
irb(main):002:0> conn = OCI8.new('username', 'password', '//server:port/sid')
=> #<OCI8:0x7fdb3d44 @privilege=nil, @prefetch_rows=nil, @ctx=[0, #<Mutex:0x7fdb3cf4>, nil, 65535], @svc=#<ocisvcctx:0x7fdb3ce0>>

We have a connection!

Accessing github from behind a proxy

January 2nd, 2009 No comments »

If you’re behind a proxy which restricts outbound ports (i.e. only port 80 and 443), then you’ll be pleased to know that you can still access Github.

Rather than using the git:// protocol (defaulting to port 9418), you can use the HTTP protocol to do the same thing! Article on Github about it here.

git clone http://github.com/justinfrench/formtastic.git

It also works for Rails plugins!

script/plugin install http://github.com/justinfrench/formtastic.git

Don’t forgot you need to set environment variable http_proxy to tell Git to use the proxy or or can set it in git-config. The example below sets it at the global level:

git config --global --add http.proxy http://myproxy:8080

SSL setup for Ruby

December 18th, 2008 No comments »

I found recently that I wanted to get SSL enabled when making HTTP connections with Ruby. However, if you’re wishing to talk to servers that have certificates signed by commercial certificate authorities then you won’t be able to verify them when you make a connection:

require 'net/http'
require 'net/https'
http = Net::HTTP.new('www.google.com', 443)
http.use_ssl = true
http.get('/mail')
"warning: peer certificate won't be verified in this SSL session"
=<#net::httpfound 302="" found="" readbody="true">

Notice line 6? Not good as its really important to be able to verify SSL certificates on the web to make sure that you’re talking to who you think you’re talking to!

So to verify these certificates, download commercial certificate authorities used by Mozilla (Firefox) that have been kindly pre-packaged for you:

http://curl.haxx.se/docs/caextract.html

Store in a logical location:

/usr/share/ssl/cert.pem

Now, test out that they are working, try this code (IRB works well!):

require 'net/http'
require 'net/https'
http = Net::HTTP.new('www.google.com', 443)
http.ca_file = '/usr/share/ssl/cacert.pem'
http.use_ssl = true
http.get('/mail')
=<#net::httpfound 302="" found="" readbody="true">

Yah! No more warnings, we’re properly verify the server’s SSL certificate!

Tip: If you’re behind a proxy, then you’ll need to change the third step to be:

http = Net::HTTP::Proxy('myproxyserver', 8080).new('www.google.com', 443)

The above code creates a HTTP class with your proxy configuration baked in. Then you can create an instance from it, just like a regulard HTTP class!

Thinking integration

December 16th, 2008 No comments »

After working on several web projects that have required plenty of integration involving many systems within the enterprise, I’ve come to some realisations about getting integration right:

Services must be exposed at the right level

It’s extremely tempting when performing integration to try and apply good application programming practices of keeping methods simple and stringing them together. This practice makes it easier to test methods in isolation, simplifies their contracts, and ultimately leads to more flexible and understandable code.

The frameworks available for performing integration (i.e. web services with Apache Axis) give you a healthy level of abstraction deliberately so that you can easily forget that you are performing integration at all.

But here in lies the problem. As soon as you forget that you are performing integration, you can start to perform good application practice which in turn can lead to disastrous integration practice. For instance, if the services exposed for integration are too fine grained, then the consumer may have to invoke many services to get a enough data to fulfill its objective. User experience and (distributed) server load are the first things that will suffer.

Services need to be exposed at the right level to ensure that a consumer can make as few a calls as possible (ideally one) to fulfill their objective.

No doubt getting this level of exposure correct is the tricky bit, but as soon as you find that you’re starting to become very chatty with services to get things done, this is the sign that its time to think about exposing a new service at a higher level of abstraction.

Ensure that services are fit for purpose

In a similar vein to the point above, it’s important to ensure that the service you’re invoking is truly designed to meet your purpose. There is a temptation to look at a service catalogue and pick out the services that will help you get what you’re after. However, if these services are not in line with your objectives, then there is a good chance that they’ll be doing more than they should be for your needs. This leads again to unnecessary server load and the likely-hood of an impaired user experience.

A good way to spot if a service is unfit for your purpose is to inspect its response payload. If it contains far more information than you need, then you’ve probably got to think about getting a better suited service exposed.

Thinking SOAP based web services as the protocol for integration, the above problem re-enforces for me why the document style web service is a far better approach than the RPC style web service. The later is tightly coupled and inflexible, just like a method call is. The former is the opposite allowing for a service to cover many situations and purposes. Some that may not have been originally conceived but are now required. Incorporating this support should not be costly and have limited if any impact on existing consumers.

So, if a service is using the document style approach and its not quite fit for purpose, you should be in luck! With a small enhancement, you will have the service that fits exactly to your needs.

Here’s an old article that sings the virtues of document style web services:

Reap the benefits of document style Web services