Skip to content

Instantly share code, notes, and snippets.

@aozisik
Last active December 29, 2020 08:42
Show Gist options
  • Save aozisik/85410519e0e8bf786f0a97636f471322 to your computer and use it in GitHub Desktop.
Save aozisik/85410519e0e8bf786f0a97636f471322 to your computer and use it in GitHub Desktop.
Zero downtime deploys using Laravel Forge
# Zero-downtime deployment script for Laravel Forge
#
# !!! WARNING FOR FIRST DEPLOYMENT !!!
# 1. Proceed with caution!
# During first setup this script will backup your .env file and storage folder, then DELETE your existing app directory.
# Make sure you don't have any important files inside your app directory and take a backup up beforehand as needed.
#
# 2. Your web server should now point at /current/public instead of /public
#
# 3. Edit these variables to match your project.
FORGE_USER="forge"
PROJECT_NAME="example.com"
PROJECT_REPO="git@github.com:username/repository.git"
RELEASES_KEPT=3
RELEASE=$(date +"%Y%m%d%H%M%S")
# That's it. Now we begin.
# Project directory
PROJECT_DIR="/home/"$FORGE_USER"/"$PROJECT_NAME
# Directory where recent releases are kept
RELEASES_DIR=$PROJECT_DIR"/releases"
# Directory holding the current release
CURRENT_RELEASE_DIR=$RELEASES_DIR"/"$RELEASE
cd "/home/"$FORGE_USER
# If deploying for the first time...
if [ ! -d $PROJECT_NAME"/releases" ]
then
# Create a directory where we'll set-up everything
TMP_DIR=$PROJECT_NAME"-tmp"
mkdir -p $TMP_DIR"/releases"
# Make copies of the storage folder and the .env file
cp $PROJECT_DIR"/.env" $TMP_DIR"/.env"
cp -r $PROJECT_DIR"/storage" $TMP_DIR"/storage"
rm -rf $PROJECT_DIR
mv $TMP_DIR $PROJECT_DIR
fi
# Create new release
mkdir -p $RELEASES_DIR
cd $RELEASES_DIR
git clone --depth 1 $PROJECT_REPO $RELEASE
cd $CURRENT_RELEASE_DIR
# ------------ DEPLOYMENT SCRIPT STARTS HERE -----------
# Install dependencies
$FORGE_COMPOSER install --no-interaction --no-dev --prefer-dist --optimize-autoloader
# Build front-end assets
npm install
npm run production
# Clean up
rm -rf node_modules
rm -rf .git
# Symlink the .env file
ln -sfn $PROJECT_DIR"/.env" $CURRENT_RELEASE_DIR"/.env"
# Symlink the storage folder
rm -rf storage
ln -sfn $PROJECT_DIR"/storage" $CURRENT_RELEASE_DIR"/storage"
if [ -f artisan ]
then
$FORGE_PHP artisan migrate --force
$FORGE_PHP artisan config:cache
$FORGE_PHP artisan route:cache
$FORGE_PHP artisan queue:restart
fi
# ------------ DEPLOYMENT SCRIPT ENDS HERE -----------
# Point the current folder to this release
ln -sfn $CURRENT_RELEASE_DIR $PROJECT_DIR"/current"
# Clean up old releases.
cd $RELEASES_DIR
rm -rf `ls -1 | sort -r | tail -n +$((RELEASES_KEPT+1))`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment