{"id":29420017,"url":"https://github.com/allebb/hooker","last_synced_at":"2026-05-16T21:01:36.958Z","repository":{"id":41215837,"uuid":"48858408","full_name":"allebb/hooker","owner":"allebb","description":"Hooker is a lightweight PHP web application that can be used to trigger remote workflows (such as automated deployments) on your Linux or UNIX based servers.","archived":false,"fork":false,"pushed_at":"2021-01-25T12:06:19.000Z","size":153,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-03-17T20:40:24.560Z","etag":null,"topics":["cicd","deployment","nginx","php","trigger-deployments","virtualhost","webhooks"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/allebb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-31T18:17:12.000Z","updated_at":"2022-12-25T03:12:59.000Z","dependencies_parsed_at":"2022-08-27T07:50:38.056Z","dependency_job_id":null,"html_url":"https://github.com/allebb/hooker","commit_stats":null,"previous_names":[],"tags_count":null,"template":null,"template_full_name":null,"purl":"pkg:github/allebb/hooker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allebb%2Fhooker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allebb%2Fhooker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allebb%2Fhooker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allebb%2Fhooker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/allebb","download_url":"https://codeload.github.com/allebb/hooker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/allebb%2Fhooker/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264922929,"owners_count":23683707,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cicd","deployment","nginx","php","trigger-deployments","virtualhost","webhooks"],"created_at":"2025-07-12T01:15:20.352Z","updated_at":"2026-05-16T21:01:36.874Z","avatar_url":"https://github.com/allebb.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hooker\n\nHooker is a lightweight PHP web application that can be used to trigger remote workflows on your Linux or UNIX based\nservers. It is fully self-contained by design (a single script), it doesn't have any external dependencies and does not require any package managers such as Composer making it perfect for inclusion into legacy projects too.\n\nIt has specifically been designed to simplify and automate application deployments using Git or Docker containers when\nyou don't want or need the complexity of a full CI/CD setup, but you can easily use it for a ton of other really useful\ntasks.\n\n## Requirements\n\n* A web server (the installation guide uses Nginx)\n* PHP 5.4+\n* The ``shell_exec()`` function is required (Some shared hosting environments disable this!)\n\n## License\n\nThis script is released under the [GPLv2](https://github.com/allebb/hooker/blob/master/LICENSE) license. Feel free to\nuse it, fork it, improve it and contribute by open a pull-request!\n\n## Installation\n\nIt is recommended to set-up a new virtual host configuration on your web server of which then acts as a web-hook endpoint for\nmultiple configured projects.\n\nYou should create separate site configurations that then get triggered by specifying the site/application configuration\nwith the ``app`` parameter eg. ``https://deploy.mysite.com/hooker.php?app=website1``.\n\n**If you have set up your server using [Conductor](https://github.com/allebb/conductor) you can automatically install Hooker by running this simple command:**\n\n```shell\nbash -c \"$(curl -fsSL https://raw.githubusercontent.com/allebb/hooker/stable/utils/auto-install-conductor.sh)\"\n```\n\n\u003e Hooker is fully self-contained in a single script (it doesn't have any external dependency and therefore doesn't't require the need to pull dependencies from Composer or ``include`` a ton of external scripts) so if you wish to include this single script into an existing project simple copy the ``hooker.php`` file and update the default values within this file to your needs.\n\n#### Creating the new virtualhost directory\n\nIn this example, we'll create a new Nginx vhost configuration on an Ubuntu Linux server and use the default ``www-data`` user (for simplicity and demonstration purposes).\n\nFirst we need to create a hosting directory to host our ``hooker.php`` file:\n\n```shell\nsudo -u www-data mkdir /var/www/hooker\n```\n\nWe will now create a cache directory for Composer, this will speed up package installs (if you intend to use it):\n\n```shell\nsudo mkdir /var/www/.cache\nsudo chown -R www-data:www-data /var/www/.cache\n```\n\nWe'll use Git to download the latest (stable) version (we'll also be able to use ``sudo -u www-data git pull`` in future\nto apply updates):\n\n```shell\ncd /var/www/hooker    \nsudo -u www-data git clone https://github.com/allebb/hooker.git .\nsudo -u www-data git checkout stable\n```\n\nWe'll now copy the example configuration file and use that to configure our individual sites:\n\n```shell\nsudo -u www-data cp hooker.conf.example.php hooker.conf.php\n``` \n\nAt this point you should edit this file and configure your sites, for example it may look like this:\n\n``/var/www/hooker/hooker.conf.php``\n\n```php\n/**\n * Hooker Configuration File\n */\nreturn [\n\n    // Enable output of debugging information.\n    'debug' =\u003e true,\n\n    // Need to customise the default Git path?\n    // 'git_bin' =\u003e '/usr/bin/git',\n\n    // Need to customise the default PHP version used for running Composer and other PHP specific tasks?\n    // ** This path can also be overridden by individual sites/applications as required in the sites array below. **\n    //'php_bin' =\u003e '/usr/bin/php7.4',\n\n    // Need to customise the default Composer path?\n    // ** This path can also be overridden by individual sites/applications as required in the sites array below. **\n    //'composer_bin' =\u003e '/usr/bin/composer',\n\n    // By default we'll allow any server(s) to \"hit\" these deployment hooks but you can add specific IP addresses\n    // to the whitelist if you wish...\n    'ip_whitelist' =\u003e [],\n\n    'sites' =\u003e [\n\n        // An example basic HTML website (Webhook example: http://deploy.mysite.com/hooker.php?app=my_basic_website\u0026key=SomeRandomWordThatMustBePresentInTheKeyParam).\n        'my_example_website' =\u003e [\n            'debug' =\u003e false, // Override and disable the output of debug info for this specific deployment workflow?\n            'key' =\u003e 'SomeRandomStringThatMustBePresentInTheKeyParam',\n            'local_repo' =\u003e '/var/www/html-website', // Use current directory\n            'is_github' =\u003e true, // Using GitHub webhooks to trigger this workflow.\n            'branch' =\u003e 'deploy-prod', // As long as the GitHub webhook request relates to changes on this git branch, we'll run the deployment workflow!\n            //'pre_commands' =\u003e [\n            //    // Uses the default (inherited deployment commands)\n            //],\n            //'deploy_commands' =\u003e [\n            //    // Uses the default (inherited deployment commands eg. cd {{local-repo}} \u0026\u0026 {{git-bin}} reset --hard HEAD \u0026\u0026 {{git-ssh-key}}{{git-bin}} pull)\n            //],\n            //'post_commands' =\u003e [\n            //    // Uses the default (inherited deployment commands)\n            //],\n        ],\n\n        // An example Laravel Deployment Configuration (Webhook example: http://deploy.mysite.com/hooker.php?app=my_other_website\u0026key=32c9f55eea8526374731acca13c81aca)\n        'my_other_website' =\u003e [\n            'key' =\u003e '32c9f55eea8526374731acca13c81aca',\n            'local_repo' =\u003e '@conductor', // This will auto-resolve to /var/conductor/applications/my_other_website\n            'git_ssh_key_path' =\u003e '@conductor', // Optional - This will auto-resolve and use the Conductor generated private (deployment) key at /var/www/.ssh/my_other_website.deploykey\n            'user' =\u003e false,\n            'php_bin' =\u003e '/usr/bin/php8.0',\n            // Override the \"default\" PHP version used for this deployment/running Composer, this application needs PHP 8.0!\n            //'composer_bin' =\u003e '/usr/bin/composer', // Need to override with a different Composer version?\n            'pre_commands' =\u003e [\n                '{{php-bin}} {{local-repo}}/artisan down', // Example of a pre-command to set our Laravel application into \"maintenance mode\".\n                '{{php-bin}} {{local-repo}}/artisan config:clear', // We'll also clear the configuration cache before we pull the latest code from Git..\n            ],\n            //'deploy_commands' =\u003e [\n            //    // Uses the default (inherited deployment command eg. cd {{local-repo}} \u0026\u0026 {{git-bin}} reset --hard HEAD \u0026\u0026 {{git-bin}} pull)\n            //    // You can of course run other tasks here too, shell scripts, npm, nodejs etc. etc.\n            //],\n            'post_commands' =\u003e [\n                'cd {{local-repo}} \u0026\u0026 {{php-bin}} {{composer-bin}} install --no-dev --no-progress --prefer-dist --optimize-autoloader',\n                'chmod 755 {{local-repo}}/storage',\n                '{{php-bin}} {{local-repo}}/artisan migrate --force',\n                '{{php-bin}} {{local-repo}}/artisan config:cache',\n                '{{php-bin}} {{local-repo}}/artisan cache:clear',\n                '{{php-bin}} {{local-repo}}/artisan route:cache',\n                '{{php-bin}} {{local-repo}}/artisan up',\n                //'{{php-bin}} {{local-repo}}/artisan queue:restart', // Using a job queue? Restart it so it uses the latest version of your code!\n                //'{{php-bin}} {{local-repo}}/artisan horizon:terminate', // Using Horizon for your queues instead??\n            ],\n        ],\n        \n        // An example Laravel Deployment Configuration using a local \".hooker.json\" repository configuration. (Webhook example: http://deploy.mysite.com/hooker.php?app=another_application\u0026key=VgUjbEIPbOCpiRQa2UHjqiXcmbE8eIht)\n        'another_application' =\u003e [\n            'key' =\u003e 'VgUjbEIPbOCpiRQa2UHjqiXcmbE8eIht',\n            'local_repo' =\u003e '/var/www/another_application',\n            'git_ssh_key_path' =\u003e '/var/www/.ssh/id_rsa', // Optional - We can set a private (deployment key) that will be used when git makes requests.\n            'use_json' =\u003e 'true', // This will read the configuration from a .hooker.json file stored in your git repo. eg. /var/www/another_application/.hooker.json\n        ],\n\n\n    ],\n];\n```\n\n### Create an SSH keypair for the www-data user\n\n**This section is optional and only required if you need to pull from private repositories and don't wish to generate deployment keys on an application by application basis (using ``conductor genkey {app_name}`` or manually).**\n\nLet's change into the ``www-data`` user's home directory:\n\n```shell\ncd /var/www\n```\n\nWe will now create a new ``.ssh`` directory (profile) for the 'www-data' user (as it is this user account that will be,\nbehind the scenes connecting to Git) and set the required permissions.\n\n```shell\nmkdir .ssh\nchown www-data:www-data -R .ssh\nchmod 0700 .ssh\n```\n\nNow we'll generate a new SSH key-pair for the ``www-data`` user of which will be used to authenticate with your Git\nhosting service.\n\n__In order to enable headless operation ensure that you use the default options (just keep pressing the ENTER key at the\nprompts) and when asked to enter a passphrase ensure that you leave it empty otherwise Hooker will not work correctly!__\n\n```shell\nsudo -u www-data ssh-keygen -t rsa -b 4096\n```\n\nThe contents of the public key (``/var/www/.ssh/id_rsa.pub``) now needs to be copied and added to your Git hosting\nprovider's SSH keys section:\n\n```shell\ncat /var/www/.ssh/id_rsa.pub\n```\n\n### Set correct permissions on the site directory\n\nNow, we need to set the correct ownership and permissions for this new site:\n\n```shell\nchown www-data:www-data -R /var/www/hooker\n```\n\n### Configure Nginx virtualhost configuration\n\nThis example Nginx virtualhost configuration can be added to your server - assuming you're using Nginx and PHP7.0-FPM (\njust make adjustments as required):\n\n``/etc/nginx/sites-available/hooker.conf``\n\n```\nserver {\n    listen 80;\n\n    # Wish to secure and host your deployment web service over HTTPS using a LetsEncrypt SSL certificate?\n    #listen          443 ssl;\n    #ssl_certificate /etc/letsencrypt/live/{your_certificcate_name}/fullchain.pem;\n    #ssl_certificate_key /etc/letsencrypt/live/{your_certificcate_name}/privkey.pem;\n    #ssl_trusted_certificate /etc/letsencrypt/live/{your_certificcate_name}/chain.pem;\n\n    # Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html\n    #ssl_protocols TLSv1.2 TLSv1.3;\n    #ssl_ciphers 'ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384';\n    #ssl_prefer_server_ciphers on;\n    #ssl_session_cache shared:SSL:10m;\n\n    root /var/www/hooker;\n    server_name {your_domain};\n\n    location / {\n        try_files $uri $uri/ /index.php?$query_string;\n    }\n\n    location ~ \\.php$ {\n        try_files $uri /index.php =404;\n        fastcgi_split_path_info ^(.+\\.php)(/.+)$;\n        fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;\n        fastcgi_index index.php;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n        include fastcgi_params;\n    }\n}\n```\n\nOnce created, you will need to symlink it to the ``/etc/nginx/sites-enabled`` directory like so:\n\n```shell\ncd /etc/nginx/sites-enabled\nln -s ../sites-available/hooker.conf .\n```\n\nNow restart Nginx for the new virtualhost configuration to take effect:\n\n```shell\nsudo service nginx restart\n```\n\n### Finished!\n\nIf all goes well, you should be able to access the 'ping' test page at: ``http://deploy.mysite.com/hooker.php?ping``, a\nsuccessful installation should return the word 'PONG'.\n\n## Updating\n\nTo update the version of Hooker simple run the following command(s):\n\n```shell\ncd /var/www/hooker\nsudo -u www-data git pull\n```\n\n**Remember to check and update your server's ``hooker.conf.php`` and if you are using them in your code repositories, your local ``.hooker.json`` files with any new configuration\noptions, an overview of the \"Configuration options\" can be found in the next section.**\n\n## Configuration options\n\nA full list and explanation of the configuration items and workflow \"placeholders\" tags can be found in\nthe [Configuration Items](docs/CONFIGURATION-ITEMS.md) file.\n\n## Using a .hooker.json configuration file in your codebase\n\nInstead of having to edit and update the ``hooker.conf.php`` on the server each time you wish to make a change to the deployment\nworkflow, a ``.hooker.json`` file can be committed to your Git repository and will be used to define the workflow steps,\nthe syntax is as follows:\n\n**This example demonstrates the deployment of a Laravel web application**\n\n```json\n{\n  \"debug\": true,\n  \"php_bin\": \"/usr/bin/php8.0\",\n  \"composer_bin\": \"/usr/bin/composer\",\n  \"pre_commands\": [\n    \"{{php-bin}} {{local-repo}}/artisan down\",\n    \"{{php-bin}} {{local-repo}}/artisan config:clear\"\n  ],\n  \"#deploy_commands\": [],\n  \"post_commands\": [\n    \"cd {{local-repo}} \u0026\u0026 {{php-bin}} {{composer-bin}} install --no-dev --no-progress --prefer-dist --optimize-autoloader\",\n    \"chmod 755 {{local-repo}}/storage\",\n    \"{{php-bin}} {{local-repo}}/artisan migrate --force\",\n    \"{{php-bin}} {{local-repo}}/artisan config:cache\",\n    \"{{php-bin}} {{local-repo}}/artisan cache:clear\",\n    \"{{php-bin}} {{local-repo}}/artisan route:cache\",\n    \"{{php-bin}} {{local-repo}}/artisan view:cache\",\n    \"{{php-bin}} {{local-repo}}/artisan up\"\n  ]\n}\n```\n\n**Notice in the above JSON file example that the ``deploy_commands`` JSON key has been commented out (with a hash), this\nis important as an empty array here will override the default ``git pull`` commands, only uncomment this if you need to\ndo custom tasks/customise the git pull command here.**\n\n**Keep in mind that the Hooker webservice will first check that a local ``.hooker.json`` file exists and then uses the\nworkflow steps within it, so you would have to effectively \"hit\" this endpoint twice for any ``.hooker.json`` changes to\ntake effect as the first time it's run, it will load the local file which in turn would then pull the latest changes\nfrom your repository and only then, on the next execution will it use the latest workflow instructions.**\n\n**For this to work, your Hooker configuration file MUST specify the ``local_repo`` and ``key`` properties\nin addition, the ``use_json`` property must also be set to ``true``.**\n\nFor security  reasons, when using a ``.hooker.json`` file some overrides are not available and will need to be set in the\nmain Hooker web service configuration file (``hooker.conf.php``). These settings are: ``remote_repo``, ``branch``\n, ``local_repo``, ``key``, ``disable_init`` and ``user``.\n\n## Configuring Services to use Hooker\n\nGenerally you would simply use the webhook URL in your CI/CD environment which will then make a request to the endpoint\nand resulting in the deployment of your application/website on your server but for smaller projects where you don't need\nthe complexity or overhead of full CI/CD environments you can instead use some of these services below to quickly and\neasily set up a fully automated deployment environment.\n\nThe following examples shows how to set up webhooks to trigger deployments from a couple of the most used Git hosting\nservices.\n\n### Configuring Hooker with GitHub Webhooks\n\nGetting your sites and web applications to deploy using GitHub web hooks is super easy - You can very easily (and\nquickly) have your code automatically deployed to your server (or group of servers) by simply adding a GitHub web hook.\n\nWhen I've needed setup quick and simple automated deployments, I'll create a separate Git branch called \"deploy-prod\" (\nor \"deploy-test\") and then set up a GitHub webhook to trigger these deployments using Hooker.\n\nIf you wish to use this simple method for having your sites or applications automatically deploy ensure that you set up\nthe GitHub webhook as follows:\n\nIn your ``hooker.conf.php`` file make sure that you have these (``is_github`` and ``branch``) settings:\n\n```text\n'sites' =\u003e [\n    'my-example-webapp' =\u003e [\n        ...\n        'key' =\u003e 'MyRandomDeploymentKey',\n        'remote_repo' =\u003e 'git@github.com:allebb/example.git',\n        'is_github' =\u003e true, // Using GitHub webhooks to trigger this workflow.\n        'branch' =\u003e 'deploy-prod', // As long as the GitHub webhook request relates to changes on this git branch, we'll run the deployment workflow!\n        ...\n    ],\n]\n```\n\nYou should then configure your GitHub web hook to send the payload to your hooker deployment URL, in our example this\nwould be ``http://deploy.mysite.com/hooker.php?app=my-example-webapp\u0026key=MyRandomDeploymentKey`` and ensure that you\nspecify the **Content type** as ``application/json`` as shown here:\n\n![GitHub web hook configuration](https://blog.bobbyallen.me/wp-content/uploads/2021/01/Screenshot-2021-01-14-at-18.48.14.png \"Example GitHub webhook configuration.\")\n\nWhen you push to the configured branch, GitHub will trigger a deployment to our server using this web hook URL. You can\nview the output of the deployment process from this screen too as long as you have the ``debug`` option set\nto ``true`` in your Hooker configuration you will be able to see the output (result) of each of your workflow/deployment\nsteps.\n\n### Configuring Hooker with BitBucket Webhooks\n\nAs per the GitHub section above (see for context), you can also enable your configuration to receive standard webhooks from BitBucket.\n\nYou should configure your BitBucket webhook like so:\n\n![BitBucket web hook configuration](https://blog.bobbyallen.me/wp-content/uploads/2021/01/Screenshot-2021-01-25-at-11.58.12.png \"Example BitBucket webhook configuration.\")\n\nEnabling BitBucket support is as simple as setting your site configuration to match this example:\n\n```text\n'sites' =\u003e [\n    'my-example-webapp' =\u003e [\n        ...\n        'key' =\u003e 'MyRandomDeploymentKey',\n        'remote_repo' =\u003e 'git@bitbucket.org:allebb/example.git',\n        'is_bitbucket' =\u003e true, // Using BitBucket webhooks to trigger this workflow.\n        'branch' =\u003e 'deploy-prod', // As long as the BitBucket webhook request relates to changes on this git branch, we'll run the deployment workflow!\n        ...\n    ],\n]\n```\n\n### Configuring Hooker with GitLab Webhooks\n\nAs per the GitHub section above (see for context), you can also enable your configuration to receive standard webhooks from GitLab.\n\nYou should configure your GitLab webhook like so:\n\n![GitLab web hook configuration](https://blog.bobbyallen.me/wp-content/uploads/2021/01/Screenshot-2021-01-25-at-11.56.06.png \"Example GitLab webhook configuration.\")\n\nEnabling GitLab support is as simple as setting your site configuration to match this example:\n\n```text\n'sites' =\u003e [\n    'my-example-webapp' =\u003e [\n        ...\n        'key' =\u003e 'MyRandomDeploymentKey',\n        'remote_repo' =\u003e 'git@gitlab.com:allebb/example.git',\n        'is_gitlab' =\u003e true, // Using GitLab webhooks to trigger this workflow.\n        'branch' =\u003e 'deploy-prod', // As long as the GitLab webhook request relates to changes on this git branch, we'll run the deployment workflow!\n        ...\n    ],\n]\n```\n\n## Bugs\n\nPlease report any bugs on the [Issue Tracker](https://github.com/allebb/hooker/issues), please ensure that bug reports\nare clear and contain as much information as possible.\n\nBug reports will be looked at and resolved as soon as possible!\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallebb%2Fhooker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fallebb%2Fhooker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fallebb%2Fhooker/lists"}