This is the script I wrote to deploy all commits to the master branch on GitHub onto my shared hosting cPanel server for coebot.tv. Because my cPanel server doesn't allow exec() or shell_exec() from PHP, I had to get creative. I worked around this by SSHing into the local server and running the command that way.
I also took care to validate the secret that GitHub passes along to prevent anyone else from activating the webhook. This is something I notice a lot of the other variations of this script I've found via googling neglect to do, but it seems like a good idea so I went for it.
First, you need to put deploy.php on your server, somewhere where it's accessible to the public (I've only tested putting it right at /public_html/deploy.php
, but I can't think of any reason you couldn't rename it or put it in a subdirectory). At the top of the script is a series of define()
statements -- you will need to change most of these to suit your setup (they all have comments describing what they do).
Now, odds are, your web server is still configured to use your hosting provider's native version of PHP, and odds are that version won't include the ssh2 module that deploy.php requires. So, open cPanel, and go to "Select PHP Version" (it's under "Software and Services"). There will be a dropdown that will probably have "native (X.Y)" as the selected option (where "X.Y" is your PHP version number). Switch the dropdown to just "X.Y". It should give you a big list of modules with checkboxes. For this script, make sure you have the "ssh2" and "json" modules checked. Also be sure to include any modules that your project needs (This varies hugely depending on what your project is, but mcrypt, mysql, mysqli, http, mbstring, tidy, pdo are all pretty common ones. It's safer to accidentally enable ones you don't need than to leave out ones you do need.)
Now you'll need to generate a keypair so that your deploy.php script can SSH into the local server (it's silly, I know). First, SSH into the cPanel server (i.e. using PuTTY or whatever). Then, you'll need to generate a keypair named "deploy" with no passphrase, and then append the public half of the keypair to your authorized_keys file. Here's what your SSH session should basically look like (please use a better passphrase than "abc123"):
$ cd .ssh
$ ssh-keygen -t rsa -b 4096 -C "deploy"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/johndoe/.ssh/id_rsa): deploy
Enter passphrase (empty for no passphrase): abc123
Enter same passphrase again: abc123
Your identification has been saved in deploy.
Your public key has been saved in deploy.pub.
The key fingerprint is:
cd:48:4e:6d:69:9f:de:67:af:44:2d:d8:07:e4:e1:70 deploy
The key's randomart image is:
+--[ RSA 4096]----+
| . E |
| . . * . |
| o = + |
| + * . + o |
| S o + + o|
| . o o |
| . o o|
| . o.|
| ...|
+-----------------+
$ cat deploy.pub >> authorized_keys
You'll need to create a webhook in the settings for your repo on GitHub. Set the Payload URL to the URL of this script (i.e. "http://example.com/deploy.php"), set the Content type to "application/json", and set the Secret to the same string of random characters that you set GITHUB_SECRET to in deploy.php. Check the radio box for "Just the push event" and then save the webhook.
You also need to have already cloned your repository into ~/public_html
on the cPanel server. You can do this by manually SSHing in to the server from your local machine and running the git clone
command.
I think that covers it all? Tweet me @haydenschiff if you have any issues.
Hi @oxguy3 ,
I run into an issue that the git pull request wants the SSH passphrase. I tried echo-ing that passphrase after row 123 of the echo git pull, but that doesn't work. I do see the passphrase in the mail, but the script doesn't pick the passphrase. I also searched for saving the passphase into the webserver settings, but that is all in the SSH session; for my putty session that works, but the session dit deploy scripts start is from Github off course. Hope you can help!