#!/usr/bin/env bash set -euo pipefail # Deploy the current working tree to a remote host using rsync. # Reads defaults from .env.local when present. # Configure via env vars or CLI args: # DEPLOY_USER / $1 : SSH user (e.g. deploy) # PROD_IP / $2 : SSH host/IP (fallback: DEPLOY_HOST) # DEPLOY_PATH / $3 : Remote path (e.g. /var/www/laravel-winary) # Optional: # SSH_OPTS : Extra ssh options (e.g. "-p 2222") # RSYNC_EXCLUDES : Extra rsync --exclude patterns, space-separated SCRIPT_DIR="$(cd "$(dirname "$0")" && cd .. && pwd)" cd "$SCRIPT_DIR" # Load local environment defaults if present if [[ -f ".env.local" ]]; then set -a # shellcheck disable=SC1091 source .env.local set +a fi DEPLOY_USER=${DEPLOY_USER:-${1:-}} # Support legacy DEPLOY_HOST for convenience PROD_IP=${PROD_IP:-${DEPLOY_HOST:-${2:-}}} DEPLOY_PATH=${DEPLOY_PATH:-${3:-}} SSH_OPTS=${SSH_OPTS:-} if [[ -z "$DEPLOY_USER" || -z "$PROD_IP" || -z "$DEPLOY_PATH" ]]; then echo "Usage: DEPLOY_USER=user PROD_IP=host DEPLOY_PATH=/path $0" echo " or: $0 user host /path" echo "Defaults can be set in .env.local" exit 1 fi # Core excludes; adjust RSYNC_EXCLUDES if you need to add more. EXCLUDES=( --exclude ".git" --exclude "node_modules" # Only skip the top-level public build; keep storage/app/public uploads --exclude "/public" --exclude "storage/logs" --exclude "vendor" --exclude ".env.local" ) # Append user-provided extra excludes if [[ -n "${RSYNC_EXCLUDES:-}" ]]; then for pattern in $RSYNC_EXCLUDES; do EXCLUDES+=(--exclude "$pattern") done fi RSYNC_SSH_OPTS=() if [[ -n "$SSH_OPTS" ]]; then RSYNC_SSH_OPTS=(-e "ssh $SSH_OPTS") fi ssh "${DEPLOY_USER}@${PROD_IP}" "\ mkdir -p '${DEPLOY_PATH}'; \ cd '${DEPLOY_PATH}'; \ docker compose -f docker-compose.prod.yml down; \ sudo -S rm -rf storage/framework; \ sudo -S rm -rf bootstrap/cache/; \ sudo -S mkdir -p storage/app/public storage/framework/cache storage/framework/sessions storage/framework/views storage/framework/testing bootstrap/cache; \ sudo -S chown -R '${DEPLOY_USER}':www-data storage bootstrap; \ sudo -S chmod -R u+rwX,g+rwX storage bootstrap; \ sudo -S find storage bootstrap -type d -exec chmod g+s {} +; \ " rsync -avz --delete "${EXCLUDES[@]}" "${RSYNC_SSH_OPTS[@]}" ./ "${DEPLOY_USER}@${PROD_IP}:${DEPLOY_PATH}"