Deploying a Laravel Site Using Git
So when I was happy enough with my new Laravel site it was time to deploy it to my live hosting. The hosting company I use are called TSO Host who provide a great pro level shared hosting package. This package includes the standard LAMP install with unlimited databases, things like mod_rewrite installed as default, SSH access, CPanel, Git and fantastic customer support. All of this for £49.99 a year. Bargain.
As I was already using Git during the sites development phase it made sense for me to also use it to deploy to live.
I had to get TSOHost to update my PHP version to >= 5.4 which they completed within an hour of my first support ticket.
Next I had to get Composer installed. You can either install Composer locally to your sites root directory or you can install it globally so you can run the command from anywhere, which is handy if you have multiple sites that require Composer hosted on the same server. Doing a quick ls -la on my users home directory showed a ~/bin directory I could install personal scripts / binaries to. I echoed out the linux $PATH variable to double check this directory was included, which it was. I installed Composer to the bin folder and could now run the composer command from any directory.
Configuring the Live Database
You will need to migrate your database schema and content to your live server. Once you have done this you will probably find your database credentials (database name, username, password etc) are different to that of your development environment. You can tell Laravel about these database credentials in your local git project by editing your app/config/database.php file. Under the ‘connections’ array within this file you will find an array with the key name of ‘mysql’ containing the credentials for your local development db. Duplicate this array, changing the array key name to something like mysql_live and enter the credentials for the live site, and save the file.
Setting up Git
The steps for deploying the Laravel code are essentially the same as here but with a couple of extra steps.
First of all, SSH into the live server, create a directory for your project to live in
mkdir -p ~/repo/<your-site> cd ~/repo/<your-site>
and cd into the newly created directory. Then run
git init --bare
This will create an empty bare git repository. As this is a bare repository we wont actually have any code checked out on disk. This means we will need to create another directory to checkout the code to. Make sure this directory is not publicly accessible, i.e. not within the public_html (or equivalent) directory.
mkdir -p ~/sites/<site-name>
Once this is created, create a post-receive hook within ~/repo/
and insert the contents
#!/bin/sh root="/home/<username>/sites/<site-name>" GIT_WORK_TREE=$root export GIT_WORK_TREE echo "Working tree set to $GIT_WORK_TREE" git checkout -f
and then run
chmod +x ~/repo/<site-name>/hooks/post-receive
to make it executable.
Git will now auto-magically run the post-receive script directly after we push to this repo. To explain the script, we first create a variable called $root (becomes useful later on) which points to the directory we want to checkout our code to. Then we tell git where the working directory is by setting the $GIT_WORK_TREE variable to our $root variable. The script will then print out the directory to the console (via the echo command - you can safely delete this line) and then run the actual checkout which will checkout the project code to the directory we specified.
In order for Laravel to successfully run on the live server, we have to add some extra lines to our post-receive script we created above.
echo "disabling debug mode" # disable debugging sed -i "s/'debug' => true/'debug' => false/g" $root/app/config/app.php echo "setting db to mysql_live" sed -i "s/'default' => 'mysql'/'default' => 'mysql_live'/g" $root/app/config/database.php echo "updating index paths" #update app paths sed -i "s#require __DIR__\.'\/..\/bootstrap\/autoload\.php';#require \"$root\/bootstrap\/autoload\.php\";#g" $root/public/index.php sed -i "s#$app = require_once __DIR__\.'\/\.\.\/bootstrap\/start\.php';#$app = require_once \"$root\/bootstrap\/start\.php\";#g" $root/public/index.php echo "updating bootstrap paths" sed -i "s/'public' => __DIR__\.'\/\.\.\/public'/'public' => '\/home\/<username>\/public_html'/g" $root/bootstrap/paths.php #update public echo "updating public_html" cp -R $root/public/ * /home/<username>/public_html echo "updating permissions" chmod -R 777 $root/app/storage
The code ensures that not only the paths Laravel needs to know about are set correctly (as they will be different from our development environment), it also disables debug mode and sets the database config to use the correct connection setting we added earlier. Finally it copies the contents of Laravels public/ directory to the public_html DocumentRoot.
See how our $root variable came in handy there? As well as changing the $root path to your own, you will need to replace the path to the public_html directory on line 15 and 19 with your own.
Adding a Remote
Back to our local git repo containing our Laravel project we can run
git remote add live ssh://firstname.lastname@example.org:port/home/username/repo/<site-name>
Which will allow us to push to the live repo.
We can double check this worked by running
git remote -v
and we should see a remote called ‘live’ in the list.
We can now run our first push!
git push live master
Once the push has completed you should see all the echoed messages we printed out in our post-receive hook.
Last thing to do. After our first successful push we will need to SSH back into our live server, cd to where our checked out code lives, and tell composer to install Laravels dependencies.
cd ~/sites/<site-name> composer update
This step we will only need to do once, after the very first push.
Once composer has done its thing we should now have a successfully deployed Laravel site!
To update it in the future all we have to do in run
git push web master
Much more fun and secure than FTP, right?
I had really enjoyed working with Laravel, and deploying to live in an automated way using git made it all the more fun.