简体   繁体   中英

Automate Deployments with Git, Bitbucket and PHP

I'm in the process of trying to set up automatic deployments when I make a git push to my bitbucket repository. I have a php deploy script that I leveraged from this blog but when the script runs it is logging that it's only updating from a previous commit.

Here is an example. Let say I log into my server and type git pull. The server will update with the latest changes and lets say the hash for that commit was 001. However if I make several commits lets call them 002, 003, and 004 my script should run every time assuming I pushed those changes to bitbucket after every commit. The script runs but every time it will keep the changes from 001. Only when I log into my server and type git pull, will the server update to 004. Do you know what would cause this?

// Make sure we're in the right directory
exec('cd '.$this->_directory, $output);
$this->log('Changing working directory... '.implode(' ', $output));

// 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.');

What I would recommend is to release not based on latest version in your master, but a latest tag.

/home/my-user/my-application/1.0.12/www
/home/my-user/my-application/1.0.13/www

etc. This provides rollback functionality. You could make a PHP script that connects to your server over SSH and makes a new clone based on that tag. If you use Composer, you can use this to execute commands. If not, you can do it with a makefile.

Edit: I have forgot to mention how you actually link it.

You have a symlink
/home/my-user/my-application/www -> /home/my-user/my-application/1.0.12/www

When your entire deployment script is finished without errors, you switch the symlink to:
/home/my-user/my-application/www -> /home/my-user/my-application/1.0.13/www

Your application is now live without downtime.

A very simple and efficient approach is to use bitbucket pipelines , you can create a YAML script to compile your dependences and push the code to a server on each commit, automatimagicaly or manually.

Here is an example of a Bitbucket Pipelines YAML script:

image: php:7.1.1

pipelines:
  default:
    - step:
       caches:
         - composer
       script:
         - apt-get update && apt-get install -y unzip
         - curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
         - composer install
    - step:
       deployment: staging
       name: Deploy to Staging Server
       script:
         - apt-get update
         - apt-get -qq install rsync 
         - echo "Upload Project files..."
         - rsync -avH * -e "ssh" root@$IP_SERVER:/var/www/html/

This script installs the Composer dependencies inside a Docker instance and pushes the projects files to server.

The problem is file permissions.

I was following the same link to that blogpost. I found that the 'www-data' user that is used by php and nginx processes, does not have write permissions to your repository code. It cannot even use git.

For verifying this try doing a 'git pull' on the server as 'www-user'. You can switch to it by 'sudo su www-data'. You will find that it does not even recognize that as a valid git repo and is unable to run your 'deploy.php' script without errors.

You need to set proper permissions to your repository so that www-data can access it.

Or you change the whole approach. Follow this post http://toroid.org/ams/git-website-howto which I feel is a much better method than the above. I ended up using this method.

You want to set a post-update hook in the remote you push to.

In the default case git will not checkout any data you push to a remote. That's why the default git configuration refuses to push to the checked out branch as the checked out files aren't up-to-date with HEAD anymore, when you push to the checkout-out branch.

When the remote receives a push to a branch you can react on that in the post-update hook, though. To see what happens you should first start with some logging:

echo "post update `date`: $*" >> /home/ingo/test/githooks.out

When I push to the branch new, for example I get the line

post update Mi 24. Jun 13:01:14 CEST 2015: refs/heads/new

, where $* contains the branches I pushed to.

With this you can write simply write a script to checkout that branch. I prefer checking out to detached heads, as its much simpler to combine work from several module repositories (no submodules) into a deployed version. See my answer to the source code deployment on how to checkout code outside of the git repository and work with that.

For example you could do

for b in $*
do B=`basename $b`
if [ "$B" = "publish" ] # react on changes to the publish branch
then git --work-tree "PATH TO THE PUBLISHED WORK TREE" checkout publish
do_some_extra_work # to change permissions or inform your team leader
fi done

Of course you can do the checkout step too, that is done on a pull

if [ "`cat HEAD`" = "ref: refs/heads/master" ]
# only do that checkout if the repository is in a sane state
then git merge new # I assume you push to new
fi

The cool thing is that you will see the output of your hook on the remote in the terminal where you executed the push:

# git push remote master:new
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 296 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Updating f81ba5b..a99a710
remote: Fast-forward
remote:  a.txt | 2 ++
remote:  1 file changed, 2 insertions(+)
To ../remote
    db48da1..a99a710  master -> new

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM