# Implementing a Detailed Backup & Restoration Plan for a Web Application ## Assumptions - **Web Server:** Apache - **Database:** MySQL - **Programming Language:** Python (using Django Framework) - **Linux Distribution:** Ubuntu Server 20.04 LTS ------------ ## Backup Software Utilities 1. **`rsync:`** Primary Tool for system backups, including code, configuration, and static assets - If not installed by default, can be installed with: `sudo apt-get install rsync` 2. **`mysqldump:`** Dedicated tool to create consistent, portable backups of the MySQL database - Part of the MySQL server package, can be installed with: `sudo apt-get install mysql-client` 3. **`tar:`** Bundles together the individual backups into a single, optionally compressed backup file for easier management and off-site storage - Pre-installed on most if not all Linux systems 4. **`cron:`** Automates the backup process based on your defined backup schedule - Pre-installed on most if not all Linux systems **Example Usage** Let's show what a sample `cron` job would look like for a daily differential backup: 1. **Create a backup script:** Make a file named `backup.sh` with the `rsync`, `mysqldump`, and `tar` commands. 2. **Make it executable:** `chmod +x backup.sh` 3. **Edit crontab:** `crontab -e` 4. **Add the schedule. Example for daily at 11 PM:** ``` 0 23 * * * /path/to/backup.sh ``` ------- ## Backup Procedure #backup_procedure 1. Application Code & Configurations (Using `rsync` gives us flexibility and efficiency): ```bash rsync -avz /var/www/html/mywebapp /backup/code_backup rsync -avz /etc/apache2 /backup/config_backup ``` - `-a`: archive mode; Preserves file permissions, ownerships, and timestamps. - `-v`: verbose; Provides output for progress monitoring. - `-z`: compression; Compresses data during transfer, especially useful for large files and when sending backups over networks **Important:** - Consider excluding temporary directories since they can change frequently and increase backup size without real value --------------------------- 2. Database Backup (`mysqldump` provides options for a tailored database export): ```bash mysqldump -u [username] -p [database_name] > /backup/database_backup.sql ``` - `-u [username]`: Specifies the user's database with appropriate permissions - `-p`: Prompts the user's password for security - `[database_name]`: The name of the database you want to backup **Important:** - If your database is very large, consider adding the `--quick` option to `mysqldump` for potentially faster backups --------------------- 3. Compression and Archiving (Using `tar` bundles the backup pieces for convenience): ```bash tar -czvf /backup/full_backup_$(date +%Y-%m-%d).tar.gz /backup/code_backup /backup/config_backup /backup/database_backup.sql ``` - `-c`: create; Creates a new archive. - `-z`: `gzip` compression; Compresses the archive to save space. - `-v`: verbose; Shows progress of compression. - `-f`: filename; Specifies the name of the output archive file. The specifier `$(date +%Y-%m-%d)` dynamically adds the current date to easily identify backup timestamps. **Important:** - Ensure you have sufficient storage space for your compressed backups. - Decide on a specific compression method based on the desired speed vs compression ratio (`gzip` vs. `bzip2`). ------- 4. Off-site Backup (Optional, but **highly** recommended; `rclone` offers versatility for various cloud providers): - First, employ a cloud storage provider like AWS S3 or Google Cloud Storage - Then, utilize a tool like `rclone` to sync backup files to cloud storage: ```bash rclone sync /backup/ aws-s3:my-backup-bucket ``` - `rclone` needs configuration with credentials and details for your chosen cloud storage system - The above command synchronizes changes, sending only new or modified files to the cloud **Important:** - Off-site backups are crucial protection against disasters that could affect your primary server location ------- ## Example Full Backup Script ```bash #!/bin/bash # Backup directories CODE_BACKUP_DIR="/backup/code_backup" CONFIG_BACKUP_DIR="/backup/config_backup" DATABASE_BACKUP_FILE="/backup/database_backup.sql" FULL_BACKUP_DIR="/backup" # Backup application code and configurations rsync -avz /var/www/html/mywebapp $CODE_BACKUP_DIR rsync -avz /etc/apache2 $CONFIG_BACKUP_DIR # Backup database mysqldump -u [username] -p [database_name] > $DATABASE_BACKUP_FILE # Create compressed archive tar -czvf $FULL_BACKUP_DIR/full_backup_$(date +%Y-%m-%d).tar.gz $CODE_BACKUP_DIR $CONFIG_BACKUP_DIR $DATABASE_BACKUP_FILE # Optional: Sync to cloud storage rclone sync $FULL_BACKUP_DIR aws-s3:my-backup-bucket ``` **CRON** ==== ```bash crontab -e ``` - Open your user's crontab file for editing ```bash 0 1 * * * /path/to/backup.sh ``` - `0`: Minute (0) - `1`: Hour (1 AM) - `*`: Every day of the month - `*`: Every month - `*`: Every day of the week - `/path/to/backup.sh`: The full path to the backup script Other Possible Variations: - **Weekly at Midnight Sunday:** ```bash 0 0 * * 0 /path/to/backup.sh ``` - **Twice a Day (Noon and Midnight):** ```bash 0 0,12 * * * /path/to/backup.sh ``` - **First day of Every Month at 3 AM:** ``` ```bash 0 3 1 * * /path/to/backup.sh ``` ------------ ## Restoration Procedure 0. Pre-Restoration Checks: - Verify your backup's integrity before attempting a restoration - Ensure you have sufficient disk space for restoring the backup - Order of restoration might matter. For example, if the code expects the database to be running during setup, then restore the database before the code assets. - Possible slight environment changes (i.e., the database connection details if the server's IP address has changed) 1. Install Bash Dependencies: Start with a fresh install of the base OS. After, we need the core components to run the application ```bash sudo apt-get update sudo apt-get install apache2 mysql-server python3-django # And other core dependencies ``` - `apache2`: Your web server software. - `mysql-server`: Database server to run MySQL. - `python3-django`: The core Python framework and any other dependencies required by the web application. **Important:** - Ensure you are keeping compatibility between versions. (installing the same versions as the ones you uninstalled) - Consider having a dedicated requirements.txt for Python-based apps that will ease the installation. ---- 2. Restore Application Code & Configurations: `rsync` efficiently brings back code and configs from backup ```bash rsync -avz /backup/code_backup /var/www/html/mywebapp rsync -avz /backup/config_backup /etc/apache2 ``` - `-a`: archive mode; Preserves file permissions, ownerships, and timestamps. - `-v`: verbose; Provides output for progress monitoring. - `-z`: compression; Compresses data during transfer, especially useful for large files and when sending backups over networks - Same flags as in #backup_procedure part 1. **Important:** - If major changes were made to the server environment, like directory paths changing, adjust your restoration `rsync` commands accordingly. ------ 3. Restore Databases: Reimport the database dump created by `mysqldump` ```bash mysql -u [username] -p [database_name] < /backup/database_backup.sql ``` - `-u [username] -p`: Provide the credentials (user and password) to create and modify the database. - `[database_name]`: If the database doesn't exist, it will be created. Be careful if the database name pre-exists to avoid overwriting existing data. **Important:** - Consider using the `--one-transaction` option with `mysqldump` when backing up your database if your database engine supports it. This helps maintain data consistency during restoration. ---- 4. Apply Permissions and Restart Services: Ensures the web application can be access and modified by your web server ```bash sudo chown -R www-data:www-data /var/www/html/mywebapp # Adjust ownership sudo systemctl restart apache2 sudo systemctl restart mysql ``` - `chown -R www-data:www-data /var/www/html/mywebapp`: Sets the ownership of the web application directory to the user and group that your web server runs as (which is often 'www-data'). - `systemctl restart apache2`: Restarts the Apache service to apply configuration settings. - `systemctl restart mysql`: Restarts the MySQL service to ensure the database is accessible. ---- ## Backup Schedule - **Daily Differential Backups**: - Backing up changes since the last full backup. This keeps smaller backup files. - **Weekly Full Backups**: - Creates a complete, independent backup. - **Monthly Off-site Backups:** - Sends a full backup to cloud storage for disaster recovery. ## Backup Retention - Keep the latest **7 daily backups** - Keep the latest **4 weekly backups** - Keep the latest **6 monthly backups** ---- ## Testing Plan 1. **Frequency**: Quarterly or after any major code/infrastructure changes. 2. **Test Environment**: Set up a separate staging server that mirrors the production environment. 3. **Procedure**: - Perform a simulated full restoration using backups on the staging server. - Verify the application runs properly, including the database data. - Use a checklist to track all restoration procedure for any deviations or needed updates.