0

I'm trying to attempt using a webhook script so that I can just commit locally and have the script triggered server-side and pull in any change.

Now if I login to the server via SSH and run php webhook.php the cript is triggered successfully and the files are updated. So I know the file does work. But if I make edits to the files, commit and push to master, I'm not seeing the files updated.

The log file produced by the script suggests everything is fine, but clearly it's not.

My file structure is like this:

var
  www
    my-project
    - webhook.php
       repo-folder

So the file should be pulling the files into repo-folder and the webhook.php is set as the webhook via the bitbucket control panel. If I view the log within bitbucket, it's showing a successful request every time I push a commit.

The script:

<?php

date_default_timezone_set('Europe/London');

class Deploy {

    /**
     * A callback function to call after the deploy has finished.
     *
     * @var callback
     */
    public $post_deploy;

    /**
     * The name of the file that will be used for logging deployments. Set to
     * FALSE to disable logging.
     *
     * @var string
     */
    private $_log = 'deployments.log';

    /**
     * The timestamp format used for logging.
     *
     * @link    http://www.php.net/manual/en/function.date.php
     * @var     string
     */
    private $_date_format = 'Y-m-d H:i:sP';

    /**
     * The name of the branch to pull from.
     *
     * @var string
     */
    private $_branch = 'master';

    /**
     * The name of the remote to pull from.
     *
     * @var string
     */
    private $_remote = 'origin';

    /**
     * The directory where your website and git repository are located, can be
     * a relative or absolute path
     *
     * @var string
     */
    private $_directory;

    /**
     * Sets up defaults.
     *
     * @param  string  $directory  Directory where your website is located
     * @param  array   $data       Information about the deployment
     */
    public function __construct($directory, $options = array())
    {
        // Determine the directory path
        $this->_directory = realpath($directory).DIRECTORY_SEPARATOR;

        $available_options = array('log', 'date_format', 'branch', 'remote');

        foreach ($options as $option => $value)
        {
            if (in_array($option, $available_options))
            {
                $this->{'_'.$option} = $value;
            }
        }

        $this->log('Attempting deployment...');
    }

    /**
     * Writes a message to the log file.
     *
     * @param  string  $message  The message to write
     * @param  string  $type     The type of log message (e.g. INFO, DEBUG, ERROR, etc.)
     */
    public function log($message, $type = 'INFO')
    {
        if ($this->_log)
        {
            // Set the name of the log file
            $filename = $this->_log;

            if ( ! file_exists($filename))
            {
                // Create the log file
                file_put_contents($filename, '');

                // Allow anyone to write to log files
                chmod($filename, 0666);
            }

            // Write the message into the log file
            // Format: time --- type: message
            file_put_contents($filename, date($this->_date_format).' --- '.$type.': '.$message.PHP_EOL, FILE_APPEND);
        }
    }

    /**
     * Executes the necessary commands to deploy the website.
     */
    public function execute()
    {
        try
        {
            // Make sure we're in the right directory
            chdir($this->_directory);
            $this->log('Changing working directory... ');

            // Discard any changes to tracked files since our last deploy
            exec('git reset --hard HEAD', $output);
            $this->log('Reseting repository... '.implode(' ', $output));

            // Update the local repository
            exec('git pull '.$this->_remote.' '.$this->_branch, $output);
            $this->log('Pulling in changes... '.implode(' ', $output));

            // Secure the .git directory
            exec('chmod -R og-rx .git');
            $this->log('Securing .git directory... ');

            if (is_callable($this->post_deploy))
            {
                call_user_func($this->post_deploy, $this->_data);
            }

            $this->log('Deployment successful.');
        }
        catch (Exception $e)
        {
            $this->log($e, 'ERROR');
        }
    }

}

// This is just an example
$deploy = new Deploy('/var/www/site-name/repo-name');

$deploy->execute();

?>

3 Answers 3

1

i was researching this more and the best way you can do is like i mention find out what is the user being used by apache server by building a php script and run the shell_exec('whoami'); and run on your browser to see that user it is.

Then on your document root for your website mine per example is /var/www you would need to create shh keys for this directory when you do that also add a config file with the host bitbucket and reference to the key you created.

Add the key to bitbucket

then you would need to add permission for apache to run the git command run the command visudo and add:
yourapacheuser ALL=(yourapacheuser) NOPASSWD: /usr/bin/

#the /usr/bin in my case is where i have installed git so you need to see what is the directory path where you install git.

After that you should be able to run your script without problems, in case it complains about a requiretty message then on visudo again add: Defaults:yourapacheuser !requiretty

hope it helps

Sign up to request clarification or add additional context in comments.

Comments

0

did you configure SSH keys for the server you are using in bitbucket and add the webhook with the url of your script?

3 Comments

I did indeed. All the details match up and the key works fine. I'm very confused.
the problem you are having is when you are executing in shell you are logged in as root and therefore it allows to run the code, but when you run via apache server your user is not root, you can do this by creating a php script with shell_exec('whoami'); and it will tell you which is user is configured for apache the user might be apache or www-data , once you find it you need to add permission to the apache user and as well to generate a key for the apache user and set it on the bitbucket ssh keys. let me know how it go.
i was researching this more and the best way you can do is like i mention find out what is the user being used by apache server by building a php script and run the shell_exec('whoami'); and run on your browser to see that user it is.
0

As user1361389 wrote you need to know what users are running the different processes. This is how I did on an Amazon Ubuntu instance.

I have a php file that calls a bash script: shell_exec("sudo -u ubuntu /home/ubuntu/gitpull.sh");

Create SSH keys for user ubuntu and uploaded the public key to bitbucket.

Also, make sure that the php files on your server are owned by the correct user. In my case ubuntu.

You then need to impersonate ubuntu when calling the php file to deploy code. Add this line in the sudoer file (>sudo visudo )

www-data ALL=(ubuntu) NOPASSWD: /path/to/gitpull.sh

Then in bitbucket add the URL to your hook.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.