thomas-shirley.com

A post receive hook for composer in production

Picture the scene; you've got a php development project, with local dev-dependencies. You're ready to push to production.

Of course, we don't want to use these dev depedencies in production, we want to use the --no-dev option in our production environment.

But how do we ensure that when we push to production, our local dev-dependancies aren't pushed too?

My solution is to create a post-receive hook, to automatically run a composer install command to download the necessary dependencies, with a --no-dev flag, once the git repo has been checked out into the webroot.

Here's the post receive hook I use.

#!/bin/bash

#Change this to the target directory you want to deploy to:
TARGET_DIR="/var/www/html"
#Change this to the  directory you want to deploy from.
#SRC_DIR="/"
GIT_WORK_TREE="$TARGET_DIR"

while read oldrev newrev refname; do
  #Change _main_ to the name of your deployment branch
  if [ "$refname" = "refs/heads/main" ]; then
  # Remove sudo if you are running on a server with sudo disabled
   sudo git --work-tree="$GIT_WORK_TREE" checkout -f "$newrev"
    echo "Changes from $SRC_DIR directory deployed to $TARGET_DIR"
  fi
done

cd $TARGET_DIR
if sudo composer install --no-dev --optimize-autoloader --no-scripts; then
    echo "Deployment successful"
else
    echo "Composer install failed" >&2
    exit 1
fi

This hook actually deploys the current working tree into the webroot and then runs composer install (to pull the plugins I want) into the webroot.

You need to make sure you are including /vendor in your .gitignore file, to make sure that you don't push your vendor folder to your production server.

Thomas

Thomas - 24-07-2025