Laravel to Digital Ocean using Server Pilot and Rocketeer

Recently I have been using Digital Ocean, they provide simple, quick, secure, and easy to setup servers which are perfect for hosting Laravel projects. They use SSD drives, take less than a minute to create, and cost as little as $5 a month, pretty nice!

I also recently discovered Server Pilot, a *really* easy way to manage your new server. With one line of code in terminal it sets up the server ready for use. It installs ngnix + Apache (yes, both at the same time), deals with security, then makes virtual hosts, ssl certificates and mysql (including security) as easy as 1 click.

Rocketeer is a deploy script, used for deploying php code simply, it integrates with Laravel nicely too.

Laravel is my MVC framework of choice, and here’s how I get it running on Digital Ocean using Server Pilot and Rocketeer.

logos

In this post we’ll be

  1. Creating a Laravel project on your local machine
  2. Uploading that to Github or Bitbucket (I’ll be using Bitbucket)
  3. Creating a server on Digital Ocean
  4. Using Server Pilot to setup the server for our needs
  5. Logging into the server to confirm a few basics
  6. Using Rocketeer to deploy our code to the server

This guide assumes you can use git, and you have accounts with the following sites:

It also assumes you have Git, Composer, and PHP installed locally.

Right, lets get stuck in!

Digital Ocean

Creating a droplet takes less than 55 seconds, that’s pretty speedy for a vps server.

Digital Ocean

You’ll want to make sure you have added your computers ssh keys to Digital Ocean, if you don’t know how to do this then follow their guide here

Now, lets create a droplet, selecting the following options:

  1. Hostname: rhtest (choose a hostname that suits you and remember it for later)
  2. Size: $5 a month should do us for now
  3. Region: choose one near you, or your audience
  4. Image: Ubuntu 14.04 x64 (it’s important you choose this image, as this is what Server Pilot requires)
  5. SSH keys: select the ssh key(s) for your computer(s)

Click ‘create droplet’

Less than a minute later and you have a server!

To login via terminal just type ssh root@[server-ip-address]
enter [yes] to confirm you want to add that server to your known hosts

Server Pilot

Now we want to connect Server Pilot to your shiny new ubuntu server.

Server Pilot

In Server Pilot click ‘connect server’ and give it a name, I’m using ‘rhtest’

Copy the code given to you, and paste it into your terminal window, press enter.

30 seconds later and the code will have finished, your server is now connected to Server Pilot.

Back on Server Pilot you are shown your new server details, click ‘Apps’ and ‘Add App’

Enter your app details, for this example I’ll be using the following

App Name: laraveltest
Domain Name: laraveltest.com 
Runtime: PHP 5.6
Server: rhtest

If you application needs a database connection, you can click the ‘databases’ tab, and click create database. Here you will be given the database connection details you will need to put in the databases.php file of your laravel app.

If you want to connect to this database externally, then you will have to set your mysql database client to ssh into the server, using the username ‘root’ and your keyfile.

Server Preperation

We need to run a few commands on the server to prepare us for laravel.

First we need to create a keyfile, which will authenticate the server with Bitbucket

ssh-keygen -t rsa -C "[your-email-address]" (you can press enter to confirm all the options)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa

Then we need to copy this into Bitbucket, type

cat ~/.ssh/id_rsa.pub

You should expect to see something like

ssh-rsa AABA4FduGd.... youremailaddress@mail.com

Copy it all to your clipboard then head to Bitbucket

At the top right click the dropdown and click manage account, then ‘ssh keys’ on the bottom left.
Click ‘add key’ and paste in your key, giving it a sensible label.

To let our server know we are happy to connect to Bitbucket, we first need to run a test connection in terminal

ssh -T git@bitbucket.org (type 'yes' to authenticate)

Now our server can connect to Bitbucket and grab our code

We’ll need to create a folder on the server to download our projects to

sudo mkdir /var/sites

Updating composer is also extremely important, notice that Server Pilot has a different name for composer, depending on your php version.

composer5.6-sp self-update

One thing to note here is that Server Pilot uses the serverpilot user when serving your site, rather than the usual www-data user, this caught me out initially.

Laravel

LAravel

I’ll assume you have a Laravel project already on the go, you can skip this section if you already have a Laravel project on Bitbucket.

If you need to create a new Laravel project quickly you can use the following command, this will create a project called laraveltest within your current folder. Make sure you are running this command on your local machine, and not on your server.

composer create-project laravel/laravel laraveltest --prefer-dist

Further documentation about starting a Laravel project can be found here

In Bitbucket click ‘create’ to make a new repo, and give it a name.

Then in terminal

cd laraveltest (your project name)
git init
git remote add origin [your-bitbucket-ssh-address] (Find in Bitbucket by clicking - Command line - I'm starting from scratch)

edit your .gitignore file and remove the line containing ‘composer.lock’, we’ll need the server to have this file later

Now, lets push this code to Bitbucket

git add .
git commit -m 'Initial commit'
git push -u origin master

Rocketeer

To install rocketeer first add it to your composer json file in the ‘require’ section

"anahkiasen/rocketeer":"2.0.*"

Add to your providers in app/config/app.php

'providers' => array(
    // ...
    'RocketeerRocketeerServiceProvider',
),

and now your aliases (also in app/config/app.php)

'Rocketeer' => 'RocketeerFacadesRocketeer',

Run a composer update

composer update

Then publish the config files using the ignite command

php artisan deploy:ignite

This will ask you a series of questions about your system

host: (the ip address of your server)
username: root
password or key: key
path to key: (it should be able to guess this, so you can just press enter)
passphrase: if you have one
repository: your Bitbucket address
username: no username required, so just press enter (as we are using keyfiles to authenticate)
password: press enter (as above)
application name: it will guess this, press enter (probably better to keep this the same as your Server Pilot app name)

Now your config files will be accessible in your app/config/packages/anahkiasen/rocketeer folder

We need to make a few changes to get things working with server pilot

paths.php

We need to update this file as server pilot uses it’s own version of php and composer. (shown for php 5.6, update the version number below if required)

'php'      => 'php5.6-sp',
'composer' => 'composer5.6-sp',
remote.php

We need to update the server root

'root_directory' => '/var/sites/',

Also the folder permissions so the app can write to the logs (as the webserver runs under the serverpilot user)

sprintf('chown -R serverpilot:serverpilot %s', $file),
hooks.php

We need to add a pre deploy hook to remove the current web server root, this is because we’ll be mapping our own server root to this location. This we will do with a pre deploy web hook.

'before' => array(
		'setup'   => array(
			'rm -r /srv/users/serverpilot/apps/laraveltest'
		),
		'deploy'  => array(),
		'cleanup' => array(),
	),

We’ll then need to map our files to the web server root.

'after'  => array(
		'setup'   => array(
			'ln -s /var/sites/laraveltest/current /srv/users/serverpilot/apps/laraveltest'
		),
		'deploy'  => array(
			'php5.6-sp artisan migrate'
		),
		'cleanup' => array(),
	),

Why did we just do that? When rocketeer deploys our code it puts it in a timestamped folder, and then maps it (via a symlink) to the ‘current’ folder. This means that the current folder will always contain the most recent version of the code. It means that we can switch between versions easily, and deploy code without writing over the old code. You are simply deploying code to a new folder, and then remapping the current folder to your new code, which happens seamlessly.

But this folder configuration doesn’t fit within Server Pilots structure, so we upload our code to a seperate folder (/var/sites/) and then map the current version (/var/sites/[app-name]/current) to your web server root. For my server this is /srv/users/serverpilot/apps/laraveltest.

Once you have deployed, and these two scripts have run, you now have your laravel code appearing in your web server root, ready to be rendered when someone navigates to your site.

Due to an error with the current version of Rocketeer you may have to run these setup commands manually. log into the terminal and run:
rm -r /srv/users/serverpilot/apps/laraveltest
ln -s /var/sites/laraveltest/current /srv/users/serverpilot/apps/laraveltest
strategies.php

Server Pilot uses a custom composer command, and although we have specified a custom command this version of rocketeer doesn’t seem to use it.

To get around this you can force the strategies file to return the correct composer command.

Comment out the ‘return $composer->install’ line (as seen below), and add in the custom composer command.

//return $composer->install([], ['--no-interaction' => null, '--no-dev' => null, '--prefer-dist' => null]);
return 'composer5.6-sp install';

Deploy

We can now deploy our application, so navigate to you laravel folder on your local machine.

php artisan deploy

The first time you run the deploy command Rocketeer will notice that the server hasn’t been setup yet and will run the setup script, this will then alert you about a missing mcrypt and mysql, you can ignore this.

Migrations

Becuase deploy hooks are not working it means that out database migrations will not fire, as a temporary solution you can log into your server and run the following commands when you need to migrate your database schema.

cd /var/sites/laraveltest/current
php5.6-sp artisan migrate

Testing

To test your site without actually modifying your domain, you can use the following command to update your hosts file (for mac)

sudo nano /etc/hosts

Then add your server ip address and domain, for example

104.131.1.1		laraveltest.com www.laraveltest.com

save with ‘control o’, exit with ‘control x’

now going to laraveltest.com will direct your browser to your server. Remember to remove these once you have finished testing, and have pointed your domains at your server.

Finished

You show now have your laravel app deployed to your server, you have arrived!

Laravel Arrived

Multiple developers

If you have multiple developers working on your project then rocketeer will run into issues when it comes to specifying the servers private key. On my machine this file is located at /Users/richard/.ssh/id_rsa, so unless all your developers on your team have the same name you’re going to want to specify a different path for each developer.

Dot files are the solution to this problem, and are hidden files used for specifying environment dependent variables.

If you don’t already have a local environment dot file, then create one in your applications root folder:

.env.local.php
<?php

return array(

    'keyfile_location' => '/Users/richard/.ssh/id_rsa',

);

Add this to your .gitignore file to make sure this file isn’t passed to your colleagues, get them to create their own version of this file.

Now you can replace the hard coded key in your config.php file to your new dot file.

'key'       => $_ENV['keyfile_location'],

1 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *