#!/usr/bin/env scotty # @servers remote=deployer@your-server.com
# @macro deploy pullCode runComposer runMigrations clearCaches restartWorkers APP_DIR="/var/www/my-app"
BRANCH="${BRANCH:-main}" # @task on:remote confirm="Deploy to production?"
pullCode() { cd $APP_DIR -weight: 500;">git pull origin $BRANCH
} # @task on:remote
runComposer() { cd $APP_DIR composer -weight: 500;">install --no-interaction --prefer-dist --optimize-autoloader --no-dev
} # @task on:remote
runMigrations() { cd $APP_DIR php artisan migrate --force
} # @task on:remote
clearCaches() { cd $APP_DIR php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache
} # @task on:remote
restartWorkers() { cd $APP_DIR php artisan horizon:terminate
}
#!/usr/bin/env scotty # @servers remote=deployer@your-server.com
# @macro deploy pullCode runComposer runMigrations clearCaches restartWorkers APP_DIR="/var/www/my-app"
BRANCH="${BRANCH:-main}" # @task on:remote confirm="Deploy to production?"
pullCode() { cd $APP_DIR -weight: 500;">git pull origin $BRANCH
} # @task on:remote
runComposer() { cd $APP_DIR composer -weight: 500;">install --no-interaction --prefer-dist --optimize-autoloader --no-dev
} # @task on:remote
runMigrations() { cd $APP_DIR php artisan migrate --force
} # @task on:remote
clearCaches() { cd $APP_DIR php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache
} # @task on:remote
restartWorkers() { cd $APP_DIR php artisan horizon:terminate
}
#!/usr/bin/env scotty # @servers remote=deployer@your-server.com
# @macro deploy pullCode runComposer runMigrations clearCaches restartWorkers APP_DIR="/var/www/my-app"
BRANCH="${BRANCH:-main}" # @task on:remote confirm="Deploy to production?"
pullCode() { cd $APP_DIR -weight: 500;">git pull origin $BRANCH
} # @task on:remote
runComposer() { cd $APP_DIR composer -weight: 500;">install --no-interaction --prefer-dist --optimize-autoloader --no-dev
} # @task on:remote
runMigrations() { cd $APP_DIR php artisan migrate --force
} # @task on:remote
clearCaches() { cd $APP_DIR php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache
} # @task on:remote
restartWorkers() { cd $APP_DIR php artisan horizon:terminate
}
scotty run deploy --pretend
scotty run deploy --pretend
scotty run deploy --pretend
composer global require spatie/scotty
composer global require spatie/scotty
composer global require spatie/scotty
composer global config bin-dir --absolute
composer global config bin-dir --absolute
composer global config bin-dir --absolute
scotty list
scotty list
scotty list
scotty init
scotty init
scotty init
/var/www/my-app/
├── current -> /var/www/my-app/releases/20260406-140000
├── persistent/
│ └── storage/
├── releases/
│ ├── 20260406-130000/
│ └── 20260406-140000/
└── .env
/var/www/my-app/
├── current -> /var/www/my-app/releases/20260406-140000
├── persistent/
│ └── storage/
├── releases/
│ ├── 20260406-130000/
│ └── 20260406-140000/
└── .env
/var/www/my-app/
├── current -> /var/www/my-app/releases/20260406-140000
├── persistent/
│ └── storage/
├── releases/
│ ├── 20260406-130000/
│ └── 20260406-140000/
└── .env
#!/usr/bin/env scotty # @servers local=127.0.0.1 remote=deployer@your-server.com
# @macro deploy startDeployment cloneRepository runComposer buildAssets updateSymlinks migrateDatabase blessNewRelease cleanOldReleases BASE_DIR="/var/www/my-app"
RELEASES_DIR="$BASE_DIR/releases"
PERSISTENT_DIR="$BASE_DIR/persistent"
CURRENT_DIR="$BASE_DIR/current"
NEW_RELEASE_NAME=$(date +%Y%m%d-%H%M%S)
NEW_RELEASE_DIR="$RELEASES_DIR/$NEW_RELEASE_NAME"
REPOSITORY="your-org/your-repo"
BRANCH="${BRANCH:-main}" # @task on:local
startDeployment() { -weight: 500;">git checkout $BRANCH -weight: 500;">git pull origin $BRANCH
} # @task on:remote
cloneRepository() { [ -d $RELEASES_DIR ] || mkdir -p $RELEASES_DIR [ -d $PERSISTENT_DIR ] || mkdir -p $PERSISTENT_DIR [ -d $PERSISTENT_DIR/storage ] || mkdir -p $PERSISTENT_DIR/storage cd $RELEASES_DIR -weight: 500;">git clone --depth 1 --branch $BRANCH -weight: 500;">git@github.com:$REPOSITORY $NEW_RELEASE_NAME
} # @task on:remote
runComposer() { cd $NEW_RELEASE_DIR ln -nfs $BASE_DIR/.env .env composer -weight: 500;">install --prefer-dist --no-dev -o
} # @task on:remote
buildAssets() { cd $NEW_RELEASE_DIR -weight: 500;">npm ci -weight: 500;">npm run build rm -rf node_modules
} # @task on:remote
updateSymlinks() { rm -rf $NEW_RELEASE_DIR/storage cd $NEW_RELEASE_DIR ln -nfs $PERSISTENT_DIR/storage storage
} # @task on:remote
migrateDatabase() { cd $NEW_RELEASE_DIR php artisan migrate --force
} # @task on:remote
blessNewRelease() { ln -nfs $NEW_RELEASE_DIR $CURRENT_DIR cd $NEW_RELEASE_DIR php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache php artisan cache:clear php artisan horizon:terminate -weight: 600;">sudo -weight: 500;">service php8.4-fpm -weight: 500;">restart
} # @task on:remote
cleanOldReleases() { cd $RELEASES_DIR ls -dt $RELEASES_DIR/* | tail -n +4 | xargs rm -rf
}
#!/usr/bin/env scotty # @servers local=127.0.0.1 remote=deployer@your-server.com
# @macro deploy startDeployment cloneRepository runComposer buildAssets updateSymlinks migrateDatabase blessNewRelease cleanOldReleases BASE_DIR="/var/www/my-app"
RELEASES_DIR="$BASE_DIR/releases"
PERSISTENT_DIR="$BASE_DIR/persistent"
CURRENT_DIR="$BASE_DIR/current"
NEW_RELEASE_NAME=$(date +%Y%m%d-%H%M%S)
NEW_RELEASE_DIR="$RELEASES_DIR/$NEW_RELEASE_NAME"
REPOSITORY="your-org/your-repo"
BRANCH="${BRANCH:-main}" # @task on:local
startDeployment() { -weight: 500;">git checkout $BRANCH -weight: 500;">git pull origin $BRANCH
} # @task on:remote
cloneRepository() { [ -d $RELEASES_DIR ] || mkdir -p $RELEASES_DIR [ -d $PERSISTENT_DIR ] || mkdir -p $PERSISTENT_DIR [ -d $PERSISTENT_DIR/storage ] || mkdir -p $PERSISTENT_DIR/storage cd $RELEASES_DIR -weight: 500;">git clone --depth 1 --branch $BRANCH -weight: 500;">git@github.com:$REPOSITORY $NEW_RELEASE_NAME
} # @task on:remote
runComposer() { cd $NEW_RELEASE_DIR ln -nfs $BASE_DIR/.env .env composer -weight: 500;">install --prefer-dist --no-dev -o
} # @task on:remote
buildAssets() { cd $NEW_RELEASE_DIR -weight: 500;">npm ci -weight: 500;">npm run build rm -rf node_modules
} # @task on:remote
updateSymlinks() { rm -rf $NEW_RELEASE_DIR/storage cd $NEW_RELEASE_DIR ln -nfs $PERSISTENT_DIR/storage storage
} # @task on:remote
migrateDatabase() { cd $NEW_RELEASE_DIR php artisan migrate --force
} # @task on:remote
blessNewRelease() { ln -nfs $NEW_RELEASE_DIR $CURRENT_DIR cd $NEW_RELEASE_DIR php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache php artisan cache:clear php artisan horizon:terminate -weight: 600;">sudo -weight: 500;">service php8.4-fpm -weight: 500;">restart
} # @task on:remote
cleanOldReleases() { cd $RELEASES_DIR ls -dt $RELEASES_DIR/* | tail -n +4 | xargs rm -rf
}
#!/usr/bin/env scotty # @servers local=127.0.0.1 remote=deployer@your-server.com
# @macro deploy startDeployment cloneRepository runComposer buildAssets updateSymlinks migrateDatabase blessNewRelease cleanOldReleases BASE_DIR="/var/www/my-app"
RELEASES_DIR="$BASE_DIR/releases"
PERSISTENT_DIR="$BASE_DIR/persistent"
CURRENT_DIR="$BASE_DIR/current"
NEW_RELEASE_NAME=$(date +%Y%m%d-%H%M%S)
NEW_RELEASE_DIR="$RELEASES_DIR/$NEW_RELEASE_NAME"
REPOSITORY="your-org/your-repo"
BRANCH="${BRANCH:-main}" # @task on:local
startDeployment() { -weight: 500;">git checkout $BRANCH -weight: 500;">git pull origin $BRANCH
} # @task on:remote
cloneRepository() { [ -d $RELEASES_DIR ] || mkdir -p $RELEASES_DIR [ -d $PERSISTENT_DIR ] || mkdir -p $PERSISTENT_DIR [ -d $PERSISTENT_DIR/storage ] || mkdir -p $PERSISTENT_DIR/storage cd $RELEASES_DIR -weight: 500;">git clone --depth 1 --branch $BRANCH -weight: 500;">git@github.com:$REPOSITORY $NEW_RELEASE_NAME
} # @task on:remote
runComposer() { cd $NEW_RELEASE_DIR ln -nfs $BASE_DIR/.env .env composer -weight: 500;">install --prefer-dist --no-dev -o
} # @task on:remote
buildAssets() { cd $NEW_RELEASE_DIR -weight: 500;">npm ci -weight: 500;">npm run build rm -rf node_modules
} # @task on:remote
updateSymlinks() { rm -rf $NEW_RELEASE_DIR/storage cd $NEW_RELEASE_DIR ln -nfs $PERSISTENT_DIR/storage storage
} # @task on:remote
migrateDatabase() { cd $NEW_RELEASE_DIR php artisan migrate --force
} # @task on:remote
blessNewRelease() { ln -nfs $NEW_RELEASE_DIR $CURRENT_DIR cd $NEW_RELEASE_DIR php artisan config:cache php artisan route:cache php artisan view:cache php artisan event:cache php artisan cache:clear php artisan horizon:terminate -weight: 600;">sudo -weight: 500;">service php8.4-fpm -weight: 500;">restart
} # @task on:remote
cleanOldReleases() { cd $RELEASES_DIR ls -dt $RELEASES_DIR/* | tail -n +4 | xargs rm -rf
}
scotty run deploy
scotty run deploy
scotty run deploy
scotty run deploy --branch=develop
scotty run deploy --branch=develop
scotty run deploy --branch=develop