laravel

Deploying a Laravel Application Using Capistrano

By Johannes Schickling

Introduction

So you’ve just built a fancy web application and you’re planning to put it online. This can be done in many ways. In this article I’d like to cover one approach to deploy your backend system to your production server. We’ll go through the following steps, by example of a Laravel application but this can be applied to any other language or technology.

 


The Past Capistrano

Perhaps you have already put some websites online in the past. You’ve probably used an FTP client and uploaded the bits and bytes by hand. Or perhaps you always logged into your server via SSH and pulled the changes manually.


The Idea

Our goal is to simplify this process as much as possible. The idea is to use your code repository as a source for every deployment. The deployment tool, in our case capistrano, will automatically log into your server and build your system right out of your repository.

Software deployment is all of the activities that make a software system available for use. – Wikipedia


What You’ll Need…

…On Your Remote Server

Your remote server needs to provide SSH access. It also should have installed all necessary dependencies for your project such as GIT, PHP, MySQL, Composer, etc. Besides that, you don’t need any extra software on your production server.

…On Your Local Machine

In order to install and use capistrano, you need at least Ruby 1.8.7 (if you don’t have Ruby installed, I recommend installing it using rbenv). To install capistrano, you simply have to run:

gem install capistrano

So, why capistrano? You may ask. As always, there are many ways to accomplish a task but in my case, capistrano always seemed to be the easiest and most flexible approach. You can configure it to all your needs and there are a lot of plugins out there which simplify your work again.

Capistrano is a utility framework for executing commands in parallel on multiple remote machines, via SSH. It uses a simple DSL (borrowed in part from Rake) that allows you to define tasks, which may be applied to machines in certain roles. It also supports tunneling connections via some gateway machine to allow operations to be performed behind VPNs and firewalls.


Prepare

Now that we have everything we need, let’s setup our deployment settings. But first we have to create a folder on the remote server where all the files should be deployed to. Log into your server with SSH and create a folder. A common place is /var/www/. So let’s do this:

$ sudo mkdir /var/www/my-app
$ sudo chown -R username:group /var/www/my-app

That’s it. There is nothing more to do on the remote server, so you can close the SSH connection and move on. Go into your project (or any other folder, that doesn’t matter right now) and run:

$ cd my-project
$ capify .

This command will create the basic files we need. The Capfile is like the mount point for capistrano but for now we’ll just need to edit the config/deploy.rb file, which, as the name tells, is responsible for all the configuration. Open this file in your favorite text editor and replace the content with the following snippet. We’ll go through the code afterwards.

set :application, "Your app name"  # EDIT your app name

set :scm, :git
set :deploy_via, :remote_cache
set :repository,  "https://github.com/laravel/laravel.git" # EDIT your git repository

role :app, "12.456.789.123" # EDIT server ip address 
set :deploy_to, "/var/www/my-app" # EDIT folder where files should be deployed

set :user, "" # EDIT your ssh user name
set :password, "" # EDIT your ssh password
set :use_sudo, false
set :ssh_options, {
	:forward_agent => true
}

default_run_options[:pty] = true # needed for the password prompt from git to work

namespace :deploy do

	task :update do
		transaction do
			update_code # built-in function
			composer_install
			prepare_artisan
			symlink # built-in function
		end
	end

	task :composer_install do
		transaction do
			run "cd #{current_release} && composer install --no-dev --quiet"
		end
	end

	task :prepare_artisan do
		transaction do
			run "chmod u+x #{current_release}/artisan"
		end
	end

	task :restart do
		transaction do
			run "chmod -R g+w #{releases_path}/#{release_name}"
			run "chmod -R 777 #{current_release}/app/storage/cache"
			run "chmod -R 777 #{current_release}/app/storage/logs"
			run "chmod -R 777 #{current_release}/app/storage/meta"
			run "chmod -R 777 #{current_release}/app/storage/sessions"
			run "chmod -R 777 #{current_release}/app/storage/views"
		end
	end

end

You now have to put your data in every line with an #EDIT comment (ip address, git repo, ssh user, password, …). The :deploy_to variable should be the folder we just created. Your webserver (Apache, nginx, …) should point to /var/www/my-app/current/public. In the first part of the deploy.rb file, you can set up all your data. In the namespace :deploy block, you specify what actually should happen for each deployment.

So let’s have a quick walk-through on what those task‘s mean:

  • update_code is a built-in method of capistrano and pulls in your latest version from your git repository.
  • composer_install fetches all your PHP dependencies, just like you’re used to during development.
  • prepare_artisan makes the artisan file executable in order to use it for migrations.
  • Every deployment is stored in /var/www/my-app/releases/. The built-in task symlink creates a symbolic link of the recent deployment to the current folder. This way you can keep older releases and switch versions without going offline for a second. When this task ran, your newest version is online.

Here you can easily add your own tasks if your build process requires some extra steps. For more detailed information, I recommend you reading the Wiki on Github.

Now it’s time to initiate the server and test if everything works. Therefore we run the following commands:

$ cap deploy:setup
$ cap deploy:check

You should see the message You appear to have all necessary dependencies installed. That means were are prepared for our first deploy.


Fire!

So, this is the moment you were waiting for. The hardest part is done. From now on, every time you want to update your application, you only have to run the following magical command. Capistrano will read your config/deploy.rb file and run each task. If a task fails, the deploy will stop and the old version will still be online.

$ cap deploy

You will see a bunch of text output and after little time (depending on your server) everything should be complete. That was easy, wasn’t it?


Further Thoughts

Security

Perhaps you might be a little worried with having to put your plain-text password in the configuration file. I only chose that way to make the demonstration as straight forward as possible, but in the real world, you might want to use an SSH key. You can import one like this:

set :user, "" # EDIT your ssh user name
set :use_sudo, false
set :ssh_options, {
	:forward_agent => true,
	:auth_methods => ["publickey"],
	:keys => ["/path/to/your/key.pem"] # EDIT your ssh key
}

Database

So far, we have focused on deploying the actual files to their new home, but in many scenarios you might also do something with your database. Laravel has a perfect tool for that: migrations. To run your migrations, you can just define an extra task. Let’s do so:

	task :laravel_migrate do
		transaction do
			run "#{current_release}/artisan migrate"
		end
	end

You also have to add this task in the transaction block of the update task. Now every time you deploy, the database will be updated to your latest migrations.

Rollback

Sometimes you deploy a non-working version of your application and you need to undo this changes. Capsitrano has a built-in feature for that called “rollback”. Just run:

cap deploy:rollback

Conclusion

You’ve just learned a very simple way of deploying your application to your production server(s) with capistrano. Once the configuration work is done, it just takes one command to deploy your latest version in seconds. But as mentioned earlier, this is not the only way to do this.

You should also checkout the taskrunner grunt which suits perfectly for building and deploying JavaScript applications. A complete different approach takes docker which acts like a lightweight VM. The idea here is to deploy your whole environment as a virtual machine. Check them out!

Source: Nettuts+

I've worked very hard for this, so please help me by donating a cup of coffee. Thanks in advance.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

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