1

I have a local git repo which I am working inside of and am trying to figure out a good workflow for deploying my local development to my production VPS server.

My Goal:

I would love to be able to work on my local git repo and simple do a git push production master which would sync my production VPS server with my latest changes, then add a git hook to execute a bash script to do all the necessary deployment on the remote server automatically without me having to intervene outside of running the above git command.

So far I have looked into using bitbucket and their webhooks service, however I believe I would then need to set up a listener server on my VPS to receive these webhook notifications and then handle them accordingly.

I thought: "why have this middle step of using bitbucket and having to add more work in setting up my server to work with this workflow?" Couldn't I just push direct to my VPS in someway and cutout the need for bitbucket webhook.

Questions:

How can I setup this architecture on my VPS? What steps are needed to create a connection between my local git repo and the remote server - with the end goal of being able to do a simple git push production master?

Is this a well thought out approach or am I overlooking any potensial issues here?

Additional Info:

  • Linux server/dev environment
  • Will be using ansible to provision the server

Any help or pointers are welcome, Thank you

GustavMahler
  • 657
  • 1
  • 6
  • 23

1 Answers1

3

If you push to a bare repo on your VPS, you could use a post-receive hook to deploy files there. The following is an example of a sparse-checkout where you can chose to exclude some files from the deploy if you want.

Creating a bare repo for deploying a subset of files (sparse-checkout)

##
## Note: In this example the deploy host and dev host are the same which is 
## why we're using local paths; ~/git/camero.git will represent the bare repo
## on the remote host.
##

# create the bare repo
# (leave out --shared if you're the only one deploying)
git init --bare --shared ~/git/camero.git

# configure it for sparse checkout
git --git-dir=~/git/camero.git config core.sparseCheckout true

# push your code to it
git --git-dir=~/dev/camero remote add deploy ~/git/camero.git
git --git-dir=~/dev/camero push deploy master
#!/bin/sh
#
# sample post-receive script
#  ~/git/camero.git/hooks/post-receive
#

deploy_branch='master'
deploy_dir='/some/place/on/this/host'

while read -r oldrev newrev ref; do
    test "${ref##*/}" == "$deploy_branch" && \
    git --work-tree="$deploy_dir" checkout -f $deploy_branch || \
    echo "not deploying branch ${ref##*/}"
done
#
# sample sparse-checkout file
# Note: the pattern syntax is the same as for .gitignore
# Save this file in ~/git/camero.git/info/sparse-checkout
#

# deploy all python files
*.py

# ... except for the test python files
!*Test*.py

Assuming you have ssh access to your VPS with key authentication, I would recommend setting up a ~/.ssh/config file with a host entry for your VPS. It will simplify your git commands.

# sample .ssh/config host entry
Host vps
    Hostname 192.0.2.1
    User your_username
    # any other ssh configuration needed by vps

Then you can replace ~/git/ with vps:

Here's a working example with notes.

Cole Tierney
  • 9,571
  • 1
  • 27
  • 35
  • Why not create normal git repo but with working dir in different place like this `git --git-dir git/test --work-tree work/test init` https://stackoverflow.com/questions/16792737/git-change-working-directory/16793529#16793529 ? – rofrol Feb 20 '23 at 12:03
  • Oh I see. You will stil need to sync working dir with .git: If you push to a non-bare repo, then the HEAD of that repo will be out of sync with the index and the working copy https://stackoverflow.com/questions/738154/what-does-git-updating-currently-checked-out-branch-warning-mean/738256#738256 – rofrol Feb 20 '23 at 12:21
  • @rofrol I added a working example to my answer. A blog that's deployed with `git read/write tree` in a pre-receive hook on the server. – Cole Tierney Feb 24 '23 at 00:39