それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

nextcloud をバックアップするのをスクリプト化

nextcloud のバックアップはちょっと面倒

nextcloud のバックアップにはひと手間が必要。occ コマンドにバックアップ用のサブコマンドが実装されていないので、手作業でバックアップする必要がある。

バックアップする対象

  • MySQL のデータベース
  • ユーザーのデータファイル
  • 設定ファイル

MySQLだとバックアップが面倒なので、SQLiteにすればよかったなと後悔してる。そんなにデータ入ってない。 メモリサイズの10%も超えること無いなら、メモリキャッシュが効くサイズだしSQLiteで十分だったわ。

MySQL のバックアップ

定番のバックアップコマンドですね

mysqldump --single-transaction -h ${db_host} -u ${db_user} --password=${db_pass} ${db_name} 2>/dev/null | gzip > ${dump} 

平文で入力するのがめんどくさそうなところですね。

バックアップスクリプトのIDが面倒。

バックアップスクリプトMySQLのパスワードを書くのは嫌なので、require/include して再利用可能にする。 幸いなことに、nextcloud の config は単体で読み込み可能になっていてこれを使えばいい

ファイルのバックアップ

ユーザーデータや設定ファイルのバックアップは個別にやる必要がありますが、私はめんどくさいので、フォルダごと転送することにした。

バックアップファイルの設置場所

nextcloud は次のようなフォルダ構成になっているため、 nextcloud の最上位のフォルダに置けばいいとわかる。

.
├── backup.php ## 設置
├── data
├── nextcloud
│   ├── apps
│   ├── config
│   ├── console.php
│   ├── core
│   ├── cron.php
│   ├── index.html
│   ├── index.php
│   ├── occ
│   ├── settings
│   ├── themes
│   ├── updater
│   └── version.php
└── tmp

上記の例ではnextcloudのソースコードの入ったディレクトリの一つ上に設置した。

こうすると大丈夫。nextcloud のソースコードの入ったディレクトリの中にファイルを置くと一貫性(integrity)のチェックでエラーになると思う。

php ファイル

<?php

/***
 *
 * 2018-11-05 nextcloudのバックアップする
 *  - MySQL をバックアップするスクリプト
 *  - データ
 *  - 稼働中のソース
 * @author takuya
 * @version 1.0
 *
 */


#########################################
# READ nextcloud database configuration
#########################################


$dir = dirname( __FILE__ );
$config_path = $dir. "/www-data/config/config.php";
if ( !file_exists($config_path ) ) {
  echo "config.php not found.\n";
  exit;
}

include $config_path;

$db_user = $CONFIG['dbuser'];
$db_pass = $CONFIG['dbpassword'];
$db_name = $CONFIG['dbname'];
$db_host = $CONFIG['dbhost'];

$nextcloud_path = "/var/www/virtualhosts/nextcloud.example.com/";
$dst_host = "takuya-oic-google-drive-epgrec";

#### set output filename
$date = date("Y-m-d");
$dump = "nextcloud-${date}-mysqldump.sql.gz";



#### rclone config
$rclone_conf = '/home/takuya/.config/rclone/rclone.conf';
#####################
## build commands
####################
$mysql_backup_cmd = "mysqldump --single-transaction -h ${db_host} -u ${db_user} --password=${db_pass} ${db_name} 2>/dev/null | gzip > ${dump} ";
$mysql_rclone_cmd = "rclone --config  ${rclone_conf}  copy ${dump}  ${dst_host}:backup/nextcloud.example.com/mysql_dump > /dev/null";
$mysql_remove_cmd = "rm ${dump}";


$data_rclone_cmd = "rclone --config  ${rclone_conf}  copy ${nextcloud_path}  ${dst_host}:backup/nextcloud.example.com/nextcloud  > /dev/null";

$cmds = array(
  $mysql_backup_cmd,
  $mysql_rclone_cmd,
  $mysql_remove_cmd,
  $data_rclone_cmd,
);


chdir('/tmp');
// echo getcwd();

foreach ( $cmds as $cmd ) {
  $ret = shell_exec($cmd . "; echo $?" );

  // echo $ret;
  if( $ret > 0  ){
    echo "Error occurred in comamnd ( '$cmd' ) ";
    exit();
  }

}

あとはこれをcronなどに登録する

実行権限は www-data か root で大丈夫。

sudo -u www-data php backup.php

今回はrclone を使ったが rsyncでも

rsync に変えても楽だと思う。sqliteならrsync で転送するだけで終わるんだけどなぁ。

だけどホストの証明書の取扱が面倒なので設定済みのrclone のconfig ファイルを使ったほうが楽でした。

参考資料

https://docs.nextcloud.com/server/14/admin_manual/maintenance/restore.html