Deploying websites with Git (and Composer)
I have been using Git to deploy my websites for quite some time now. It is so much easier than having to drag 'n drop files with FTP or SFTP. When I switched to Laravel 4 earlier this year, I updated the script to automatically update composer packages.
To deploy a website using Git you basically have to set up 2 repositories; one on your workstation and one on the webserver with the actual live "production" code. You push changes from your workstation to the "production" repository, where a Git post-receive hook will update the live code.
Start by initialising a non-bare Git repository in your website's directory:
> cd /var/www/website > git init Initialized empty Git repository in /var/www/website/.git/
After this we need a post-receive hook that will make sure that any time anything is pushed to the repository, the live code is updated. These hooks are custom scripts that are executed when certain important events occur, and are located in the
.git/hooks directory. In this case we need to create the
.git/hooks/post-receive hook with the following content:
#!/bin/bash # Update the working tree after changes have been pushed here cd .. env -i git checkout -f # Check if a composer.json file is present if [ -f composer.json ]; then # Install or update packages specified in the lock file composer install fi
The first lines update the live code with the changes that are pushed, and the part below checks if a
composer.json file is present. The
composer install command will install or update your packages with the versions specified in the composer.lock file, so make sure this file is not in your .gitignore file. This way, your remote host will always have the same package versions as your workstation. For more information about this lock file, and why it should not be in your .gitignore file check: getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file.
Ensure the hook is executable:
> chmod +x .git/hooks/post-receive
To be able to push to a non-bare repository you need to execute the following command:
> git config receive.denyCurrentBranch ignore
The only thing that is left is to add the correct remote to the website's repository on your workstation:
> git remote add production ssh://email@example.com/var/www/website
To test if everything is working, modify something and push it to the newly created production remote:
> touch test > git add test > git commit -m "Testing deployment" > git push production master Counting objects: 3, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (2/2), 268 bytes, done. Total 2 (delta 1), reused 0 (delta 0) remote: Composer up to date To ssh://firstname.lastname@example.org/var/www/website cf43bc5..96f33d8 master -> master