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.