You’re gonna want to put on your admin hat! This guide is written for a new Ubuntu 14.04.2 LTS droplet built on digitalocean.com. We’ll go for repository versions of all these components.
First, this guide is 99% accurate for 14.04.2 and will get you Nginx, MySQL and PHP taken care of.
Bonus: Jenkins. I love Jenkins, mainly because it’s a one-install server that lets me schedule automated builds and other deployment tasks via my browser. It’s easy to set up, easy to secure, and once it’s set up you may never need to SSH into the server again. Just follow the regular instructions at http://pkg.jenkins-ci.org/debian/ – that will put Jenkins on port 8080, then follow this quick guide to enable some basic security.
We’ll need some more software though. This is taken from the list of components that Homestead uses, and all commands are being run as the root user.
apt-get install git redis-server beanstalkd memcached php5-cli php5-mcrypt php5-curl node node-legacy npm
An oddity here – you need to manually enable mcrypt before PHP can use it:
With that done, install the tools Laravel uses:
npm install -g bower grunt gulp
And last but not least, Composer:
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin --filename=composer
That will add “composer” as a CLI command in one go.
So we’ve got a Laravel-capable server now. Let’s get a basic CI pipeline going using Jenkins. We’ll set up something simple that will pull changes from our develop branch into a develop directory on the server, and run any migrations or updates that are required. This is not the best way to handle production releases (you’ll want to use versioned-everything on the server), but it’ll do for a quick setup.
Before getting started – database access. Default Laravel 5.1 applications are configured to connect as ‘forge’, to localhost with no password, and use the ‘forge’ database. You might have different details in your project, in which case you’ll need to configure MySQL with matching username, password and database. We’ll just set it up to handle Laravel’s system defaults here:
mysql -uroot -p Enter password: create database forge; grant all on forge.* to 'forge'@'localhost' identified by '';
There’s a little more server-side prep to do – folders and SSH keys. Prepare the folders by ensuring the jenkins user has write access. I prefer having my projects live in a root folder, with symlinks out to the html root:
mkdir -p /projects/project-1/develop cd /projects chown -R jenkins:jenkins *
Now set up Jenkins’ SSH key. On the server, run:
su jenkins ssh-keygen
Accept all the defaults. That should create a key in /var/lib/jenkins/.ssh/. Run:
Copy the public key. Save it somewhere, if you’re going to use this same server to pull and compile multiple repositories. Right now you’ll just want to add it as a Deployment key under the repository Settings in bitbucket.
Finally, we’ll set up the symlink. It’ll be broken until the project itself is checked out for the first time. Start by dropping the default html folder:
cd /var/www rm -rf html
Now create a symlink that points to where the public subfolder will be:
ln -s /projects/project-1/develop/public/ html
Finally, to Jenkins. We’re going to use the most basic job possible – a straightforward series of commandline instructions. Create a new Freestyle project and give it a name. Under the Build heading, click Add Build Step -> Execute Shell. In there, we’ll just put the commands we would have run ourselves:
# Move to working directory cd /projects/project-1/develop; # If artisan exists and composer has run, bring the app down for maintenance if [ -e artisan ] && [ -d vendor ]; then php artisan down fi; # If we've already cloned, update - otherwise clone from scratch if [ -e artisan ]; then git pull else git clone -b develop firstname.lastname@example.org:woganmay/project-1.git .; fi; # Ensure storage folders are writeable chmod -R 0777 storage/; # Run updates and migrations composer update; php artisan migrate --force; # Bring us back out of maintenance mode php artisan up;
Save the job config and hit Build Now. This will schedule a new job, and then run it immediately, showing the status under the Build History widget. You can view the output of the job as it runs by hovering over the little down arrow by the light, and clicking Console Output:
This will show the raw output from all your commands. It’ll take a while the first time around, as it has to download all the composer packages for the first time. Subsequent runs will be a lot faster as it installs everything from cache. When it’s done you should see something like this towards the bottom of the Console Output:
That ‘Finished: SUCCESS’ is what we’re after. That means the project deployed correctly, and you should now be able to browse to it via HTTP. Future deployments can be kicked off by logging into Jenkins and clicking Build Now.