Laravel Project Backup to Azure Blob with Bash Script

If you’re running a Laravel app and want an easy way to back it up to Azure Blob Storage without Docker images or third-party SaaS tools, here’s a self-contained Bash script that does exactly that.

It backs up:

Your Laravel project files (with exclu…


This content originally appeared on DEV Community and was authored by Edgaras

If you’re running a Laravel app and want an easy way to back it up to Azure Blob Storage without Docker images or third-party SaaS tools, here’s a self-contained Bash script that does exactly that.

It backs up:

  • Your Laravel project files (with exclusions like vendor/ and logs)
  • Your MySQL database (via mysqldump)
  • Packages everything into a .tar.gz
  • Uploads to Azure Blob Storage using az CLI
  • Cleans up local backups older than X days

Requirements

  • bash, tar, gzip, find
  • mysqldump (MySQL/MariaDB client)
  • Azure CLI

The Script

#!/usr/bin/env bash
set -Eeuo pipefail


# ---- Paths ----
LARAVEL_DIR="/path/to/laravel/project" # Path to your Laravel project root
BACKUP_DIR="/path/to/local/backup/directory" # Local backup directory  

# ---- Azure Storage (account + key) ----
AZURE_STORAGE_ACCOUNT="<ACCOUNT_NAME>"
AZURE_STORAGE_KEY="<ACCOUNT-KEY>"
AZURE_CONTAINER="<CONTAINER-NAME>"

# ---- Retention (local only) ----
RETAIN_LOCAL_DAYS=7

# ---- Backup content exclusion ----
EXCLUDES=(
  "vendor"
  "node_modules"
  "storage/framework/cache"
  "storage/logs"
  ".git"
)

#############################################

timestamp_utc() { date -u +"%Y%m%dT%H%M%SZ"; }

require_cmd() {
  command -v "$1" >/dev/null 2>&1 || { echo "ERROR: Missing required command: $1" >&2; exit 1; }
}

read_env_var() {
  local key="$1"
  local val=""
  if [[ -f "$LARAVEL_DIR/.env" ]]; then
    val="$(grep -E "^${key}=" "$LARAVEL_DIR/.env" 2>/dev/null | tail -n1 | sed -E "s/^${key}=(.*)$/\1/" | tr -d '\r' || true)"
  fi
  if [[ -n "$val" && "${val:0:1}" == '"' && "${val: -1}" == '"' ]]; then
    val="${val:1:-1}"
  elif [[ -n "$val" && "${val:0:1}" == "'" && "${val: -1}" == "'" ]]; then
    val="${val:1:-1}"
  fi
  echo "$val"
}

dump_mysql() {
  local db_host db_port db_name db_user db_pass db_socket dump_path
  db_host="$(read_env_var "DB_HOST")"
  db_port="$(read_env_var "DB_PORT")"
  db_name="$(read_env_var "DB_DATABASE")"
  db_user="$(read_env_var "DB_USERNAME")"
  db_pass="$(read_env_var "DB_PASSWORD")"
  db_socket="$(read_env_var "DB_SOCKET")"
  dump_path="$1"

  require_cmd mysqldump

  db_host="${db_host:-127.0.0.1}"
  db_port="${db_port:-3306}"

  local args=( --user="$db_user" --single-transaction --quick --routines --events --triggers )
  if [[ -n "$db_socket" ]]; then
    args+=( --socket="$db_socket" )
  else
    args+=( --host="$db_host" --port="$db_port" )
  fi

  umask 077
  MYSQL_PWD="$db_pass" mysqldump "${args[@]}" "$db_name" > "$dump_path"
}

make_archive() {
  local src_dir="$1"
  local db_sql="$2"
  local out_tar_gz="$3"

  local stage
  stage="$(mktemp -d)"
  trap 'rm -rf "$stage"' RETURN

  mkdir -p "$stage/site" "$stage/db"

  pushd "$src_dir" >/dev/null
  local tar_excludes=()
  for e in "${EXCLUDES[@]}"; do
    tar_excludes+=( "--exclude=$e" )
  done
  tar -cf - "${tar_excludes[@]}" . | tar -C "$stage/site" -xf -
  popd >/dev/null

  cp "$db_sql" "$stage/db/database.sql"

  tar -C "$stage" -czf "$out_tar_gz" site db
}

upload_with_azcli() {
  local file="$1"
  AZURE_STORAGE_ACCOUNT="$AZURE_STORAGE_ACCOUNT" AZURE_STORAGE_KEY="$AZURE_STORAGE_KEY" \
    az storage blob upload \
      --container-name "$AZURE_CONTAINER" \
      --file "$file" \
      --name "$(basename "$file")" \
      --overwrite true >/dev/null
}

main() {
  [[ -d "$LARAVEL_DIR" ]] || { echo "ERROR: LARAVEL_DIR not found: $LARAVEL_DIR" >&2; exit 1; }
  mkdir -p "$BACKUP_DIR"

  local ts app_name base_name db_dump archive
  ts="$(timestamp_utc)"
  app_name="$(basename "$LARAVEL_DIR")"
  base_name="${app_name}-${ts}"
  db_dump="${BACKUP_DIR}/${base_name}.sql"
  archive="${BACKUP_DIR}/${base_name}.tar.gz"

  echo "[1/4] Dumping MySQL → $db_dump"
  dump_mysql "$db_dump"

  echo "[2/4] Creating archive → $archive"
  make_archive "$LARAVEL_DIR" "$db_dump" "$archive"

  echo "[3/4] Uploading to Azure via az CLI"
  upload_with_azcli "$archive"
  echo "Upload complete: $(basename "$archive")"

  echo "[4/4] Pruning local backups older than ${RETAIN_LOCAL_DAYS}d"
  find "$BACKUP_DIR" -type f -name "${app_name}-*.tar.gz" -mtime +"$RETAIN_LOCAL_DAYS" -print -delete || true
  find "$BACKUP_DIR" -type f -name "${app_name}-*.sql" -mtime +"$RETAIN_LOCAL_DAYS" -print -delete || true

  echo "Done."
}

main "$@"

How It Works

  1. Database Dump

    • Reads DB_HOST, DB_DATABASE, DB_USERNAME, DB_PASSWORD from .env
    • Runs mysqldump
  2. File Packaging

    • Copies project files while excluding unnecessary directories
    • Adds database.sql
    • Compresses into tar.gz
  3. Azure Upload

    • Uses az storage blob upload with AZURE_STORAGE_ACCOUNT + AZURE_STORAGE_KEY
  4. Retention Cleanup

    • Deletes .sql and .tar.gz files older than RETAIN_LOCAL_DAYS

Usage

Save the script:

nano laravel-backup.sh
chmod +x laravel-backup.sh

Configure variables:

  • LARAVEL_DIR
  • BACKUP_DIR
  • AZURE_STORAGE_ACCOUNT
  • AZURE_STORAGE_KEY
  • AZURE_CONTAINER

Run manually:

./laravel-backup.sh

Or schedule with cron:

crontab -e
0 3 * * * /path/to/laravel-backup.sh >> /var/log/laravel-backup.log 2>&1


This content originally appeared on DEV Community and was authored by Edgaras


Print Share Comment Cite Upload Translate Updates
APA

Edgaras | Sciencx (2025-08-25T22:13:48+00:00) Laravel Project Backup to Azure Blob with Bash Script. Retrieved from https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/

MLA
" » Laravel Project Backup to Azure Blob with Bash Script." Edgaras | Sciencx - Monday August 25, 2025, https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/
HARVARD
Edgaras | Sciencx Monday August 25, 2025 » Laravel Project Backup to Azure Blob with Bash Script., viewed ,<https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/>
VANCOUVER
Edgaras | Sciencx - » Laravel Project Backup to Azure Blob with Bash Script. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/
CHICAGO
" » Laravel Project Backup to Azure Blob with Bash Script." Edgaras | Sciencx - Accessed . https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/
IEEE
" » Laravel Project Backup to Azure Blob with Bash Script." Edgaras | Sciencx [Online]. Available: https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/. [Accessed: ]
rf:citation
» Laravel Project Backup to Azure Blob with Bash Script | Edgaras | Sciencx | https://www.scien.cx/2025/08/25/laravel-project-backup-to-azure-blob-with-bash-script/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.