iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Odoo

Odoo 部署策略系列 第 27

docker volume 備份方案:使用 volumerize 建立 odoo 恢復點

  • 分享至 

  • xImage
  •  

今天要研究如何使用 volumerize 來備份 Docker 的 volumes。首先,釐清一下我的目標:我使用這個功能的主要目的不是為了確保資料不會丟失,因為我的整個 Docker 都放在 VM 中,而這個 VM 我已經有定期備份。而是我希望當我有操作失誤,或需要測試某個狀態下的行為時,可以快速地回到相對精準的時間點,而不是只能回到以一週為單位的備份。

目前我們儲存 odoo 資料的地方有兩個:一個是資料庫的 volume db-dev-data:/var/lib/postgresql/data,用來儲存資料庫的內容;另一個是 odoo 的 volume odoo-dev-data:/var/lib/odoo,用來儲存一些檔案或附件,因此我們的目標就是這兩個 volumes。


在 docker-compose.yml 中設定 volumerize

實作的方式相當簡單,基本上就是修改 docker-compose.yml,新增關於 volumerize 的部分,將我們要備份的 volumes 掛載給它,還有掛載備份的目標位置,並設定備份的頻率和形式即可。

不過,由於原作者 blacklabelops 的 GitHubDocker Hub 已經很久沒有更新,我採用了 pumbaasdad 維護的GitHub 分支,但他的 Docker Hub 沒有可以直接拉取的映像檔,所以以 submodule 的形式加入,再透過 build 的方式得到映像檔。

volumerize:
  build: ./volumerize
  restart: unless-stopped
  volumes:
    - odoo-dev-data:/source/odoo-dev-data:ro
    - db-dev-data:/source/db-dev-data:ro
    - odoo-prod-data:/source/odoo-prod-data:ro
    - db-prod-data:/source/db-prod-data:ro
    - ./backup:/backup  # 使用資料夾進行備份
    - volumerize-cache:/volumerize-cache  # Duplicity 的快取
  environment:
    - VOLUMERIZE_SOURCE=/source
    - VOLUMERIZE_TARGET=file:///backup
    - VOLUMERIZE_JOBBER_TIME=0 0 * * * *    # 每小時執行增量備份
    - VOLUMERIZE_FULL_IF_OLDER_THAN=1D      # 每日進行完整備份
    - REMOVE_OLDER_THAN=7D                  # 移除超過 7 天的備份
    - TZ=Asia/Taipei                        # 設定時區為台北時間

接下來是還原的容器,基本上就是把內容都複製過來,添加 profiles 讓它不會預設啟動,再加上 command 指定要還原到的時間點。

volumerize-restore:
  build: ./volumerize
  restart: no
  profiles:
    - restore
  network_mode: none  # 如果將其他容器全部停掉再啟動這個容器,會出現找不到網路的錯誤,所以乾脆關閉網路,反正這種情況下也不需要網路
  volumes:
    - odoo-dev-data:/source/odoo-dev-data
    - db-dev-data:/source/db-dev-data
    - odoo-prod-data:/source/odoo-prod-data
    - db-prod-data:/source/db-prod-data
    - ./backup:/backup
    - volumerize-cache:/volumerize-cache
  environment:
    - VOLUMERIZE_SOURCE=/source
    - VOLUMERIZE_TARGET=file:///backup
    - VOLUMERIZE_JOBBER_TIME=0 0 * * * *
    - VOLUMERIZE_FULL_IF_OLDER_THAN=1D
    - REMOVE_OLDER_THAN=7D
    - TZ=Asia/Taipei
  command: restore -t 2024-10-11T23:49:18+08:00 # 也可改成還原到多久之前的形式

驗證備份還原

首先,我在對話中輸入了兩句話,然後進行備份。一分鐘後,再輸入另外兩句話。
https://ithelp.ithome.com.tw/upload/images/20241012/20168935RhjJTt4PDQ.png

手動備份的方式:

docker-compose exec volumerize backup
No valid action found. Will imply 'backup' because a path source was given and target is a url location.
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Fri Oct 11 22:40:53 2024
--------------[ Backup Statistics ]--------------
StartTime 1728661758.92 (Fri Oct 11 23:49:18 2024)
EndTime 1728661759.48 (Fri Oct 11 23:49:19 2024)
ElapsedTime 0.56 (0.56 seconds)
SourceFiles 5898
SourceFileSize 248675285 (237 MB)
NewFiles 23
NewFileSize 657077 (642 KB)
DeletedFiles 1
ChangedFiles 26
ChangedFileSize 34341174 (32.8 MB)
ChangedDeltaSize 0 (0 bytes)
DeltaEntries 50
RawDeltaSize 1120943 (1.07 MB)
TotalDestinationSizeChange 120860 (118 KB)
Errors 0
-------------------------------------------------

running /postexecute/backup/0-removeoldbackup.sh
Checking if old backups should be removed
Removing all backups older than 7D if they are no more recent ones that depend on them
Local and Remote metadata are synchronized, no sync needed.
Last full backup date: Fri Oct 11 22:40:53 2024
No old backup sets found, nothing deleted.
remove-older-than finished

running /postexecute/backup/1-replicate.sh

列出備份列表,可以看到我在 23:49:18 做了最後一次增量備份。

docker-compose exec volumerize list
Last full backup date: Fri Oct 11 22:40:53 2024
Collection Status
-----------------
Connecting with backend: BackendWrapper
Archive dir: /volumerize-cache/3fe07cc0f71075f95f411fb55ec60120

Found 0 secondary backup chain(s).

Found primary backup chain with matching signature chain:
-------------------------
Chain start time: Fri Oct 11 22:40:53 2024
Chain end time: Fri Oct 11 23:49:18 2024
Number of contained backup sets: 38
Total number of contained volumes: 38
 Type of backup set:                            Time:                            Num volumes:
Full                    Fri Oct 11 22:40:53 2024                 1
Incremental             Fri Oct 11 22:42:00 2024                 1
Incremental             Fri Oct 11 22:43:00 2024                 1
...
Incremental             Fri Oct 11 23:12:00 2024                 1
Incremental             Fri Oct 11 23:22:01 2024                 1
Incremental             Fri Oct 11 23:31:28 2024                 1
Incremental             Fri Oct 11 23:49:18 2024                 1
-------------------------
No orphaned or incomplete backup sets found.

停掉所有容器,這步驟可能不需要,但我先這樣測試。

docker-compose down
[+] Running 11/11
 ✔ Container webapp-deployment-postgresql-admin-1  Removed     3.5s
 ✔ Container webapp-deployment-static-brand-1      Removed     1.3s
 ✔ Container webapp-deployment-odoo-prod-1         Removed     2.1s
 ✔ Container webapp-deployment-reverse-proxy-1     Removed     2.8s
 ✔ Container webapp-deployment-odoo-dev-1          Removed     2.4s
 ✔ Container webapp-deployment-volumerize-1        Removed     1.0s
 ✔ Container webapp-deployment-postgresql-prod-1   Removed     1.0s
 ✔ Container webapp-deployment-postgresql-dev-1    Removed     1.0s
 ✔ Network webapp-deployment_prod-net              Removed     0.2s
 ✔ Network webapp-deployment_default               Removed     0.4s
 ✔ Network webapp-deployment_dev-net               Removed     0.7s

將還原容器的指令改為我們要回復的時間點:restore -t 2024-10-11T23:49:18+08:00(前面的實作範例已經是使用這個時間)。

啟動 volumerize-restore 容器來執行還原:

 docker-compose up volumerize-restore
[+] Running 1/1
 ✔ Container webapp-deployment-volumerize-restore-1  Recreated     0.1s
Attaching to volumerize-restore-1
volumerize-restore-1  | version: 1.4
volumerize-restore-1  |
volumerize-restore-1  | resultSinks:
volumerize-restore-1  |   - &stdoutSink
volumerize-restore-1  |     type: stdout
volumerize-restore-1  |     data:
volumerize-restore-1  |       - stdout
volumerize-restore-1  |       - stderr
volumerize-restore-1  |   - &notifyApprise
volumerize-restore-1  |     type: program
volumerize-restore-1  |     path: /opt/volumerize/notify_apprise.py
volumerize-restore-1  |
volumerize-restore-1  | prefs:
volumerize-restore-1  |   runLog:
volumerize-restore-1  |     type: file
volumerize-restore-1  |     path: /var/log/jobber-runs
volumerize-restore-1  |     maxFileLen: 100m
volumerize-restore-1  |     maxHistories: 2
volumerize-restore-1  |
volumerize-restore-1  | jobs:
volumerize-restore-1  |
volumerize-restore-1  |   VolumerizeBackupJob:
volumerize-restore-1  |     cmd: /etc/volumerize/periodicBackup
volumerize-restore-1  |     time: '0 0 * * * *'
volumerize-restore-1  |     onError: Continue
volumerize-restore-1  |     notifyOnError:
volumerize-restore-1  |       - *stdoutSink
volumerize-restore-1  |       - *notifyApprise
volumerize-restore-1  |     notifyOnFailure:
volumerize-restore-1  |       - *stdoutSink
volumerize-restore-1  |       - *notifyApprise
volumerize-restore-1  |
volumerize-restore-1  | Local and Remote metadata are synchronized, no sync needed.
volumerize-restore-1  | Last full backup date: Fri Oct 11 22:40:53 2024
volumerize-restore-1 exited with code 0

重啟所有容器:

docker-compose up
[+] Running 11/11
 ✔ Network webapp-deployment_dev-net               Created     0.0s
 ✔ Network webapp-deployment_default               Created     0.0s
 ✔ Network webapp-deployment_prod-net              Created     0.0s
 ✔ Container webapp-deployment-postgresql-admin-1  Created     0.1s
 ✔ Container webapp-deployment-postgresql-dev-1    Created     0.1s
 ✔ Container webapp-deployment-volumerize-1        Created     0.1s
 ✔ Container webapp-deployment-postgresql-prod-1   Created     0.1s
 ✔ Container webapp-deployment-static-brand-1      Created     0.1s
 ✔ Container webapp-deployment-reverse-proxy-1     Created     0.1s
 ✔ Container webapp-deployment-odoo-dev-1          Created     0.1s
 ✔ Container webapp-deployment-odoo-prod-1         Created     0.1s

登入 odoo,可以看到我們的對話回到了只有兩句的狀態,還原成功。

https://ithelp.ithome.com.tw/upload/images/20241012/20168935vCxixfkcfI.png


上一篇
又又又是 odoo 安全與效能:X-Sendfile、X-Accel、HSTS、Cookie 安全標記、Gzip 壓縮
下一篇
certbot container:Let's Encrypt 憑證申請和自動更新
系列文
Odoo 部署策略30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言