萬神殿託管網站的自動備份腳本

已發表: 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

現在我們不需要像以前那樣手動進行所有備份,因為該過程是完全自動化的。 此外,我們還為日常工作流程節省了一些時間。