Automatic Git Deploy with Kinsta via SSH

Kinsta is my preferred WordPress host provider. This year I’ve switched all my new customers to Kinsta. Coming from WP Engine, one feature I miss is a per site git URL which will automatically deploy updates whenever a git push is run locally. This isn’t something Kinsta currently offers.

There are plenty of workarounds. In fact I’ve previously mentioned a solution using a 3rd party service called Beanstalk. That said I’ve decided to see how hard it would be to handle the Git deployments using just Kinsta.

With some upfront setup, Kinsta can totally handle an automatic deploy from a local git push.

  • On local computer cd to a WordPress site and run git init
  • Add a .gitignore file with common WordPress exclusions (plugins/themes/core files).
  • On server add a bare git repo under private folder. This will act as the deployment repo similar to WP Engine’s built in deployment repo.
git init --bare ~/private/{site-name}.git
cd ~/private/*.git
git symbolic-ref HEAD refs/heads/main
  • On server add a new git repo under the public folder. cd ~/public; git init
  • Create a post-receive hook stored within ~/private/{site-name}.git/hooks/ and named post-receive (see below example). This will deploy from the bare git to the ~/public/ directory whenever a git push is received.
  • Assign execute permissions. 
    chmod +x ~/private/{site-name}.git/hooks/post-receive
  • On local computer add the remote.
    git remote add production ssh://{site-name}@{site-ip}:{site-port}/www/{site-folder}/private/
    {site-name}.git
  • On local computer make file changes, git commit and deploy as normal with a git push. This will deploy via SSH to the live site. On the first push git you may need to specific which branch to use on the remote like so git push --set-upstream production main.

Example post-receive file: ~/private/sitename.git/hooks/post-receive

#!/bin/bash
TARGET="/www/sitename_123/public"
GIT_DIR="/www/sitename_123/private/sitename.git"

while read oldrev newrev ref
do
        # Neat trick to get the branch name of the reference just pushed:
        BRANCH=$(git rev-parse --symbolic --abbrev-ref $ref)

        if [[ $BRANCH == "main" ]];
        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 main branch may be deployed on this server."
        fi
done

I recommend creating this script directly on the server using SSH rather then attempting to upload via SFTP. That will prevent any issues with line endings that can happen between platforms. To create files directly, start by SSH into the Kinsta site then run nano ~/private/sitename.git/hooks/post-receive and paste contents of above script then tweak as needed. Press Ctrl + X then Y then Enter to save and quit Nano.

References