I really like using Git and Capistrano to manage my personal projects. If you’re not familiar with Git, it’s a version control system that allows you to track versions of your project. Capistrano is a Ruby utility that allows you to deploy your project to a production server from your local machine with a single command, and easily roll back to a previous version if something goes wrong.
If you haven’t used Git before, don’t be put off by its reputation as difficult to learn. It’s not. And for a single-person project, using it is quite simple. To get started, visit the Gittutorial. The tutorial walks you through the basic steps of using Git to manage a project.
Capistrano is similarly straightforward. Originally written to deploy Rails projects, it is easily adapted for applications or websites written in other languages. For instructions on how to install Ruby and Capistrano, visit the Ruby Downloads page and the Capistrano getting started page.
For this post, I am assuming you already have Git and Capistrano installed on your local machine. Neither has to be installed on your server. (However, if, like me, you like to store your stuff in a remote git repository, you will need to install git out there too.) I am also assuming that your production server is running Apache, and that you have access to your Apache configuration file, httpd.conf. The instructions below should work for any *nix operating system.
Adding A Project to Git
From the root directory of a project, enter the following on the command line:
[joyce@LocalMachine newproject] $ git init
That tells Git to create a new repository for the project. If you do an ls -a on your root project directory, you should see a new folder, .git. Once you’ve created the repository, you add all of the project’s files to it:
[joyce@LocalMachine newproject] $ git add . [joyce@LocalMachine newproject] $ git commit -m "First commit"
Next, I like to create a repository out on my server to store my project, and to deploy my project from. I use ssh to get out to my server, then go to the directory where I keep all of my repositories. Once I’m there, I create a new directory for my new project, change into that directory, initialize an empty git repository and exit back to my local machine:
[joyce@MyServer ~] $ cd /opt/git [joyce@MyServer git] $ mkdir newproject.git && cd newproject.git [joyce@MyServer newproject.git] $ git --bare init [joyce@MyServer newproject.git] $ exit
Now I want to tell my local Git repository where the remote repository is and push the files from my local repository out to the remote one:
[joyce@LocalMachine newproject] $ remote add origin ssh://MyServer/opt/git/newproject.git [joyce@LocalMachine newproject] $ git push origin master
All done. Next I set up Capistrano.
Setting Up Capistrano
Capistrano does all of its work from your local machine. All you have to do is set up a deploy.rb file to describe your set up to Capistrano and give it any special instructions or tasks that you want it to complete as part of your deploy procedure. First you “capify” your project:
[joyce@LocalMachine newproject] $ capify .
Capify adds a config folder to the project’s root directory and puts a “deploy.rb” file inside it. It also adds a file called “Capfile” to the project’s root directory. Here is what a very simple deploy.rb that would work just fine to deploy a PHP application, such as WordPress, might look like:
#Required settings #Set application to the url of the project set :application, "myproject.com" #Set repository is the path to the Git repository to deploy from. Capistrano will ssh into the server, #so the user specified below must be able to ssh into the server set :repository, "MyServer.com:/opt/git/newproject.git" # #Roles #Roles are named sets of servers that you can target Capistrano tasks to execute against. role :web, "myproject.com" role :app, "myproject.com" # #Optional Settings #This allows Capistrano to prompt for passwords default_run_options[:pty] = true #The following lines tell Capistrano where to deploy the project set :deploy_to, "/PathToProjectfiles/myproject.com" # defaults to "/u/apps/#{application}" set :current_path, "#{deploy_to}/current" set :releases_path, "#{deploy_to}/releases/" set :shared_path, "#{deploy_to}/shared/" #This tells Capistrano that I'm using Git for versioning. set :scm, :git #This tells Capistrano that sudo access is not needed to deploy the project. set :use_sudo, false # #And here are the tasks required to deploy a simple project namespace:deploy do task:start do end task:stop do end task:finalize_update do run "chmod -R g+w #{release_path}" end task:restart do end after "deploy:restart" do #add any tasks in here that you want to run after the project is deployed run "rm -rf #{release_path}.git" end end
You might be wondering why I have tasks that don’t seem to be doing anything. If you recall, Capistrano was designed to deploy Rails applications. There are a number of steps involved in deploying a Rails app that are not required for a PHP app like WordPress. Those empty tasks in my deploy.rb are overwriting the default ones, which contain steps unneeded for my purposes. As an example, the default “finalize_update” task creates some directories and symlinks that I don’t need for my set up. So I simply overwrote the task in my deploy.rb file, including only the part of the task that I do want Capistrano to carry out.
Once the settings in deploy.rb are updated to reflect the new project, it’s time to let Capistrano set things up on the sever. From the command line, run:
[joyce@LocalMachine newproject] $ cap deploy:setup
Capistrano will go out to the server and set up the file structure in the directory you told it to deploy to. It’s a good idea to ssh out to your server to make sure the correct file structure is in place. In the deploy directory, you should see two new subdirectories, “releases” and “shared.” While you’re out there, you’ll want to update your “httpd.conf” file and set the document root to “/pathToYourProject/newproject.com/current.” Be sure to restart the service after you’ve updated the config file.
Back on your local machine, the project is ready to deploy. If everything has gone well, the following will deploy the new project:
[joyce@LocalMachine newproject] $ cap deploy
Everything we’ve done so far may seem like a lot of work. But you’ll find subsequent updates to the project simple and error-free. All you’ll need to do is commit your changes to your git repository, push the changes to your remote repository and deploy:
[joyce@LocalMachine newproject] $ git status #shows all of the files you've changed or updates since your last commit [joyce@LocalMachine newproject] $ git add updatedFile.php #add changed files & new files [joyce@LocalMachine newproject] $ git commit -m "committing my updates" [joyce@LocalMachine newproject] $ git push #push my updates to the remote repository [joyce@LocalMachine newproject] $ cap deploy
If something goes wrong and you want to go back to the previous release, simply:
[joyce@LocalMachine newproject] $ cap deploy:rollback
and Capistrano deletes the most recent release, rolling your app back to the previous release. Finally, Capistrano includes a handy cleanup feature, which deletes any releases older than the most recent five. To use it:
[joyce@LocalMachine newproject] $ cap deploy:cleanup
There’s a lot more that you can do with Git and Capistrano. Check out their websites for more information.
