Today we are going to talk about how to deploy our code to our testing server or production server using git/apache. In this scenario git will be taking the place of the tradional method of using ftp servers to upload code to a server.
We will get to know how to
- configure a remote git repository so it checks out data to a web root location
- configure apache and create an apache conf file that will enable communication between the git repository and apache
- setup authenticaton in apache for git events
- push to remote repository and see files in web root
Let’s hit the road!!!
Configure remote git repository
We first need to create an empty remote git repository on the remote box we want to push changes to using apache. For the sake of this post the local/remote repositories can be on the same local machine but the distinction has to be made betweeen local repository(where u store your local work/code) and remote repo(remote repo where u push after working) which is usually on a remote machine with a git repo available.
Assuming we want to create the local repo in /opt/git/local/ and the remote repo in /opt/git/remote/test_repo.git We use the commands below
##for local
cd /opt/git/
mkdir local
cd local
git init
##for remote
cd /opt/git/
mkdir remote
cd remote
git init --bare --shared=group test_repo.git
The flag - -bare create an empty repository with no content. The - -shared=group flag also creates a git repository which will be shared among many users.
We now have to enable pushing to the remote git repository else valid users won’t be able to push to the git repository. We use the commands below to enabling pushing
cd /opt/git/remote/test_repo.git
git config --file config http.receivepack true
A git hook is a script which can perform some action when some event occurs. They are stored in the .git/hooks/ directory of your git repository. They are executed at various stages when using git such as when a push,commit,merge ,etc is done ..
There are client side hooks as well as server side hooks.
Client side hooks are used on the local repository and server side hooks on the remote repository.
We will be using the post-receive hook which is a server side hook which gets run after the push is done.
This script can’t stop the push process, but the client doesn’t disconnect until it has completed, so be careful if you try to do anything that may take a long time.
We will rename the post-receive.sample to post-receive in the /opt/git/remote/test_repo.git/hooks/ folder and make it executable so it can be run after a git push.
We will then paste in our shell script to move our code to the web root of our box. We use the code below
##renames post-receive sampe script to post-receive
mv /opt/git/remote/test_repo.git/hooks/post-receive.sample /opt/git/remote/test_repo.git/hooks/post-receive
##makes it executable
chmod u+x /opt/git/remote/test_repo.git/hooks/post-receive
#!/bin/bash
unset GIT_INDEX_FILE
##the target below should have been created already in our web root else we will get an error
## although the push will succed
TARGET="/var/www/html/remote/test_repo_web"
GIT_DIR="/opt/git/remote/test_repo.git/"
##this can be http or https depending on whether you are using a http/https
UAT_BRANCH_PATH="http://127.0.0.1/remote/test_repo_web"
##this short script creates a new directory where branches can be checked out to
##if branch directory does not exist it is created and data is checked in there
##some checks will have to be done if branch conforms to naming conventions
while read oldrev newrev ref
do
IN=$ref
BRANCH_NAME=$(git rev-parse --symbolic --abbrev-ref $ref)
BRANCH=$TARGET/$BRANCH_NAME
echo "branch is ${BRANCH_NAME}"
if [ ! -d "$BRANCH" ]; then
echo "Creating branch directory"
mkdir $BRANCH
echo "Ref $ref received. Deploying ${BRANCH_NAME} branch to uat..."
echo "Go to ${UAT_BRANCH_PATH}/${BRANCH_NAME} to view/review changes"
git --work-tree=$BRANCH --git-dir=$GIT_DIR checkout -f $BRANCH_NAME
else
echo "Branch exists. skipping creation"
echo "Ref $ref received. Deploying ${BRANCH_NAME} branch to uat..."
echo "Go to ${UAT_BRANCH_PATH}/${BRANCH_NAME} to view/review changes"
git --work-tree=$BRANCH --git-dir=$GIT_DIR checkout -f $BRANCH_NAME
fi
done
Thats it for git !! . Next is apache.
Configure apache
Assuming you dont have apache installed, you have to install it for your os distribution first before continuing. After installing apache you have to enable some modules which are needed for our purpose. We will use the command below to enable the modules we need
sudo a2enmod cgi alias env auth_digest
- cgi module allows apache to communicate with the cgi script git-http-backend which is is a simple CGI program to serve the contents of a Git repository to Git clients accessing the repository over http:// and https:// protocols.
- alias module allow for manipulation and control of URLs as requests arrive at the server. This is necessary becuase we will be setting up patterns which identify requests as git requests
- env allows control of the environment that will be provided to CGI scripts and SSI pages. We basically need to pass environmental variables and pass them to the git-http-backend cgi script
- auth_digest module enables us to setup authentication using md5 digests stored in password files.
After enabling the above modules,we now need to creat an apache configuration file for git .
So we creat an apache config file for git,insert comands in and make sure that apache loads it when its starting.
touch /etc/apache2/git.conf
#environmental variables for git-http-backend
#also tells apache to run the git-http-backend as the handler for anything coming into
#the /git/ path your web server
SetEnv GIT_PROJECT_ROOT /opt/git/remote/
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/
##tells apache to allow requests to this path which contains git commands
<Directory "/usr/lib/git-core*">
Options +ExecCGI +Indexes
Require all granted
</Directory>
#tells apache to ask for authentication before allowing pushing
#it will use the /opt/git/.htpasswd file for authentication
<LocationMatch "^/git/.*/git-receive-pack$">
AuthType Digest
AuthName "Git Access"
AuthUserFile /opt/git/.htpasswd
Require valid-user
</LocationMatch>
sudo echo "Include /etc/apache2/git.conf" >> /etc/apache2/apache2.conf
sudo apache2 restart
Setup authentication
We next need to setup authentication so the whole world cant push to our git repository. We partly did that by setting up the AuthUserFile but we now have to create the physical file and put users in it . we do the following
##create auth file
touch /opt/git/.htpasswd
##add users
htdigest /opt/git/.htpasswd "Git Access" test
##enter password when prompted
Push to remote repository and view files through browser
Now we are ready to make some changes to our local repo . after the changes are made,we will be able to view the changes cuz the branch will have been moved to the web root. Exampe if we were to execute the following commands below in our local repo
cd /opt/git/local/
git remote add origin http://127.0.0.1/git/test_repo.git
git checkout -b testing
touch index.html
echo "<div>It works!!</div>" >> index.html
git add index.html
git commit
git push -u origin testing
##ask for username and password here password here..
## enter test and the password you used earlier
Either way with a little creativity we can do some nice stuff with git.