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