Tự động backup VPS tại Digital Ocean

Hướng dẫn tự động backup VPS tại Digital Ocean hằng ngày, hằng tuần, hằng giờ... tùy theo ý thích của bạn.

Chào các bạn, để backup VPS tại Digital Ocean, chúng ta có thể sử dụng 3 cách:

  1. Sử dụng chức năng tự động backup của Digital Ocean. Tính năng này sẽ tạo 1 snapshot 1 tuần và được tính giá bằng 20% giá của VPS bạn đang sử dụng. Tuy nhiên chỉ tạo 1 bản backup 1 tuần, do đó không phù hợp với những website thường xuyên cập nhật thông tin.
  2. Tự tạo Snapshot bằng tay: Cách này giá rẻ hơn, chỉ $0.05/GB/tháng. Tuy nhiên bất tiện là phải truy cập vào hệ thống hằng ngày để tạo snapshot.
  3. Tạo một ứng dụng web kết hợp với API của Digital Ocean để tự động tạo snapshot theo lịch trình mong muốn: hằng ngày, hằng giờ...

Trong bài viết này mình hướng dẫn các bạn sử dụng cách thứ 3. Bởi theo mình nó an toàn và hiệu quả nhất.

Công việc cần làm: 

  • Tạo Access token từ Digital Ocean
  • Viết Php script
  • Tạo cron job

Bước 1: Tạo Access Token

Bước 1: Tạo Access Token,digital ocean,backup vps,quản trị website

Truy cập vào phần quản lý API trong tài khoản Digital Ocean của bạn và nhấn nút tạo Token

Bước 2: Thay thế token và ID của droplet bạn cần backup vào script dưới đây

Thay thế các thông tin Token, ID của Droplet bạn muốn backup vào script dưới đây.

class BackupDroplet
{
    private $apiUrl = 'https://api.digitalocean.com/v2/';
    private $token;
    private $dropletId;
    public function __construct($token, $dropletId)
    {
        $this->token = $token;
        $this->dropletId = $dropletId;
    }
    public function getSnapshots()
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->apiUrl . 'droplets/' . $this->dropletId . '/snapshots');
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->token
        ));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
        $response = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($response);
        if ($result) {
            return $result->snapshots;
        }
        return [];
    }
    public function createSnapshot()
    {
        $data = array("type" => "snapshot", "name" => "Tên cho snapshot " . date('d-M-Y H:i'));
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->apiUrl . 'droplets/' . $this->dropletId . '/actions');
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json',
            'Authorization: Bearer ' . $this->token
        ));
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
        curl_exec($ch);
        curl_close($ch);
    }
    public function deleteSnapshot($id)
    {
        if ($id) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $this->apiUrl . 'images/' . $id);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json',
                'Authorization: Bearer ' . $this->token
            ));
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
            curl_exec($ch);
            curl_close($ch);
        }
    }
    public function deleteOutdatedSnapshots()
    {
        $currentDate = new DateTime();
        $snapshots = $this->getSnapshots();
        foreach ($snapshots as $snapshot) {
            $snapshotDate = new DateTime($snapshot->created_at);
            $snapshotDate->modify('+2 days');
            if ($snapshotDate < $currentDate) {
                $this->deleteSnapshot($snapshot->id);
            }
        }
    }
}
$BackupDroplet = new BackupDroplet('Access token của bạn', 'ID droplet cần tạo snapshot để backup');
$BackupDroplet->createSnapshot();
$BackupDroplet->deleteOutdatedSnapshots();

Click để xem bản script gốc

Bước 3: Tạo cron job

Tạo một cron job tự động chạy script trên theo lịch trình mà bạn mong muốn. Trong ví dụ dưới đây, mình tự động chạy script lúc 0:00 mỗi ngày.

0 0 * * * /usr/bin/php /<đường dẫn tới script>/backup.php

Lưu ý: Token là thông tin quan trọng, nó có thể sử dụng để xóa droplet, snapshot... và hiện tại Digital Ocean chưa có nhiều mức độ cấp quyền cho các token này (chỉ đọc và viết). Do đó, hãy đảm bảo mình đã làm tốt nhất những gì có thể để bảo mật nó.

Script tham khảo từ ekreative.com