Automating Project Deployment with GitLab Webhooks
User Permissions and Shell Access
Automation scripts often run under the web server's user account (e.g., www-data or nginx). If the current shell user differs from the web server user, permission errors will occur during git pull operations. Switch to the web server user to configure the environment:
su - www-dataIf the system returns "This account is currently not available," modify the user's shell entry in /etc/passwd to allow login:
vim /etc/passwd
# Update the shell path for the user
# Original: www:x:1000:1000::/home/www:/sbin/nologin
# Modified: www:x:1000:1000::/home/www:/bin/bashSSH Key Generation and GitLab Configuration
Generate an SSH key pair for the user to enable password-less interaction with the GitLab repository.
ssh-keygen -t rsa -b 4096 -C "deploy@server"
# Output example
Generating public/private rsa key pair.
Enter file in which to save the key (/home/www/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:Navigate to the GitLab project settings and add the contents of ~/.ssh/id_rsa.pub to Deploy Keys. Ensure the key has write access if required. Before automating, manually pull the repository once while logged in as the web user to accept the server's SSH fingerprint and avoid interactive prompts during script execution.
PHP Environment Setup
The webhook handler relies on shell commands. Verify that the exec or shell_exec function is enabled in php.ini. If exec is listed under disable_functions, remove it and restart the PHP service.
Webhook Handler Implementation
Create a PHP file accessible from the web root to act as the webhook endpoint. This script validates the request token and triggers the corresponding deployment shell script.
<?php
define('ACCESS_TOKEN', 'your-secure-token-string');
// Map project identifiers to specific scripts
$allowedProjects = [
'main-site' => '/var/www/scripts/deploy_main.sh',
'api-service' => '/var/www/scripts/deploy_api.sh',
];
$projectKey = $_GET['project'] ?? '';
$requestToken = $_GET['token'] ?? '';
// Validate Token
if (!hash_equals(ACCESS_TOKEN, $requestToken)) {
http_response_code(403);
exit('Access Denied');
}
// Validate Project
if (!array_key_exists($projectKey, $allowedProjects)) {
exit('Invalid Project');
}
// Log the request
$logName = __DIR__ . "/logs/{$projectKey}_" . date('Y-m-d') . '.log';
file_put_contents($logName, "[" . date('H:i:s') . "] Request received from " . $_SERVER['REMOTE_ADDR'] . PHP_EOL, FILE_APPEND);
// Execute the deployment script
$scriptPath = $allowedProjects[$projectKey];
$command = "bash {$scriptPath} 2>&1";
// Run command and capture output
$output = shell_exec($command);
file_put_contents($logName, "Output: " . $output . PHP_EOL, FILE_APPEND);
echo "Deployment triggered successfully.";GitLab Webhook Configuration
Navigate to the project's Settings > Webhooks in GitLab. Add the URL of the PHP handler script created above.
URL Example: https://your-domain.com/webhook.php?token=your-secure-token-string&project=main-site
Select specific trigger events (e.g., Push Events) and save the webhook. Test the connection to ensure the server responds with the expected success message.