Deploy an Application to the Remote Server

With Git prepared on both the local workstation and on the remote server, I can now deploy my application.

Defining a Remote Repository

In order to deploy an application from my development workstation to istarelworkshop.com, I need to configure the application repository on my workstation such that is can communicate with the repository on the production server.

Here is the current configuration for the Istarel Workshop application:

markf$ cd ~/Sites/iw
markf$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true

Now I configure this repository with user and path information on the remote Git repository. (Note that the 1158 in the remote declaration is the port, for cases where ssh is not listening to its standard port 22.)

markf$ git remote add istarelworkshop 
       ssh://git@www.istarelworkshop.com:1158/var/git/iw
markf$ cat .git/config

If I look at the configuration for the local repository now, I see the definition for "istarelworkshop".

markf$ cat .git/config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
[remote "istarelworkshop"]
	url = ssh://git@www.istarelworkshop.com:1158/var/git/iw
	fetch = +refs/heads/*:refs/remotes/istarelworkshop/*

Cloning a Bare Repository

With the description of the remote repository done, I can now deploy the application.

markf$ git push istarelworkshop master

I am not done yet, though. The repositorities I set up on istarelworkshop.com are bare repositories; that is, they contain all the branches and history but are not a working repository. I need to clone that bare repository to the appropriate location on istarelworkshop.com. In an earlier article, I showed how to set up Apache2 virtual hosts. The first such host has its base directory at /var/www/istarelworkshop.com. I need to take the bare repository and clone it to that location.

markf$ ssh markf@www.istarelworkshop.com
iwuser$ cd /var/www
iwuser$ sudo git clone /var/git/iw istarelworkshop.com
iwuser$ sudo chown -R www-data:www-data istarelworkshop.com

Configure the Remote Application

Back when I set up the local repository, I made sure that certain key configuration files were not part of the repository. This is important because every server is different, and the key paths and identities used on my local workstation are quite different from the Ubuntu VPS I deployed. So, I need to create those configuration files on istarelworkshop.com.

iwuser$ sudo su - www-data
$ bash
www-data$ cd /var/www/istarelworkshop.com
www-data$ mkdir conf && cd conf
www-data$ vi ApplicationConstants.php

Listing: /var/www/istarelworkshop.com/conf/ApplicationConstants.php

<?php

# Fundamental Application Mode
define('IN_PRODUCTION', 1);             # 0 = Development, 1 = Production

# Application Directories
define('APPL_ROOT_DIR', '/');
define('APPL_RSRC_DIR', '/var/www/istarelworkshop.com/rsrc/');

# Istarel Workshop Frameworks Directory
if (! defined('FRAMEWORK_DIR'))
   define('FRAMEWORK_DIR', '/var/www/istarelworkshop.com/fw/');

# Supplemental Directories Required by Application Frameworks Classes
define('APPL_IMG_DIR', APPL_ROOT_DIR . 'img/');
define('APPL_LIB_DIR', APPL_ROOT_DIR . 'lib/');

# Define the Application Database attributes
define('DB_TYPE',       'pgsql');
define('DB_HOST',       'localhost');
define('DB_NAME',       'iw');
define('DB_USERNAME',   'iwdb');
define('DB_PASSWORD',   'secret');

?>

The application framework uses Apache's mod_rewrite system to power the Front Controller. I need to create an .htaccess file at the root of the repository to ensure that proper routing happens.

Listing: /var/www/istarelworkshop.com/.htaccess

RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

Configure Apache with Virtual Hosts

The minimal Ubuntu 8.0.4 package from A2 Hosting comes with Apache 2 preinstalled, but it does not come with mod_rewrite enabled (which is necessary for all applications built with the Istarel Workshop Application Framework).

iwuser$ sudo a2enmod rewrite
iwuser$ sudo /etc/init.d/apache2 force-reload

Virtual Hosts

I intend to host several domains on this Virtual Private Server, and Apache and Ubuntu make it very straightforward to handle mutiple domains through a mechanism called Virtual Hosts. Essentially, you use the IP Address of the server as the "host" (using the NameVirtualHost directive) and then provide a configuration file for each hosted domain which establishes its identity in the context of the main "host".

Partial Listing: /etc/apache2/apache.conf

NameVirtualHost 74.126.25.201:80
Include /etc/apache2/sites-enabled/

I want istarelworkshop.com to be the foremost hosted domain. I need to create its configuration file in /etc/apache2/sites-available.

Listing: /etc/apache2/sites-available/istarelworkshop.com

<VirtualHost 74.126.25.201:80>
   ServerName istarelworkshop.com
   ServerAlias www.istarelworkshop.com
   ServerAdmin admin@istarelworkshop.com
   
   DocumentRoot /var/www/istarelworkshop.com
   <Directory /var/www/istarelworkshop.com>
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Order allow,deny
      allow from all
   </Directory>
   
   ErrorLog /var/log/apache2/istarelworkshop-error.log
   LogLevel warn
   CustomLog /var/log/apache2/istarelworkshop-access.log combined
   ServerSignature On
</VirtualHost>

The AllowOverride is set to all so that Apache will look for (and respect) .htaccess files in the /var/www/istarelworkshop.com directory. That file is where the mode_rewrite rules are given.

To enable this virtual site, I need to create a symbolic link to the sites-avaialble configuration in its sibling sites-enables directory (which is what is actually referenced in the main Apache configuration file). Once Apache is restarted, any visitor navigating to www.istarelworkshop.com will be served pages from /var/www/istarelworkshop.com.

iwuser$ cd /etc/apache2/sites-enabled
iwuser$ sudo ln -s ../sites-available/istarelworkshop.com 001-istarelworkshop.com
iwuser$ sudo /etc/init.d/apache2 restart

Prepare PostgreSQL and PHP

Ubuntu uses aptitude for package management. Before attempting any software installations, aptitude should be updated and upgraded (this process can take quite some time).

iwuser$ sudo apt-get update
iwuser$ sudo apt-get upgrade

Install and Configure PostgreSQL

iwuser$ sudo apt-get install postgresql

I want to change the access control to trust for the unix socket connections.

Listing: /etc/postgresql/8.3/main/pg_hba.conf

# Database administrative login by UNIX sockets
local   all         postgres                          trust

# TYPE  DATABASE    USER        CIDR-ADDRESS          METHOD

# "local" is for Unix domain socket connections only
local   all         all                               trust
# IPv4 local connections: (was "md5")
host    all         all         127.0.0.1/32          trust
# IPv6 local connections:
host    all         all         ::1/128               md5

Those changes make it more convenient for using PostgreSQL's command line tool, allowing a user to assume the identity of any PostgreSQL user. The security here is fine because the only way to access PostgreSQL at the command line is to be ssh'd into www.istarelworkshop.com. Any change to PostgreSQL's security requires a restart of the database server.

iwuser$ sudo /etc/init.d/postgresql-8.3 restart
iwuser$ psql template1 postgres
Welcome to psql 8.3.11, the PostgreSQL interactive terminal.

Type:  copyright for distribution terms
       h for help with SQL commands
       ? for help with psql commands
       g or terminate with semicolon to execute query
       q to quit

template1=# q

Install and Configure PHP 5

iwuser$ aptitude search php5-
iwuser$ sudo apt-get install php5-pgsql php5-xdebug

The aptitude search command is useful for seeing what packages are available (the search term is wildcarded). Because this is a production server, I want to modify the PHP configuration file to provide a little more memory to running scripts, and to hide errors from any visitor.

Partial Listing: /etc/php5/apache2/php.ini

memory_limit = 64M      ; Maximum amount of memory a script may consume (16MB)
display_errors = Off

As always, any changes to the PHP configuration require a restart of the Apache server (which is pre-installed).

iwuser$ sudo /etc/init.d/apache2 restart