Install Solr on Vagrant

[Update]
This method will install an older version of Solr. To get the latest I followed this guide.

All I had to do was add:

config.vm.network :forwarded_port, host: 4569, guest: 8983

to the Vagrant file.

You can then start Tomcat with:

/etc/init.d/tomcat6 start

and Solr

sudo java -jar /opt/solr/example/start.jar

[/Update]

Installing Solr on Vagrant is pretty simple.

vagrant shh

then:

sudo apt-get update

sudo apt-get install openjdk-6-jdk

sudo apt-get install solr-tomcat

Then in your Vagrantfile add something like:

config.vm.network :forwarded_port, host: 4568, guest: 8080

Reload Vagrant:

vagrant reload

and ssh back in again.

Finally:

sudo service tomcat6 start

and Solr should be running. Test it out:

http://localhost:4568/solr/

Solving [Doctrine\DBAL\DBALException] Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform may not support it.

Importing pre-existing MySQL DB using Doctrine in Symfony2 I came across this error:

 [Doctrine\DBAL\DBALException]
  Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform
   may not support it.

The fix was found within the Symfony2 Docs

To app/config/config.yml just under your connection info add:

mapping_types:
                    enum: string

PHP – Auto generate links from pre-defined strings Class

I needed a way of automatically generating links from blog posts, based on a pre-defined set of variables, so I built this basic PHP Class. I did’nt’ Google around to see what others had done as I fancied the challenge. I’m sure this can be improved immensely. :)

/**
 * Link Builder from array
 *
 * Takes received string and array of text and auto generates links based on the array.
 *
 * Usage:
 * $linkArray[] = array(
 *                  'link' => 'http://www.kieronhoward.co.uk',
 *                  'text' => array(
 *                          'My Website',
 *                          'kieron howard'
 *                  )
 *          );
 *
 * @author Kieron Howard <contact@kieronhoward.co.uk>
 * @version 1.0
 *
 */

Class LinkBuilder
{
    private $linkArray;
   
    public function getLinkArray()
    {
        return $this->linkArray;
    }
   
    public function setLinkArray(array $linkArray)
    {
        $this->linkArray = $linkArray;
        return $this;
    }
   
    public function addLinkText($link , $text = array())
    {
        $linkArray = $this->linkArray;
       
        $linkArray[] = array(
                    'link' => $link,
                    'text' => $text                        
                   
        );
       
       
        $this->linkArray = $linkArray;     
       
        return $this;      
    }
   
    public function generateLinks($string)
    {      
        $LinkedText = '';
        foreach ($this->linkArray as $linkText)
        {
            foreach($linkText['text'] as $text)
            {              
                $pattern = '~' . $text . '~';
                   
                if(preg_match($pattern, $string, $url))
                {
                    $LinkedText .= preg_replace($pattern, '<a href="'.$linkText['link'].'" rel="nofollow">'.$url[0].'</a>', $string);                      
                }              
            }          
        }
       
        if($LinkedText != '')
        {
            return $LinkedText;
        }
        else
        {
            return $string;
        }  
       
    }
   
}

Usage:

You can either pass in a predefined array , or use the addLinkText() method.

$linkArray[] = array(
'link' => 'http://www.kieronhoward.co.uk',
'text' => array(
'Kieron Howard',
'my site'
)
);

$LinkBuilder = new LinkBuilder();
$LinkBuilder->setLinkArray($linkArray);
$LinkBuilder->;addLinkText('myLink' , array('MyText' , 'MyText2'));

//will output 'Welcome to <a href="http://www.kieronhoward.co.uk">my site</a>
echo $LinkBuilder-&gt;generateLinks(Welcome to my site);

Initial look at the Laravel PHP framework

Over the last few years I’ve had great experiences and results using Symfony2 to build web apps. It was the first framework I really explored and used to any extent and the focus on MVC really helped my progression as a developer.

For a project I needed to decide whether to use what I knew (Silex/Symfony2) or branch out and try something new. Symfony2 is quite heavy, so I wanted something a little lighter, but not so light that it lacks power. It also needed to be flexible enough to extend and scale as needed. It needed to be modern, actively maintained and follow the MVC pattern.

 

I looked at Yii , CakePHP and thought about Zend for a second, but then came across Laravel. It uses some Symfony2 components and has its own ORM and templating engine called Blade.

I’d run into issues before with some templating solutions being too restrictive, so was happy to see its was easy to extend Blade:

 


Blade::extend(function($value) {
    return preg_replace('/\{\?(.+)\?\}/', '&lt;?php ${1} ?&gt;', $value);
});

Perhaps not quite as nice as writing a Twig extension, but it will do the job.

Laravel also has its own dependency injection container called Illuminate, which from this guys tests seemed to be decent enough.

Building RESTful API’s also seems pretty straightforward.

One negative aspect a few people raised was Laravels heavy use of static method calls, and how this would impact on writing unit tests. There docs do have a basic example of using PHPUnit,  but I’ll have to see how this goes, as I really want this app to have 100% coverage.

 

I will continue to post my experiences with Laravel as I go.

 

Using Git to deploy live/dev sites

Deploying to live/dev

Deployment to the live server consists of creating a bare repo in a location on the server accessible via SSH, then pushing to that. A hook script is setup inside this repo to pull any changes out into the working directory for that particular site.

Prerequisites

You need to be able to push changes over SSH to the live server. This means your local machine’s SSH setup must contain the proper keys and an appropriate configuration.

In the case of projects that use private submodules, the server and GitHub repo will need to be set-up with the appropriate deployment keys.

Deployment Keys

Deployment keys are SSH keys that are not tied to a particular user account. They are used to authenticate a server as being able to download code from GitHub for deployment.

For example, if code is pushed to the server that contains links to private submodules on GitHub, then the post-receive hook will try to download and update that code. It’s not appropriate to put a particular user’s keys on the server, so a separate deployment key is created instead.

Deployment keys can be created in the usual way, with the “ssh-keygen” command. The key should be password-less so that updates on the server do not have to be performed manually. The idea is that code in the repos and any associated code to be pulled from submodules happens as quickly as possible to reduce downtime.

The private key should be added to the SSH configuration on the server and associated with the GitHub host. The public key should be placed there for safe-keeping but will also need to be added to any GitHub repos that deploy in this fashion. Under the “Admin” page for a particular repo, there is a tab called “Deploy Keys”.

Deployment keys are transient. If there is an issue with the server, the old keys can be removed from the server and the GitHub repos and new ones generated.

Creating the Remote Repo

SSH into the live server, and create a directory (outside of www is a good place) called “Repos”. Inside here, create a folder with the name of the repo and a “.git” extension. For consistency, match the name used for the repo inside GitHub.

cd ~/Repos
mkdir my-git-repo.git

Change into the newly created directory and initialise a “bare” git repository.


git init --bare my-git-repo.git

A bare repo only has information about the various branches and commits and has no working directory. This means that there are no local changes in this repo, so changes from elsewhere can be pushed in without any conflicts (if it was not bare, a pull action would be necessary, which involves logging in to the server each time).

Pushing Changes

This repo can then be set-up as a remote to any local repo. To push changes over SSH, you just require the location of the repo on the server and the server address:

git remote add live ssh://my-live-server.com/home/ubuntu/Repos/my-git-repo.git

The current state can then be pushed to this repo’s master branch:

git push live master

this assumes you have already setup a ‘live’ ssh shortcut in the .ssh/config file. Without that it would look something like:

git push ubuntu@ssh:my-live-server master

 

The Working Directory

We can now set-up the main location for the site (i.e. where you would normally upload files to over FTP) as a working directory and pull changes from this bare repo. How this is done depends on whether it’s a new site or an existing one.

For a new site, the process is very simple. It involves changing into the directory where the new site is going to be based and cloning from our bare repo.

cd ~/www/mylovelysite.com/web
git clone /home/ubuntu/Repos/my-git-repo.git .

For a site that already contains files, it’s a little more complicated. We need to create a git repo out of the current directory, add a remote to it under the name “origin”, fetch the branches from the origin and then checkout a branch into master.

cd ~/www/mylovelysite.com/web
git init
git remote add origin /home/ubuntu/Repos/my-git-repo.git
git fetch
git checkout -f -b master origin/master

The “-f” flag will overwrite all files in the directory that are currently under version control. Any files in the destination directory that are not under version control will stay as they are. Running a “git status” will no show all the remaining untracked files. These should either be removed if they’re not necessary or added to the “.gitignore” file.

Receive Hooks

After pulling from the bare repo the first time, we want to automate the process of merging in new changes. The act of pushing changes to the bare repo can trigger a script called a post-receive hook. This is simply a bash or other script within the bare repo.

Here’s an example script to take changes pushed to the bare repo and merge them into the working tree where the site sits:

#!/bin/bash

GIT_DIR=/home/ubuntu/www/mylovelysite.com/web/.git/
GIT_WORK_TREE=/home/imagineftp/www/mylovelysite.com/web/
cd /home/ubuntu/www/mylovelysite.com/web

git fetch
git merge origin/master
git submodule update --init --recursive

After setting up some environment variables and changing into the working directory for the site, the script fetches all the current refs from all the remotes. It then merges the master branch from the origin remote (which should point to the bare repo). Finally, it will update all submodules within the repo. Here you can also run any cache clear commands or other housekeeping.

This script would sit inside the bare repo’s “hooks” directory, named “post-receive”. Make sure that execute permissions are set properly on this file otherwise it will not be able to run:

chmod a+x post-receive

The output of this script will be echoed back to you when you push changes to the bare repo so that any problems can be addressed.

Creating a Symfony2 Custom Exception Handler

I wanted to be able to handle 404 , 500 errors etc. in my own way. The first step is to create your custom error404.html.twig template. The issue I was having was that I had a dynamic menu (amongst other things) that were then not available to the view.
Using the built in exception handler resulted in required variables not being available.

This meant building my own exception handler:

namespace MyCo\MyBundle\Listener;

use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\TwigBundle\TwigEngine;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class MyErrorExceptionListener
{

private $container;

function __construct($container)
{
$this-&gt;container = $container;
}

public function onKernelException(GetResponseForExceptionEvent $event)
{
// We get the exception object from the received event
$exception = $event-&gt;getException();

if($exception-&gt;getStatusCode() == 404)
{

$response = new Response($templating-&gt;render('MyBundle:Exception:error404.html.twig', array(
'exception' =&gt; $exception
)));

$event-&gt;setResponse($response);

}

}

and then in your config.yml register the service:

 

core.exceptlistener:
class: %core.exceptlistener.class%
arguments: [@service_container]
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException, priority: 200 }

making sure to pass any arguments you want into the service register.

You should then be able to pass any dependent variables in using something like:

$globalVars = $this->container->get(‘globalvars’);

Block bots attempting to login to Ubuntu server using Denyhosts

It’s common practice to only allow web server access via SSH using key authentication. While this makes it impossible to login without the key, a quick look at:

tail -n500 -f -s3 /var/log/auth.log

Showed an endless stream of dictionary attempts trying to gain root/admin access to the servers. While they would never succeed, its preferable to try and avoid a DDOS scenario.

As we run a SSHd which is available remotely , I installed DenyHosts

sudo apt-get install denyhosts

DenyHosts will block an IP after a few failed attempts.

Denyhosts need no real setup, but its advisable to add your IP’s you use to access your server to:

sudo nano /etc/hosts.allow

So you can never be locked out.

Installing Varnish reverse proxy for PHP on Ubuntu

Varnish is a reverse proxy designed to speed up your PHP apps. A good introduction can be read on IBM’s site and on the PHP Manual.

 

Installation:

curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -

echo “deb http://repo.varnish-cache.org/ubuntu/ precise varnish-3.0″ | sudo tee -a /etc/apt/sources.listdeb http://repo.varnish-cache.org/ubuntu/ precise varnish-3.0

then update apt by running:

sudo apt-get update

install Varnish by:

sudo apt-get install varnish

Next we need to edit the default Varnish config:

sudo nano /etc/varnish/default.vcl

Then replace

“# backend default {

# .host = “127.0.0.1″;

# .port = “8080″;

# }”

With

backend default {

.host = “127.0.0.1″;

.port = “8080″;

}

 

Edit the ports.conf file

sudo nano ports.conf

and change the port setting from “Port 80″ to “Port 8080″, and restart apache.

sudo service apache2 restart

You may also have to change “Listen 80″ to “Listen 8080″ if it exists.

 

Now open the Varnish default.vcl and change the port of the default backend to 8080.

Edit the Vhosts file in sites-enabled:

sudo nano my-virtual-hosts-site
to be on 8080

pkill varnishd

sudo varnishd -f /etc/varnish/default.vcl -s malloc,1G -T 127.0.0.1:2000

Check logs with : Varnishlog

Should look like:

12 TxProtocol   c HTTP/1.1
12 TxStatus     c 500
12 TxResponse   c Internal Server Error
12 TxHeader     c Server: Apache/2.2.22 (Ubuntu)
12 TxHeader     c X-Powered-By: PHP/5.3.10-1ubuntu3.4
12 TxHeader     c cache-control: no-cache, max-age=1
12 TxHeader     c Expires: Mon, 21 Jan 2013 10:26:48 GMT
12 TxHeader     c Vary: Accept-Encoding
12 TxHeader     c Content-Encoding: gzip
12 TxHeader     c Content-Type: text/html; charset=UTF-8
12 TxHeader     c Content-Length: 8094
12 TxHeader     c Accept-Ranges: bytes
12 TxHeader     c Date: Mon, 21 Jan 2013 10:26:50 GMT
12 TxHeader     c X-Varnish: 1823340195

varnishtop -i rxurl

will show you what URLs are being asked for by the client. 

varnishtop -i txurl

will show you what your backend is being asked the most. 

varnishtop -i RxHeader -I Accept-Encoding

will show the most popular Accept-Encoding header the client are sending you.