How to deploy from git repo without server having

2019-02-11 02:59发布

I have a PHP project in a BitBucket git repo.

I work in a branch called "develop" for small fixes, or I work in temporary feature branches. When I'm ready to deploy, I merge those branches into "master".

I want to make deploying to my live site as easy as that (merging to master and pushing to BitBucket).

But I really don't want my server to have any access to my repo because that adds security concerns. If you care about security, you want your repo to be in as few places as possible. If your server gets compromised, that's a bad enough situation, but it would be even worse if the attacker then would have access to my full repo. This person agrees.

So I assume that I'll want to use something like git archive master, like https://stackoverflow.com/a/163769/470749 explains.

How can I set up a hook that detects a push of "master" and then runs git archive master to export the latest code (not as a repo, though) to a compressed zip file which it then sends (via SCP and/or Rsync?) to the remote server, unzips it to a new directory, and then (maybe via changing a symlink) points the server to that new directory?

Bonus question: how could I enable easy emergency rollbacks? (I imagine there might be situations where I want to revert to the previous commit quickly.)

1条回答
Melony?
2楼-- · 2019-02-11 03:44

I'm happy with the scripts I ended up with:

deploy.sh:

##This executable file will export your latest code from master (via "git archive") and will upload it 
##to the remote server and then call a script on the server to handle from there.
##----------------------------------------------------------------------------------------------------

source dev-ops/archive_and_upload.sh

##On the remote server, run a script to archive the existing production site files and then deploy the uploaded package.
ssh -i ~/.ssh/id_rsa myUserName@vientiane.dreamhost.com <<'ENDSSH'

set -e

cd /home/myUserName/myProjectName/latest

##Unzip the zip file, then delete it.
echo "Unzipping the package.zip..."
unzip -o package.zip && rm package.zip  

cd /home/myUserName/myProjectName/

nowTime=$(date -u +"%Y-%m-%d__%H:%M:%S")
echo "The archive will have this timestamp: " $nowTime

##Copy the "latest" folder to a dated "packages" subfolder.
cp -R latest/ packages/$nowTime 
echo "Copied the existing site to an archive."

##Install Laravel dependencies.
echo "Running Composer so that the remote server downloads and installs dependencies..."
cd packages/$nowTime 
php -d memory_limit=256M ~/bin/composer.phar install   

##Delete the "live" symlink and immediately create a new "live" symlink to the most recent subfolder within "packages".
echo "Updating the symlinks..."
cd /home/myUserName/myProjectName/
echo `pwd`
rm previous
mv live previous && ln -s packages/$nowTime live && ls -lah  

##Clear out the "latest" folder in preparation for next time.
echo "Deleting the contents of the 'latest' folder in preparation for next time..."
rm -rf latest/* && ls latest   
ENDSSH

echo "FINISHED DEPLOYING!"

archive_and_upload.sh:

##This executable file will export your latest code from master (via "git archive") and will upload it 
##to the remote server.
##----------------------------------------------------------------------------------------------------

##Clear out the contents of the previous export package.
rm -rf dev-ops/package/*   

##Export the "master" branch of this git repo. (The result is not a repo but is just code.)
git archive --format zip --output dev-ops/package/package.zip master  

##Send zip file to remote server.
scp -i ~/.ssh/id_rsa dev-ops/package/package.zip myUserName@vientiane.dreamhost.com:/home/myUserName/myProjectName/latest/package.zip 

revert_to_previous_package.sh:

ssh -i ~/.ssh/id_rsa myUserName@vientiane.dreamhost.com <<'ENDSSH'

set -e

cd /home/myUserName/myProjectName/

mv live rollingBack && mv previous live && mv rollingBack previous && ls -lah

ENDSSH

echo "ROLLED BACK!"

As you can see, I set my Dreamhost server to serve from a folder called "live", which is really just a symlink to a subfolder that is named as the timestamp for when that package of code was uploaded. There is also another symlink called "previous" which makes rolling back easy (in case I notice problems after deploying and want to revert).

查看更多
登录 后发表回答