# Database Backups

A daily `mysqldump` of the MySQL database, gzipped into `storage/app/backups/`, rotated after 30 days.

The script reads all credentials from `.env` — nothing is hardcoded.

## One-time server setup

1. Install the client tools if missing:

   ```bash
   sudo apt install mysql-client   # or default-mysql-client
   ```

2. Test a backup by hand from the Laravel app root:

   ```bash
   bash backup-db
   ```

   Confirm it prints `Done` and that `storage/app/backups/` contains a non-trivial `.sql.gz`.

3. Install the cron entry (`crontab -e`), e.g. 03:10 every night:

   ```cron
   10 3 * * * cd /path/to/turista && bash backup-db >> storage/logs/backup.log 2>&1
   ```

## Options

- **Retention:** default 30 days. Override per run or in cron with `BACKUP_KEEP_DAYS=60 bash backup-db`.
- **Destination:** default `storage/app/backups/`. Override with `BACKUP_DIR=/secure/location bash backup-db`.
  `storage/app` is typically not web-served, but placing backups outside the app tree is safer.

## Off-site copies (recommended)

Local backups do not survive a disk failure or a compromised server. Sync them elsewhere, e.g. add after the dump in cron, or a second cron entry:

```cron
30 3 * * * rsync -a --remove-source-files /path/to/turista/storage/app/backups/ backupuser@offsite-host:/srv/backups/turista/
```

Or upload to S3-compatible storage with `aws s3 sync`.

## Restoring

```bash
gunzip < storage/app/backups/turista-YYYYMMDD-HHMMSS.sql.gz \
  | mysql --host=127.0.0.1 --user=root turista
```

> **Production note:** restore into a fresh database first (`turista_restore`), inspect it, and only then switch `DB_DATABASE` in `.env` — never pipe a dump directly over the live database.

## What is not covered

- Media/uploads stored on disk are **not** included — this dumps the MySQL database only. Back up the uploads directory separately if it holds user files.