# Backing up Apidog


To protect your application data (including teams, projects, APIs, and more), it's essential to perform regular backups.

Apidog relies on a single SQL database to store most of its runtime application data. By backing up this database, you safeguard the majority of your data. In the event of an issue, such as during an upgrade, you can use this backup to restore your Apidog installation.

## Backing Up the Application Database

### Amazon RDS for the Application Database

Amazon Web Services (AWS) provides established best practices for backing up and restoring Amazon RDS databases. We strongly recommend adhering to these guidelines and enabling Automated RDS Backups for enhanced reliability and data protection.

For detailed instructions, please refer to the [Amazon RDS User Guide](http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_WorkingWithAutomatedBackups.html).

### Self-Hosted MySQL or MariaDB Database

If you are hosting your own MySQL or MariaDB database, you should follow the standard procedures for backing up your database. For instance, when using MySQL for your application database, refer to MySQL’s official documentation for [backing up your database](https://dev.mysql.com/doc/refman/8.0/en/backup-methods.html).

As long as you have a backup (dump) of the Apidog database, your data should be secure and easily restorable.

#### Scheduling Automated Backups

The following script provides an example for automating the backup process of your MySQL Docker instance data.

By default, this script is designed to align with the instructions outlined in our [Docker Compose Setup Guide](https://self-hosting.apidog.io/running-apidog-on-docker-405306m0#install-docker-compose-if-necessary).

1.  Create the backup script by executing `touch /root/backups/mysql-backup.sh`. Ensure that you replace `<password>` in the `DB_PASS` variable with your actual MySQL root password.

```bash
#!/bin/sh

# --- Configuration ---
# The name of your MySQL Docker container
CONTAINER_NAME="mysql8"

# The directory on the host machine where backups will be stored
BACKUP_DIR="/root/backups/mysql"

# MySQL credentials
# Note: Storing passwords directly in scripts can be a security risk if multiple users have access to this file on your server.
# For production environments, consider using Docker secrets or environment variables.
DB_USER="root"
DB_PASS="<password>"

# --- Apidog File Data (Optional) ---
# If you are not using object storage (e.g., AWS S3/Minio), you must also back up the file data.
# Set the path to the Apidog data volume on your host. Leave this empty to skip file data backup.
# Example: "/var/lib/docker/volumes/apidog-ee_apidog_uploads/_data"
APIDOG_DATA_DIR=""
APIDOG_BACKUP_DIR="/root/backups/apidog-files"


# --- Script Logic ---
# Create a timestamp for the backup file
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
DB_FILENAME="mysql_backup_$TIMESTAMP.sql"
DB_FILE_PATH_IN_CONTAINER="/tmp/$DB_FILENAME"

# Ensure the backup directory exists on the host
mkdir -p "$BACKUP_DIR"
echo "Starting backup for container '$CONTAINER_NAME'..."

# 1. Execute mysqldump inside the container
# We use 'sh -c' to properly handle the output redirection '>' inside the container.
docker exec "$CONTAINER_NAME" sh -c "mysqldump -h 127.0.0.1 -P 3306 -u'$DB_USER' -p'$DB_PASS' --all-databases --default-character-set=utf8mb4 > $DB_FILE_PATH_IN_CONTAINER"

# Check if the mysqldump command was successful
if [ $? -ne 0 ]; then
  echo "Error: mysqldump failed. Aborting."
  exit 1
fi

# 2. Copy the backup file from the container to the host
docker cp "$CONTAINER_NAME:$DB_FILE_PATH_IN_CONTAINER" "$BACKUP_DIR/$DB_FILENAME"

# 3. Clean up the temporary backup file inside the container
docker exec "$CONTAINER_NAME" rm "$DB_FILE_PATH_IN_CONTAINER"

echo "Database backup successful: $BACKUP_DIR/$DB_FILENAME"

# --- Backup Apidog File Data (if configured) ---
if [ -n "$APIDOG_DATA_DIR" ]; then
    mkdir -p "$APIDOG_BACKUP_DIR"
    FILE_BACKUP_FILENAME="apidog_files_$TIMESTAMP.tar.gz"
    echo "Backing up Apidog file data from $APIDOG_DATA_DIR..."
    tar -czf "$APIDOG_BACKUP_DIR/$FILE_BACKUP_FILENAME" -C "$(dirname "$APIDOG_DATA_DIR")" "$(basename "$APIDOG_DATA_DIR")"
    echo "File data backup successful: $APIDOG_BACKUP_DIR/$FILE_BACKUP_FILENAME"
fi


# 4. Clean up old backups on the host (optional, keeps last 7 days)
echo "Cleaning up old backups..."
find "$BACKUP_DIR" -type f -name "*.sql" -mtime +7 -delete
if [ -n "$APIDOG_DATA_DIR" ]; then
    find "$APIDOG_BACKUP_DIR" -type f -name "*.tar.gz" -mtime +7 -delete
fi

echo "Backup process complete."
```

2.  To grant execute permissions to the script, run the following command:
        ```bash
        chmod 700 mysql-backup.sh`
        ```
3.  Add the desired crontab configuration to schedule the script. To edit the crontab file, execute the following command `crontab -e`:

    ```
    10 23 * * * sh /root/backups/mysql-backup.sh
    ```

### Troubleshooting

If you encounter issues during the cleanup process, consider the following:

1. **Permission Denied**: Ensure that you are using the correct MySQL credentials with appropriate permissions.
2. **Container Not Found**: Double-check the MySQL container name and confirm that the container is running.
3. **Database Locked**: Verify that no other processes are currently accessing or locking the database.

## Backing Up Other Data

Certain data, such as automated testing reports, user-uploaded files, and project icons, are not stored within the database. If you have configured an object storage service, these files will be stored externally. For backup purposes, refer to the backup strategies provided by the respective object storage service.

- **Amazon S3:** Amazon provides comprehensive best practices for backing up and restoring S3 data. We recommend enabling automated backups for S3. For more details, refer to the official guide: [Using AWS Backup for Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/backup-for-s3.html)
- **MinIO:** MinIO also offers its own guidelines for data backup and recovery. For detailed instructions, refer to the [Minio Documentation](https://min.io/docs/minio/container/index.html).

If you have not configured an object storage service, Apidog will store these files locally by default. In this case, we recommend regular file-based backups. To automate this process, you can modify the `APIDOG_DATA_DIR` value in the Scheduling Automated Backups script to match your actual data directory.

## Resetting the Database for Proof-of-Concept (POC) Deployments

:::warning[Warning]
This section is intended exclusively for POC (Proof of Concept) environments. **Never** perform these operations in production, as they will permanently delete all Apidog data.
:::

In POC deployments, you may need to completely reset the Apidog database to start fresh. This process involves dropping the existing database and creating a new one. Proceed with caution, and ensure that you have adequate backups before performing this operation.


```bash
docker exec -it mysql8 mysql -u root -p -e "
DROP DATABASE IF EXISTS apidog;
CREATE DATABASE IF NOT EXISTS apidog DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
SHOW DATABASES;
"
```
