Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

GitHub PHP webhook to auto-pull on repo push

View github_post_recieve.php
1 2 3 4 5 6 7 8 9
<?php
// Use in the "Post-Receive URLs" section of your GitHub repo.
if ( $_POST['payload'] ) {
shell_exec( 'cd /srv/www/git-repo/ && git reset --hard HEAD && git pull' );
}
?>hi
Owner

This seems to be the bare minimum required to get a GitHub post-receive hook up and running with PHP on a webserver, to facilitate automatic site updates with group collaboration on a small static site.

I had to create a private/public key pair, without passphrase. The public key gets added in GitHub as a "deploy key" while the private key gets saved as /var/www/.ssh/id_rsa. I also did sudo touch /var/www/.ssh/known_hosts && sudo chmod www-data /var/www/.ssh/known_hosts, then ran sudo -u www-data git pull from the command line to update the known_hosts file.

(I think that's it)

Have any improvements? Let me know!

tried every which way and couldn't get this to work. script executed just fine from the command line using php script.php, but wouldn't work using service hooks. Oh well..

@sudo chmod www-data /var/www/.ssh/known_hosts" should be sudo chown www-data /var/www/.ssh/known_hosts.

Also make sure www-data have access to the files in /var/www/.ssh

The permission instructions were very helpfull, but the script doesn't work, so I made one that does:
https://gist.github.com/3915531

Here is a similar project with a bit more advanced options: https://github.com/Coppertino/github-webhook.

I used suPHP to make the php webhook handler execute under my user instead of web server, hence no permissions problems and file ownership changes on pull. May sound scary but if the shell command is hard coded and suPHP is enabled only for that particular script (I can put it in a separate directory) it's pretty safe (feel free to call me out if that's still very bad %))

@jorijnsmit Interesting, a different approach to the problem! Thanks for sharing.

I'm concerned about git reset --hard HEAD... is it safe to do so? What if some tracked files are (accidentally) edited on a running server? This shouldn't happen, of course, but if it does, I think I'd rather have the change NOT propagate to the server instead of overwriting something.

just a little typo error.. it's receive not recieve.

@webjay It works, you just need to generate the web server's ssh keys. I've merged your security code with this gist and the ssh keys: https://gist.github.com/phedoreanu/11321236.

Note that your repo SHOULD NOT include files that are changed on server. Maybe /uploads folder or app/logs or anything. git reset --hard HEAD will delete everything. Put such files and folders in your .gitignore.

Just an fyi: I had to change the following before it would work:

if ( $_POST['payload'] ) {

to

if ($_SERVER['HTTP_X_GITHUB_EVENT'] == 'push') {

also, as usually shell_exec is run from the user www-data I had to change permissions by executing the following command inside /var/www/html

sudo chown www-data:www-data -R my-repo/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.