Configure GitHub Webhooks with a Web Server
We’ve all faced it! After pushing many updates to GitHub, you realize that you haven’t pulled from the git server onto your web server. Soon, you cannot see your updates on the web server. So, how do you solve this problem? How do you make the git server sync with your web server?
What are Webhooks?
Webhooks are “user-defined HTTP callbacks”. They are usually triggered by some event, such as pushing code to a repository or a comment being posted to a blog. When that event occurs, the source site makes an HTTP request to the URL configured for the webhook. Users can configure them to cause events on one site to invoke behaviour on another. The action taken may be anything.
If you didn’t understand a word of that definition, webhooks are HTTP callbacks that do some action when an event is triggered. In this case, we will be configuring the webhook to execute a pull command from the shell when a push event is made to the git server.
Creating a Webhook
Now that we understand the functioning of webhooks, let’s create our first webhook!
Note- Although I have added the bitbucket logo on the cover image, I haven’t tried it out on a BitBucket repository. There shouldn’t be much of a difference while configuring bitbucket webhooks. Nevertheless, hit me up in the comments section if you run into problems!
Log on to github.com and push some code into your repository. Go to Settings->Webhooks->Add webhook
What do these fields represent?
Payload URL- This is the URL the webhook will ping when an event is completed on the GIT server.
Content Type- We aren’t going to worry about this because we aren’t going to configure the webhook with a secret as the verification process is time-consuming.
Secret- Again, I’m not going to configure the webhook with a secret as the verification process is time-consuming. However, I have a way to work around this problem.
SSL Verification (Secure Socket Layer)- If your payload URL has an SSL certificate (https://domain.tld), then you will have an option to enable SSL verification which will encrypt all the connections. Else, if your payload URL does not have an SSL certificate (http://domain.tld), then you will not see the option.
Events- Define when the webhook should be triggered.
Active- Leave the box checked (Recommended). If you want to disable the webhook (NOT RECOMMENDED), then uncheck the box.
More information on the official website here.
We have configured the webhook!
Fixing User Errors on Ubuntu
Note- I have only faced this error on Ubuntu as the OS has predefined users on setup; furthermore, the root user isn’t the user performing operations for an Apache/Nginx Server on Ubuntu.
Figuring out the user performing operations on the web server
To do this, create a .php file in your public directory and add the following code.
Visit the page using a browser and see the output. The output displays the web server’s user that is performing the operations on the web server.
If you’re using Ubuntu 18.04 LTS, the user will most probably be “www-data”. I will use “www-data” as the user throughout this tutorial.
Generating SSH keys for the GitHub Repository (Only for Private Repositories)
Note- Skip the following steps till the next breakpoint if you are not using a Private Repository.
While pulling from the GitHub repository, you cannot use the HTTPS method if you are using a private repository. Moreover, you will have to use the SSH method as it only requires the SSH key for authentication while pulling from the repository.
To use the SSH method, we have to generate an SSH key with the web server’s user “www-data” (in your case this might be a different user). Run this command:
$ sudo -Hu www-data ssh-keygen -t rsa
“-Hu www-data” part is running the command as the “www-data” user in this case.
Save the SSH key in the default folder and DO NOT SET A PASSPHRASE.
Note: If you get a “Permissions Error”, then you will have to grant access to www-data to access the /var/www/ directory. To do this, run the following command
$ sudo chown www-data:www-data /var/www/
Note- If you get an error which says that the folder does not exist, then you might have to manually create the folder by running the following command.
$ sudo mkdir /var/www/.ssh/
Adding our SSH key to GitHub
Once you’ve created the SSH key, got to the /var/www/.ssh/ folder by using the following command
$ cd /var/www/.ssh/
Copy the SSH key from here from the output of the following command (Assuming your key is called id_rsa)
$ cat id_rsa.pub
In the GitHub repository, go to Settings->Deploy Keys->Add Deploy Key.
What do these fields represent?
Title- Key’s name (Name it anything you want)
Key- Paste the key you copied in the previous step
Allow write access- Since we’re just going to be pulling from the repository, we do not need write access. However, if you want to push to the repository, then you need to “Allow write access”.
More information about adding deploy keys here.
Configuring the payload URL
Create a new file called “webhooks-file-name.php” (Same name as entered while creating the webhook)
Add the following code to the file
echo shell_exec('git pull');
Congratulations! You have successfully configured a webhook with GitHub!
Now push code to your GitHub repository and watch the magic happen!
Adding security to hide the payload URL from the public (OPTIONAL)
Remember when I said that I had a way to work around not adding a “Secret” to the webhook. The solution is to pass arguments through the URL and verify them. The URL could be something like this
Let’s verify that the arguments. Add the following code to the webhooks-file-name.php file
Now the webhook has been configured with some form of security!
Officially published at snpranav.com