// Tutorial //

How To Horizontally Scale a Laravel 4 App with a PostgreSQL Database

Published on February 27, 2014
Default avatar
By Alex Kavon
Developer and author at DigitalOcean.
How To Horizontally Scale a Laravel 4 App with a PostgreSQL Database

Introduction


There are two methods to scaling an application, service, server, etc. The first, vertical scaling, calls for more resources to a machine. The second, horizontal scaling, calls for a separation of functionality to create a more piecemeal assembly of parts.

For example, does a machine spit out memory errors in the syslog? It may make sense to just add more RAM or a swapfile. However, let’s say the database server is growing to a large amount of entries and the web server alone is starting to increase in traffic – a better idea may be to set up a more controllable environment (not to mention more cost effective). To do so, a separation of the web server and database server into separate machines is the key. That is horizontal scaling.

Requirements


  • Two droplets each running Debian 7. Each VPS should have completed Initial Server Setup tutorial.

  • A basic understanding of Linux commands and what they do. See An Introduction to Linux Basics for a good starting point.

  • You will need to have installed Laravel successfully on one of the droplets. This tutorial will work for NGINX + Laravel 4 (skip the Wrap Up step): Laravel + Nginx

Do not install a database on the same virtual server as your Laravel install

For the sake of simplicity, we will refer to the first droplet with the Laravel and Nginx install as the Laravel droplet with an IP of 192.0.2.5. The second droplet with the PostgreSQL install will be called the database droplet with an IP of 192.0.2.1.

Prepping the Database


Horizontal scaling is a rather simple concept that can be come rather complex when you start thinking about more advanced topics such as database replication and load balancing. However we’ll only be covering a basic separation of services: the web server frontend and the database backend. Luckily PostgreSQL and Laravel make this a rather simple process.

First we will need to install PostgreSQL on our database droplet:

sudo apt-get install postgresql

Next, we must create a database and user within the server that will have the proper permissions to interact with the database. To do so, we must log into the PostgreSQL server:

sudo -u postgres psql

First, let’s create the database user:

CREATE USER databaseuser WITH PASSWORD 'password';
GRANT CREATE ON SCHEMA public TO databaseuser;
GRANT USAGE ON SCHEMA public TO databaseuser;

Then create the database with the user as the owner and then quit the server:

CREATE DATABASE mydatabase WITH OWNER databaseuser;
\q 

Next, the database droplet will need to know that it’s okay for the Laravel droplet to connect to it. PostgreSQL has a client authentication file that makes this super easy.

sudo nano /etc/postgresql/9.1/main/pg_hba.conf

Add a line that includes the connection, database name, database user, address to be accepted, and the method of connection:

# IPv4 local connections:
host  mydatabase   databaseuser   192.0.2.5/32   md5

Save and exit, then open up postgresql.conf and find the line that says “listen_addresses = ‘localhost’”.

sudo nano /etc/postgresql/9.1/main/postgresql.conf

listen_addresses = '192.0.2.1'

You may also change this value to one that will accept any address:

listen_addresses = '*'

Save, exit, and restart the PostgreSQL server:

sudo service postgresql restart

Configuring Laravel


The first thing that needs to be done is to give PHP some knowledge of how to work with the PostgreSQL server. Do so by installing the php5-pgsql extension.

sudo apt-get install php5-pgsql sudo service php5-fpm restart

Next we need to tell Laravel where our database server is located and how to access it. If you followed the NGINX + Laravel tutorial, then Laravel should be installed at /var/www/laravel.

sudo nano /var/www/laravel/app/config/database.php

First let’s have Laravel use it’s PostgreSQL driver:

'default' => 'pgsql',

Next, let’s setup information about the PostgreSQL server.

'pgsql' => array(
      'driver'   => 'pgsql',
      'host'     => '192.0.2.1',
      'database' => 'mydatabase',
      'username' => 'databaseuser',
      'password' => 'password',
      'charset'  => 'utf8',
      'prefix'   => '',
      'schema'   => 'public',
    ),

Save and exit.

Testing the Connection


To test this connection, let’s run a migration in from the command line that will help build our database tables out.

Note: Migrations isn’t an extra package to be installed. It comes with laravel and it’s a set of commands to interact with our database.

First enter the application directory where artisan is located.

cd /var/www/laravel

Great! Now it’s time to install migrations and see if our database connection is working.

php artisan migrate:install

If this command runs successfully without errors you should see a new table in your database called migrations.

Wrapping it Up


As you can see, splitting servers is rather simple. By combining horizontal scaling with vertical scaling, a sysadmin can achieve separation of services and increased performance. Even better these methods require 0 extra software.

<div class=“author”>Submitted by: <a href=“https://twitter.com/alexkavon”>Alex Kavon</div>


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?

A more advanced version of this tutorial could go on and put a haproxy balancing between two php-fpm (or even hhvm) servers, and then two postgres (read and write, replicated), and some memcached or redis for the sessions.

@tony: Laravel works great on Digital Ocean’s servers. Especially since they have fantastic articles that guide you through every step. It seems like you’re saying you don’t like the default settings for Apache and blaming Digital Ocean. I had zero previous experience with servers before I started using these guys and now I have multiple Laravel installs across 2 droplets, 1 Apache and 1 Nginx (I prefer nginx wholeheartedly, btw). It’s not recommended to rely on .htaccess for Laravel anyway; or any server really.

@tony: That’s how Apache is packaged by default on most distributions. It’ll be same on any other provider that runs Linux.

Are there any specific issues you’re having that I might be able to help with?

Just tried installing Laravel on your servers and it was more trouble than it was worth. By default AllowOverride is set to None so I could not even get my htaccess file to work.

I don’t know if I’d use your servers for a laravel app