万神殿托管网站的自动备份脚本

已发表: 2023-03-28

DigiSavvy 在 Pantheon 上托管许多网站。 付费计划的站点启用了自动备份,但尚未付费计划的站点没有此功能; 这是我们要解决的问题的核心。 因此,我们需要创建一个脚本,为那些没有自动备份功能的网站运行每日备份。

进入 Automate Pantheon 备份工作流程

我们知道这可以通过混合使用 Terminus、Bash 和 Linux cronjobs 等工具来实现。 经过一番讨论,我们开始研究一种解决方案,使非付费 Pantheon 站点的 Pantheon 备份过程自动化。

解决方案

我们创建了一个每天运行的 bash 脚本来备份所有没有自动备份功能的 Pantheon 网站。

此外,还会向我们的 Slack 频道发送一条通知消息,告知我们可能出现的错误或问题。

要求

您将需要一些特定的环境和工具来实施此解决方案。 确保设置这些项目。

  • 具有 SSH 访问权限的 Ubuntu 服务器:需要高级服务器定制来安装一些工具并解决可能的问题。 我们使用 Ubuntu,但您可以使用您喜欢的 Linux 风格。
  • Terminus :这是官方的 Pantheon CLI 工具。 它需要安装在您的 Ubuntu 服务器上。
  • Slack App :可选,但在备份运行后触发通知是必需的。 按照本教程进行配置。 另外,请记住将应用程序添加到您要发送通知的频道。

编写脚本

需要使用 bash 语法编写脚本是必要的,因为我们需要进行一些条件检查并执行一些 Linux 和 Terminus 命令。

备份 bash 脚本

此 bash 脚本遍历网站字符串标识符数组,并使用 Terminus 命令terminus backup:create为每个标识符创建一个备份。 --keep-for选项确定保留期(以天为单位)以保留备份。

 #!/bin/sh # Exit on error set -e # Stash list of all Pantheon sites in the org PANTHEON_SITES=("site1.env" "site2.env" "site3.env") # Loop through each site in the list for sitename in ${PANTHEON_SITES[@]}; do terminus backup:create --keep-for 30 $sitename done

Terminus 命令结构通常包括<site>.<env>确定要执行的目标站点和环境。

请注意,<> 符号是示例的一部分,不应包含在您的 Terminus 命令中。

此外,在使用任何命令之前,Terminus 必须使用机器令牌进行身份验证。 您可能还需要设置 SSH 密钥访问以执行远程指令。

在我们的案例中,我们实施的用于自动化 Pantheon 备份过程的脚本并没有托管在它上面,而是托管在另一台服务器上。 因此,我们必须设置 SSH 密钥访问。

检查备份状态

我们编写了另一个 bash 脚本来检查备份脚本创建的所有备份的状态。

脚本中定义了两个数组,一个用于备份网站字符串标识符,另一个用于单个备份的每个部分。

每个 Pantheon 备份都包含三个文件。

  • 代码:通过站点仪表板控制和提交的任何版本。 不备份未提交的 SFTP 代码更改。
  • 文件:图像和资产存储在 WordPress 的标准上传路径wp-content/uploads和 Drupal 的sites/all/default/files中。
  • 数据库:是您站点数据库的 MySQL 转储。

当这三个文件可供下载时,备份成功。

然而,有时这些文件中的一些不会被创建,因为 Terminus 在备份过程中的某个时刻失败了。

该脚本使用 Terminus 命令terminus backup:get来检查这三个文件是否存在。 如果这三个文件中的任何一个丢失,则备份状态将被视为失败。

每次备份检查的结果都保存在一个名为backups_results.txt的文件中。 backups_results.txt包含 JSON 对象的字符串表示形式。 该对象对每个备份网站都有一个条目。

 #!/bin/sh # Stash list of all Pantheon sites in the org PANTHEON_SITES=("site1.env" "site2.env" "site3.env") FILES=("code" "files" "database") backups_checks='{' # JSON file with all the websites with a true variable. This file will save the backup status of each website # Loop through each site in the list to check the backups for sitename in ${PANTHEON_SITES[@]}; do check_result=true # Assume the backup was sucefully made # Each backup has a code, files and database file. If one of these is missing, Pantheon reports the back as failed. for file_type in ${FILES[@]}; do result=$(terminus backup:get --no-ansi --element $file_type $sitename) if [ -z "$result" ] then # Edit the corresponding JSON entry to false. check_result=false fi done # Save true or false in a json file. That file will be used by a php script to generate the Slack notification backups_checks+="\\"$sitename\\":\\"$check_result\\"," done # Remove last character ',' backups_checks=${backups_checks:0:-1} backups_checks+="}" echo $backups_checks > backups_results.txt

松弛通知——可选

最后,我们创建了一个 PHP 文件来使用 Slack API 发送通知。 首先,使用file_get_contents()函数提取“backups_results.txt”中的字符串,并使用函数json_decode()将其转换为有效的 PHP 变量。 此变量将有助于设置创建 Slack 消息所需的逻辑。 该代码遍历 overreach 网站并为每个网站创建一个通知。 该消息将根据其上次备份的状态而有所不同。

使用端点chat.postMessage将消息发送到特定的 Slack 通道。 您还可以使用端点conversations.list来查找要将消息发送到的通道 ID。

 <?php $backups_results_file = file_get_contents( 'backups_results.txt' ); $backups_results = json_decode( $backups_results_file, true ); slack_post( $backups_results ); /** * POST the message to the Slack channel named 'client-support' */ function slack_post( $backups_results ) { $ch = curl_init(); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt( $ch, CURLOPT_TIMEOUT, 10 ); curl_setopt( $ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Authorization: Bearer your-slack-token', ) ); # The id of the client-support channel. The channel id could be retrieved using this function $channel_; # Prepare the slack message $slack_blocks = array( array( 'type' => 'section', 'text' => array( 'type' => 'plain_text', 'emoji' => true, 'text' => 'Some Pantheon backups were made', ), ), array( 'type' => 'divider', ), ); foreach ( $backups_results as $website_name => $website_backup_status ) { $website_dashboard = shell_exec( "terminus dashboard:view --print -- $website_name" ); if ( $website_backup_status ) { $status_icon = ':white_check_mark:'; $status_text = "*Website $website_name* \\n The backup was successfully made $status_icon \\n Visit $website_dashboard to download the backup"; } else { $status_icon = ':x:'; $status_text = "*Website $website_name* \\n The backup could not be completed $status_icon \\n Visit $website_dashboard to manually create the backup"; } $slack_blocks[] = array( 'type' => 'section', 'text' => array( 'type' => 'mrkdwn', 'text' => $status_text, ), ); } $payload = json_encode( array( 'channel' => $channel_id, 'text' => 'Posting to Digisavy client-support channel', 'blocks' => $slack_blocks, ) ); curl_setopt( $ch, CURLOPT_URL, '<https://slack.com/api/chat.postMessage>' ); curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'POST' ); curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload ); $result = curl_exec( $ch ); $result_encode = json_decode( $result ); curl_close( $ch ); }

设置定时任务

cronjob 是备份自动化过程的重要组成部分。 按照后续步骤进行设置。 使用 SHH 访问您的服务器并运行命令crontab -e以打开 cronjob 配置文件。

crontab 文件由命令组成,每行一个命令,这些命令在每个命令行的前五个字段指定的时间自动执行。 crontab 文件中的每个命令都必须包含一行,即使该行很长。 crontab 文件不识别额外的回车符。

如果您在生成 cron 命令和配置计划语法方面需要帮助,那么这个 crontab 生成器可以提供帮助。

您的 cron 行必须包含

  • 访问脚本所在文件夹的命令
  • 执行脚本的命令。

PATH 变量的目的是让 crontab 知道库在脚本中的位置,例如 Terminus。

这是我们添加到服务器 crontab 文件的行的示例。

 PATH="/path/to/backup/scripts/.local/bin:/usr/bin:/bin:/usr/local/bin" #Pantheon backups 0 11 * * * cd /path/to/backup/scripts/; bash pantheon-backups.sh; bash pantheon-backups-check.sh; php slack-notification.php >/dev/null 2>&1

现在我们不需要像以前那样手动进行所有备份,因为该过程是完全自动化的。 此外,我们还为日常工作流程节省了一些时间。