Using Git to deploy PHP software - Part 1

Submitted by Kamal Wickramanayake on

Last time I wrote an article about Gitolite titled "Create and manage your own Git repositories with Gitolite". In this article, let us explore how to securely distribute and deploy PHP software using Git. Here we will use Gitolite but other Git repository management software may also be used with the technique mentioned below.

Given that PHP is an interpreted language where no compilation is involved, the code maintained in a Git repository may directly be deployed. One may just have to follow some best practices to organize the process to avoid troubles.

Let’s look at a simple scenario first. Let’s assume that there’s only one developer and one or more deployment servers. Given that there’s only one developer, that one developer with some effort can maintain stable code in the master branch of the Git repository. Assuming so, we can make the master branch code be available to the deployment servers easily.

How to go about doing this?

  1. Create a Git repository with the developer having say full read-write access. Let’s call it “testproject”.
  2. In the deployment servers, create SSH keys.
  3. Add the SSH keys of the deployment servers to the Gitolite admin repository.
  4. In the Gitolite configuration file, define users representing the deployment servers.
  5. For those users, grant read only access.

Here’s how the Gitolite admin repository content may be organized:

gitolite-admin/
├── conf
│   └── gitolite.conf
└── keydir
   ├── kamal.pub
   ├── testproject-server1.pub
   └── testproject-server2.pub

Here’s how the Gitolite configuration file content may look like:

@testproject_servers = testproject-server1 testproject-server2

repo gitolite-admin
   RW+     =   kamal

repo testproject
   RW+     =   kamal
   R       =   @testproject_servers

Now the Git configuration is over. How to go about using the setup?

Let’s assume that the deployment servers follow a specific directory structure where the PHP code inside /home/hostingaccount/public_web is served by PHP. Here I am assuming that /home/hostingaccount is the home directory of a user account named "hostingaccount" in a deployment server.

In the developer’s machine:

  1. Clone the testproject git repository.

    git clone git@git.software.lk/testproject
  2. Inside the cloned directory, create the directories and other content as per the structure needed at the deployment servers. For example, the content may be organized as follows:

    testproject/
    ├── bin
    │   └── update.sh
    ├── public_web
    │   ├── index.php
    │   └── other.php
    └── README
  3. Push the new content to the remote testproject Git repository.

In a deployment server, as the “hostingaccount” user, clone the testproject Git repository to the home directory:

hostingaccount@server1$ cd ~
hostingaccount@server1$ git clone git@git.software.lk/testproject .

Now if the developer makes changes and pushes changes to the remote Git repository called testproject, to get the updated code available at a deployment server, only a "git pull" command is needed there.

There are many instances where code update is not just sufficient but other changes like database updates need to run too with code updates. One may use a command like bin/update.sh as shown in the directory structure earlier with some best practices to get such tasks to execute with code updates.

In the developer machine, it is more convenient if the local working copy of the Git repository can be maintained in a directory like /home/hostingaccount similar to where the code is maintained in the deployment servers and configure the developer's machine to serve PHP content from say /home/hostingaccount/public_web directory. This way, the developer can make changes, test locally and push the changes available inside that same directory to the remote Git repository.

The approach discussed in this article is simple and easy but is not ideal when there are many developers or multiple versions of the software are required to be maintained. In part 2 of the article, we will explore how Git branches can be used to maintain the stable releases and use Git to sync specific stable release branches to the deployment servers.