Using git as a source of truth is a great practice. Using git to deploy code has all sorts of benefits to your health.
While managing a team of coders for a web design firm, it became commonplace for code deployments to go south far too often. One coder would upload just the code they had touched, and another would come and overwrite the same code with a previous version. Despite the fact we were using git as a code repository, people's commits were infrequent and their understanding of what other coders were doing was incomplete. We needed a way to enforce good habits and give back the time I would spend constructing what a site was supposed to be from disparate parts. It took a conference call to convince everyone that I was right -- we were going to have full git buy-in. Coders would no longer be part of a staff group with permissions to edit files in the web root. The would push their code to the server, and the server would handle the rest. This post covers how to set up git deployments in a very basic setup. A post-receive hook puts the files where they should be (you can expand upon this to run tests and build if needed, but I'll save some of that for another post)
Without further ado, here's some steps to get you started:
navigate to your ssh directory:
cd ~/.ssh/
Generate ssh key
ssh-keygen -t rsa -b 4096 -f serverName-git -C "Git Deploy - serverName"
Add Key to ssh-agent:
ssh-add ~/.ssh/serverName-git
Copy public key to server:
ssh git@serverName 'cat >> ~/.ssh/authorized_keys' < ~/.ssh/serverName-git.pub
edit ssh config:
Host serverName-as-git
HostName <serverName>
User git
IdentityFile ~/.ssh/serverName-git
IdentitiesOnly yes
add the remote to your git repo:
git remote add production git@serverName-as-git:<reponame>.git
Now for setup on the server:
set up a git user account
adduser git
make yourself git user:
su git
initialize bare repository:
git init --bare repoName.git
navigate to hooks folder
cd reponame/hooks
create post-receive hook:
touch post-receive
make post-receive executable:
chmod +x post-receive
add the logic for the post-receive hook:
#!/bin/bash
TARGET="/var/www/repoName.com"
GIT_DIR="/home/git/repoName.git/"
BRANCH="master"
while read oldrev newrev ref
do
# only checking out the master (or whatever branch you would like to deploy)
if [[ $ref = refs/heads/"$BRANCH" ]];
then
echo "Ref $ref received. Deploying ${BRANCH} branch to production..."
git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f
else
echo "Ref $ref received. Doing nothing: only the ${BRANCH} branch may be deployed on this server."
fi
done
exit git user and navigate to the level below target directory, in this case: /var/www
make git owner of the directory:
chown -R git:www-data /var/www/repoName.com
Bring it all together
Now, when you add a commit, you can:
git push production master
and the files will be automatically deployed. *note, the repo gets put in your web root in this example, so make sure you put the files you want web facing in a folder like dist and have nginx look there for files to serve.
There are many more neat options to be had here, like running tests and building from source, but I'll leave those for another post.