Automatically deploy changes from your Git repository to your Cloudways application whenever new code is pushed.
Git auto-deployment helps keep your Cloudways application updated without requiring you to manually pull changes after every update. It uses a webhook and the Cloudways API to trigger a Git deployment automatically.
A webhook is an automated notification sent by one application to another when a specific event occurs. In this setup, your Git provider sends a webhook request when code is pushed to your repository.
The request then triggers the Cloudways API to deploy the latest code to your application.
Prerequisites
Before starting, make sure that:
You are the primary owner of the Cloudways account.
Your application is deployed on a Cloudways Flexible server.
Your Git repository supports Git over SSH.
Git deployment has already been configured for your Cloudways application.
The public SSH key of your Cloudways application has been added to your Git repository.
You have access to the settings of your Git repository.
You can create files inside your Cloudways application through SSH or SFTP.
Read the Deploy Code to Your Application Using Git article first if Git deployment has not yet been configured for your application.
Note:
Cloudways is replacing the legacy API Key with API Access Tokens. Do not create a new integration using the legacy API Key.
Read How to Create and Manage Cloudways API Access Tokens to learn how to create, configure, secure, and manage an API Access Token.
How Git Auto-Deployment Works
The automatic deployment process works as follows:
You push a code change to your Git repository.
Your Git provider sends a request to the webhook URL.
The webhook script validates the request.
The script sends an authenticated request to the Cloudways API.
Cloudways pulls the latest code from the selected Git branch and deploys it to your application.
Step #1: Create a Cloudways API Access Token
An API Access Token is a secure credential that allows the deployment script to communicate with the Cloudways API.
To create an API Access Token:
Log in to the Cloudways Platform.
Click the grid icon located near the bottom of the left navigation menu.
Select API Integration.
In the Access Token Details section, click Create Access Token.
Enter a descriptive name, such as:
Git Webhook DeploymentSelect an appropriate expiration period.
Select one of the following scopes:
Limited Access: Recommended. Select only the Git API operation required to pull and deploy code.
Full Access: Use only when Limited Access does not provide the required operation.
Click Create Access Token.
Copy the generated Access Token immediately.
Store it in a secure location.
Important:
The complete Access Token is displayed only once. It cannot be viewed again after you close the confirmation screen.
Do not share the token in a support ticket, chat message, screenshot, public repository, or publicly accessible application file.
Selecting an expiration period
Select an expiration period that meets the requirements of your deployment workflow.
When the Access Token expires, the webhook will no longer be able to authenticate with the Cloudways API. Automatic deployment will stop until you create a new token and update the configuration file.
For a long-term deployment workflow, you can select a longer expiration period. However, you should periodically review and rotate the token according to your organization’s security policy.
Step #2 - Collect the Required Deployment Information:
Before creating the deployment files, collect the following information:
Server ID
The Server ID identifies the Cloudways server that hosts your application.
You can find it in the URL displayed in your browser after opening the server from the Cloudways Platform.
Application ID
The Application ID identifies the application where the code will be deployed.
You can find it in the URL displayed in your browser after opening the application.
Git Repository URL
Use the SSH URL of your Git repository.
Example:
[email protected]:username/repository.git
Branch Name
Enter the Git branch that you want Cloudways to deploy.
Examples include:
main
or:
master
Use the exact branch name configured in your repository.
Deployment Path
The deployment path determines where the code will be deployed inside the application.
Leave the value empty to deploy the code to the default public_html directory.
Use a custom deployment path only when your repository must be deployed to a specific subdirectory.
Step #3 - Create a Secure Configuration File:
The Access Token and deployment details should not be stored directly inside the publicly accessible public_html directory.
Connect to your application through SSH or SFTP and open the application directory that contains the public_html folder.
Create a file outside public_html and name it:
gitautodeploy-config.php
Add the following code:
<?php
return [
// Paste the Cloudways API Access Token here.
'access_token' => 'YOUR_CLOUDWAYS_API_ACCESS_TOKEN',
// Enter a long and difficult-to-guess webhook secret.
'webhook_secret' => 'YOUR_RANDOM_WEBHOOK_SECRET',
// Enter the Cloudways Server ID.
'server_id' => 'YOUR_SERVER_ID',
// Enter the Cloudways Application ID.
'app_id' => 'YOUR_APPLICATION_ID',
// Enter the SSH URL of the Git repository.
'git_url' => '[email protected]:username/repository.git',
// Enter the branch that should be deployed.
'branch_name' => 'main',
// Leave empty to deploy to public_html.
'deploy_path' => '',
];
Replace each placeholder with the correct information.
Creating a webhook secret
The webhook secret helps prevent unauthorized users from triggering the deployment file.
Use a long, random value containing letters, numbers, and symbols. Do not use your Cloudways password, Access Token, application name, or another easily guessed value.
Example format:
f8K2mP7xQ4vN9sR6dT3w
Do not use the example value in your production configuration.
Step #4 - Create Auto-Deployment File:
Open your application’s public_html directory.
Create a file and name it:
gitautodeploy.php
Add the following code:
<?php
const API_KEY = "YOUR API ACCESS TOKEN HERE";
const API_URL = "https://api.cloudways.com/api/v1";
const EMAIL = "YOUR EMAIL GOES HERE";
/* examples
const BranchName = "master";
const GitUrl = "[email protected]:user22/repo_name.git";
*/
//Use this function to contact CW API
function callCloudwaysAPI($method, $url, $accessToken, $post = [])
{
$baseURL = API_URL;
$ch = curl_init();
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_URL, $baseURL . $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
//Set Authorization Header
if ($accessToken) {
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer ' . $accessToken]);
}
//Set Post Parameters
$encoded = '';
if (count($post)) {
foreach ($post as $name => $value) {
$encoded .= urlencode($name) . '=' . urlencode($value) . '&';
}
$encoded = substr($encoded, 0, strlen($encoded) - 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
curl_setopt($ch, CURLOPT_POST, 1);
}
$output = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpcode != '200') {
die('An error occurred code: ' . $httpcode . ' output: ' . substr($output, 0, 10000));
}
curl_close($ch);
return json_decode($output);
}
//Fetch Access Token
$tokenResponse = callCloudwaysAPI('POST', '/oauth/access_token', null
, [
'email' => EMAIL,
'api_key' => API_KEY
]);
$accessToken = $tokenResponse->access_token;
$gitPullResponse = callCloudwaysAPI('POST', '/git/pull', $accessToken, [
'server_id' => $_GET['server_id'],
'app_id' => $_GET['app_id'],
'git_url' => $_GET['git_url'],
'branch_name' => $_GET['branch_name']
/* Uncomment it if you want to use deploy path, Also add the new parameter in your link
'deploy_path' => $_GET['deploy_path']
*/
]);
echo (json_encode($gitPullResponse));
?>
You can also try pasting the following code:
<?php
declare(strict_types=1);
const CLOUDWAYS_API_URL = 'https://api.cloudways.com/api/v1';
/*
* Load the protected configuration file located outside public_html.
*/
$configFile = dirname(__DIR__) . '/gitautodeploy-config.php';
if (!file_exists($configFile)) {
http_response_code(500);
exit('Deployment configuration file was not found.');
}
$config = require $configFile;
/*
* Allow only POST requests.
*/
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
header('Allow: POST');
exit('Only POST requests are allowed.');
}
/*
* Validate the webhook secret.
*/
$providedSecret = $_GET['secret'] ?? '';
if (
empty($config['webhook_secret']) ||
!hash_equals($config['webhook_secret'], $providedSecret)
) {
http_response_code(403);
exit('Invalid webhook secret.');
}
/*
* Send an authenticated request to the Cloudways API.
*/
function callCloudwaysApi(
string $method,
string $endpoint,
string $accessToken,
array $parameters = []
): object {
$curl = curl_init();
if ($curl === false) {
http_response_code(500);
exit('Unable to initialize the API request.');
}
curl_setopt_array($curl, [
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_URL => CLOUDWAYS_API_URL . $endpoint,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 60,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $accessToken,
'Content-Type: application/x-www-form-urlencoded',
],
CURLOPT_POSTFIELDS => http_build_query($parameters),
]);
$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
$curlError = curl_error($curl);
curl_close($curl);
if ($response === false) {
http_response_code(500);
exit('Cloudways API request failed: ' . $curlError);
}
if ($httpCode < 200 || $httpCode >= 300) {
http_response_code($httpCode);
exit(
'Cloudways API returned HTTP status ' .
$httpCode .
'. Response: ' .
substr($response, 0, 2000)
);
}
$decodedResponse = json_decode($response);
if ($decodedResponse === null && json_last_error() !== JSON_ERROR_NONE) {
http_response_code(500);
exit('Cloudways API returned an invalid response.');
}
return $decodedResponse;
}
/*
* Prepare the Git deployment request.
*/
$deploymentParameters = [
'server_id' => $config['server_id'],
'app_id' => $config['app_id'],
'git_url' => $config['git_url'],
'branch_name' => $config['branch_name'],
];
if (!empty($config['deploy_path'])) {
$deploymentParameters['deploy_path'] = $config['deploy_path'];
}
/*
* Trigger the Git pull operation.
*/
$deploymentResponse = callCloudwaysApi(
'POST',
'/git/pull',
$config['access_token'],
$deploymentParameters
);
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'message' => 'The Git deployment request was submitted successfully.',
'response' => $deploymentResponse,
]);
This script:
Uses the API Access Token directly as a Bearer Token.
Does not require your Cloudways account email address.
Does not generate a temporary token through the legacy API Key authentication endpoint.
Allows only POST requests.
validates the webhook secret before triggering a deployment.
Uses fixed deployment information from the protected configuration file.
Prevents repository and application information from being changed through the webhook URL.
Important:
Do not add gitautodeploy-config.php to your Git repository.
Consider adding the file name to your project’s .gitignore file to prevent it from being committed accidentally.
Step #5 - Create the Webhook URL:
Create the webhook URL by combining your application URL, the auto-deployment file name, and the webhook secret.
Use the following format:
https://example.com/gitautodeploy.php?secret=YOUR_RANDOM_WEBHOOK_SECRET
Replace:
example.comwith your Cloudways application domain or temporary application URL.YOUR_RANDOM_WEBHOOK_SECRETwith the secret defined ingitautodeploy-config.php.
Example:
https://www.example.com/gitautodeploy.php?secret=f8K2mP7xQ4vN9sR6dT3w
The webhook URL is sensitive because anyone with the complete URL may be able to trigger a deployment. Store it securely and do not publish it.
Step #6 - Add a Webhook in Your Git Repository:
To generate a webhook, copy your application URL and append these arguments at the end:
filename = (auto-deployment file name)
server_id = ( your server id on which you need to deploy the code)
app_id = ( your app id where you need to deploy the code )
git_url = ( it should be something like [email protected]:username122/phptest.git)
branch_name = ( branch name in your repo eg. master )
deploy_path = ( leaving it empty will deploy code at public_html, optional parameter)
Webhook URL Example:
example.com/gitautodeploy.php?server_id=12345&app_id=678910&git_url=[email protected]:username123/phptest.git&branch_name=master.
The exact navigation depends on your Git provider.
Open your GitHub repository.
Select Settings.
Select Webhooks.
Click Add webhook.
Paste the complete webhook URL into the Payload URL field.
Select application/x-www-form-urlencoded as the content type.
Select the push event as the webhook trigger.
Make sure that the webhook is active.
Click Add webhook.
Here, example.com needs to be replaced with your Cloudways application URL.
Add the Webhook to Bitbucket
Open your Bitbucket repository.
Select Repository settings.
Under Workflow, select Webhooks.
Click Add webhook.
Enter a name for the webhook.
Paste the complete webhook URL.
Select the repository push event.
Make sure that the webhook is active.
Click Save.
For another Git provider, use its webhook settings to send a POST request to the webhook URL whenever code is pushed to the selected repository.
You can add a webhook in your Github account by:
Get into your Github repo and click Settings
Now click Webhooks and Click on Add Webhook
Name your webhook and add the webhook URL to your app, then click Save.
You can test your webhook while making a small change to your repository which will automatically trigger your application, to generate a pull request using Cloudways API. For complete documentation of the API, visit our playground.
Step #7 - Test the Automatic Deployment:
After adding the webhook:
Make a small change in the configured Git branch.
Commit the change.
Push the commit to the remote repository.
Open the webhook delivery history in your Git provider.
Confirm that the webhook received a successful response.
Check the Cloudways application to confirm that the latest code was deployed.
A successful response should indicate that the Git deployment request was submitted.
Note:
A successful webhook response confirms that Cloudways accepted the deployment request. The complete Git pull operation may require additional time to finish.
Troubleshooting Git Auto-Deployment
The webhook returns HTTP 400
An HTTP 400 response usually means that required deployment information is missing or invalid.
Check:
Server ID
Application ID
Git repository URL
Branch name
Deployment path
The webhook returns HTTP 401
An HTTP 401 response means that the API Access Token is invalid, expired, or no longer available.
Confirm that:
The Access Token was copied correctly.
The token has not expired.
The token has not been revoked.
The complete token value is stored in the configuration file.
Create a new Access Token when the existing token has expired or cannot be recovered.
The webhook returns HTTP 403
An HTTP 403 response can mean either:
The webhook secret is incorrect.
The Access Token does not have permission to perform the Git pull operation.
Confirm that the secret in the webhook URL matches the value in the configuration file.
Also review the Access Token scope and make sure that it includes the required Git deployment operation.
The webhook returns HTTP 405
An HTTP 405 response means that the deployment file received a request method other than POST.
Configure the Git provider to send a POST request.
The deployment configuration file was not found
Confirm that:
The file is named gitautodeploy-config.php.
It is stored in the application directory immediately above public_html.
The file name and path match those used in the deployment script.
The webhook succeeds, but the code is not updated
Check the following:
The correct branch is configured.
The repository SSH URL is correct.
The Cloudways SSH key still has access to the repository.
The application and server IDs are correct.
The pushed change belongs to the configured branch.
The deployment path is correct.
The Git repository is accessible.
Deployment stopped after previously working
Check whether the Access Token has expired or been revoked.
Open API Integration in the Cloudways Platform and review the token’s expiration and status. When necessary:
Create a replacement Access Token.
Assign the required Git permissions.
Replace the old token in gitautodeploy-config.php.
Test the webhook again.
Revoke the previous token if it remains active but is no longer required.
Security Recommendations
Use a separate Access Token
Create a dedicated Access Token for this deployment workflow. Do not reuse a token that is connected to unrelated applications or integrations.
Use Limited Access
Select only the API permissions required for Git deployment whenever Limited Access supports the required operation.
This reduces the actions that can be performed if the token is exposed.
Protect the Access Token
Never store the Access Token:
In a public Git repository
Inside client-side website code
In a publicly accessible document
In a screenshot
In a support ticket or chat message
Directly in the webhook URL
Protect the webhook URL
Treat the complete webhook URL as sensitive information because it contains the webhook secret.
Replace the webhook secret immediately if the URL is exposed.
Use HTTPS
Use an HTTPS application URL so that webhook requests are encrypted while traveling between your Git provider and the Cloudways application.
Rotate the Access Token
Replace the Access Token periodically or whenever:
It has expired.
It may have been exposed.
A connected team member or service no longer requires access.
The token’s storage location may have been compromised.
You cannot confirm where the token is being used.
Revoke unused tokens
Revoke the Access Token when the automatic deployment workflow is permanently removed.
Revoking a token immediately prevents the deployment script from authenticating with the Cloudways API.
New code pushed to the configured Git branch should now trigger an automatic deployment to your Cloudways application.
That’s it! We hope this article was helpful.


