Tiny PHP Framework

Home Getting Started Core Concepts Helpers Extensions Repo

Deploy using git push

Push into a remote repository with a detached work tree and a post-receive hook that runs git checkout -f.

On the remote server, create a new repository to mirror the local one.

Assuming the website directory is /home/webapp

$ cd /home/webapp
$ mkdir repo.git && cd repo.git
$ git init --bare
Initialized empty Git repository in /home/webapp/repo.git/

Continue to define (and enable) a post-receive hook that checks out the latest tree into the web server’s DocumentRoot (this directory must exist! Git will not create it for you):

$ cd /home/webapp
$ mkdir /home/webapp/html
$ nano /home/webapp/.git/hooks/post-receive

Put the below code into .git/hooks/post-receive:

#!/bin/bash

WORKDIR=/home/bell/html_html/WEBSITE_DIR_NAME
PUBLIC_DIR_NAME=public
POST_DEPLOY_COMMAND="echo 'done'"

while read oldrev newrev ref
do
  if [[ $ref =~ .*/main$ ]]; then
    echo "Main repo received. Deploying branch to production..."
    # check out the latest commit into /src
    mkdir $WORKDIR/src && git --work-tree=$WORKDIR/src --git-dir=$WORKDIR/repo.git checkout main -f

    # delete existing code
    rm -rf $WORKDIR/app/*
    rm -rf $WORKDIR/html/*

    # move relevant parts out of /src
    mv $WORKDIR/src/tiny $WORKDIR
    mv $WORKDIR/src/html $WORKDIR/$PUBLIC_DIR_NAME
    mv $WORKDIR/src/composer.json $WORKDIR
    rm -Rf $WORKDIR/src

    # run composer install
    cd $WORKDIR && composer update

    # finish
    $POST_DEPLOY_COMMAND > /dev/null 2>&1
    composer install --no-dev --optimize-autoloader
  else
    # only the main branch may be deployed on this server
    echo "Ref $ref received. Nothing to do"
  fi
done

Finally, make this file executable:

$ chmod +x /home/webapp/.git/hooks/post-receive

On your workstation (or CI/CD), create another remote for the repository named deploy and mirror to it, creating a new “main” branch there.

$ git remote add deploy ssh://USER@SERVER:PORT/home/webapp/repo.git
$ git push deploy +main:refs/heads/main

On the server, /home/webapp should now contain a copy of your files, independent of any .git metadata.

For all future deployments, use:

$ git push deploy

This will transfer any new commits to the remote repository, where the post-receive hook will immediately update the website for you.