Using GIT to remotely deploy a PHP project to production

Here is my tried and tested method for setting up GIT to allow pushing from a local repository to production. Note: this is not a post about whether GIT should even be used as a deployment tool so I would recommend you research the pros and cons before selecting any solution.

Be aware of the following:

  1. The .git/ repository will exist in the root of the web directory – ensure that your web server is correctly configured so as not to expose it.
  2. The composer.lock file should exist in the root of your project structure. If not, adjust the composer install command in the post-receive script below.

On Local Development PC (wherever your GIT repository is cloned to):


# Get the ssh key (If no key run ssh-keygen to generate one and then repeat cat command)
cat ~/.ssh/id_rsa.pub
#> ssh-rsa ABC...

On Remote Production Server:


# Setup the remote bare GIT repository which we will push to
sudo su {$USERNAME}
cd ~/web/
git init --bare .git
# Add a post-receive hook to checkout and update composer dependencies
touch  .git/hooks/post-receive
chmod +x .git/hooks/post-receive
nano .git/hooks/post-receive


#!/bin/bash
echo "Checkout master"
`GIT_WORK_TREE=../ git checkout -f master`
echo "Updating Composer packages"
composer install --no-dev --no-interaction -d ../


# Setup the SSH key from the local PC to authenticate with
mkdir ~/.ssh
nano ~/.ssh/authorized_keys
# paste in id_rsa key from your development PC
chmod go-w ~/ ~/.ssh ~/.ssh/authorized_keys

Back On Local Development PC:


ssh {$USERNAME}@{$IP ADDRESS}
# Last login: Sat Jan  4 12:13:10 2020...
exit
git remote add production {$USERNAME}@{$IP ADDRESS}:~/web/.git
# Pushing the latest commit is now as simple as running:
git push production master


Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 353 bytes | 353.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Checkout master
remote: Already on 'master'
remote: Updating Composer packages
remote: Loading composer repositories with package information
remote: Installing dependencies from lock file
remote: Nothing to install or update
remote: Generating autoload files
To xxx.xxx.xxx.xxx:~/web/.git
   e971254..28cb581  master -> master

Bonus Feature: Rollback to a specific commit (e.g. something has gone very wrong...)


# Find the commit hash of the commit you want to restore to
git push production +${COMMIT HASH}:master 

Load Comments...