Simple and automatic Github deployment using PHP
If you’re like me, every project you work on worth anything gets put in GitHub. It’s safe and you get all the benefits of using Git. Of course those benefits include deployment hooks, if you’ve got the system setup for it. On small projects it may seem like it’s more hassle to setup deployment hooks, after all SFTP is simple enough, however it’s actually quite easy to do and only take a few minutes to setup. My use case is JonDavis.name (which is kept in a private GitHub repo) and this has made life much easier for me, even for a single-page website.
- ssh to your server & navigate to your website folders
sudo mkdir /var/www/.ssh
sudo chown -R www-data:www-data /var/www/.ssh/
sudo echo "deny from all" > /var/www/.ssh/.htaccess/
sudo -Hu www-data ssh-keygen -t rsa# choose “no passphrase”
sudo cat /var/www/.ssh/id_rsa.pub
unzip master.zip && rm master.zip
mv deploy-config.example.php deploy-config.php
nano deploy-config.php(or your editor of choice)
define('SECRET_ACCESS_TOKEN',— to something more secure, perhaps use a strong password generator
define('REMOTE_REPOSITORY',— You must use the SSH url if its a private repository
- Save & Exit
- Go to your repository on GitHub
- Settings > Deploy Keys
- Copy & paste the output from id_rsa.pub above
- Do _not_ allow write access.
- Add Key
- Go to Webhooks & Services
- Add Webhook
- Payload URL: https://YOURDOMAIN.TLD/simple-php-git-deploy-master/deploy.php?sat=YOUR_SECRET_ACCESS_TOKEN
- Content Type & Secret don’t matter (can be left blank)
- Select “Just the push”
- Add Webhook
- At this point GitHub should test your webhook and if all was setup correctly, your most recent commit will be deployed onto your server.
- Before you’re done… verify that your http://serverip/.ssh/ is not accessible.
- Commit more code!
One of the important security items that I want to highlight and re-highlight is that you’re using the apache process (www-data or apache) with SSH outbound (inbound is generally disabled, so that’s not an issue). However Apache’s home directory (/var/www) is publicly accessible/readable by default, including ~/.ssh/. You need to make sure no one can read those keys (or theoretically they could go fetch your private codebase). You may need to change the Apache configs (/etc/apache2/sites-enabled/000-default.conf) to allow the “Deny from all” statement to work.
Beyond this small piece of securing your code, you’re good to go! It’s really easy to do your dev work locally, commit, and watch the changes show up in production a minute later. Since I use my portfolio site to learn new web technologies, it’s been really handy to be able to quickly iterate. So go out there and code!