pixel4のストレージ容量が画像データで圧迫されているのを前々から何とかしたいと思っており、前々から定期的に自動退避する仕組みを作れないものかと思いつつだらだら先延ばしにしていたらついに使用率90%を越えてしまい、慌てて年末年始に対応することに。
pixel4ならそれこそGoogleフォト使えよという話なのですが1、容量無制限もいつまで続くかどうか分からない&一回Googleフォトに上げたものをまた手元に持ってくるのも大変なので他に手段がないか調べていたところ、Nextcloudのandroidクライアントにそういう機能がありそうだったので、FreeBSDのJail上で立ててみました。実は半年前くらいに1回トライしたものの失敗し放り出していたのですが、再トライしたら上手くいったので備忘として残しておきます。
NextCloudセットアップ
各コンポーネント(Apache、PHP、MySQL)の導入や設定はほぼ以下サイト及びNextcloudのマニュアルの通りに進められた。HTTPS化はDDNS+Let’s Encryptで対応。
Nextcloud導入
HTTPS化(Let’s Encrypt使用)
公式マニュアル(Apache版)
Example installation on CentOS 8 — Nextcloud latest Administration Manual latest documentation
一方で、Nextcloudのセットアップ(初期インストール)において幾つか躓いたところがあったため、以下に記載。
MySQL8.0のデフォルト認証方式変更に伴うphp接続時のエラー
下記のようなエラーがセットアップ画面に出て失敗。
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
こちらのサイトの内容で解決。最近MySQL全然触ってないので分からなかった。。。
php必須モジュール不足
同じく下記のようなエラーがセットアップ画面に出て失敗。
Fatal error: Call to undefined function filter_var()
マニュアルちゃんと読みましょう案件。単純にphp74-filterをpkgで落としてきて解決。
php - Call to undefined function filter_var() - Stack Overflow
ユーザ認証エラー
セットアップ全体の内半分くらいの労力を費やすことになってしまったくらいここでドハマりした。
上記2つのエラーを解決し正しい情報を入力しても、ユーザ認証に失敗した旨のエラーが出力される。nextcloudのログには以下のように表示される。
Failed to connect to the database: An exception occurred in driver:
SQLSTATE[HY000] [1044] Access denied for user '<username>'@'<hostname>' to database '<dbName>'
セットアップ画面で入力したユーザでNextCloudが使用するユーザとかデータベースを作成後、NextCloudが使用するユーザで再接続してDBオブジェクトなどを作成しに行く動きをしてるっぽいのだが、その再接続の部分でエラーが発生している模様。
Install fails if database user has no grant permission · Issue #13628 · nextcloud/server · GitHub
NextCloudのコミュニティには上記BUGに該当する事象として記載があったものの、最新バージョンでは既にクローズされているように見える。grant optionなしで権限付与されているのが原因という話なので、セットアップ失敗後に手動で権限付与してセットアップページをリロードしてみたものの、そのタイミングで新しく連番の新ユーザが作成されてしまい結局同じことの繰り返しに。
てことでこりゃどうにもならんなあと頭を抱えてたのですが、別のサイト(Redditだったかな?)でサイレントインストールなら上手くいく旨の記載があったためマニュアルから探して実行。
Installing from command line — Nextcloud latest Administration Manual latest documentation
コマンドログを取り忘れてたけど、ほぼマニュアル通りのオプションで無事成功した。
trusted_domainsエラー
サイレントインストール完了後、nextcloudサイトにFQDNでアクセスしたところ信用できないドメイン名である旨のエラーが出力された。このため、nextcloudインストール配下の「config/config.php」のtrusted_domains変数を以下のように修正して解決。ちなみにインストールオプションでMySQLのホスト名として指定したものがデフォルトで設定される模様。
'trusted_domains' =>
array (
0 => 'localhost',
1 => '<アクセスに使用するFQDN名>'
)
NextCloudへのデータ移行
さて、実はもっと大変だったのがこちら。
まずAndroidから約5万ファイル(約20GB)を超えるデータを手元に引っ張ってくるのがメチャクチャ大変だった。最初はNextCloudのAndroidクライアントから自動アップロード機能で移行しようとしたけど、流石にこれだけのファイル数&サイズだとクライアントがまともに動かず断念。Android側でFTP立てるとかもやってみたけど遅くて、結局PCにUSB接続して持ってくることに。ただAndroid上のファイルパスにはエクスプローラ(GUI)経由でしかアクセスできないっぽく2、その影響かコピーが途中で失敗したりした。最終的には成功したけど軽く3時間くらいかかった。
で、それをNextCloudのデスクトップクライアントで移行する方針だったのだけど、どうもディレクトリ単位で同期する思想のツールのようでAndroid版クライアントとは微妙に使用感が異なっており、かつ若干数のファイルがAndroidクライアントからアップロードできていたためディレクトリ単位で上書きするのも憚られたということで、直接NextCloudのデータディレクトリに物理コピーすることにした。幸いディレクトリ構造そのものはNextCloudから見えているものと同じだったので。
Powershellコマンドメモ
Androidクライアントからアップロードする際のオプションで、ファイルの更新日時(YYYY/MM)に応じたサブディレクトリ配下にファイルをアップロードするようにしていたので、それに合わせたディレクトリに手元のファイルをmvした時のPowershellコマンドメモ。ファイル名に更新日時が入っていたのでその情報を使用。
> Get-ChildItem -File | Foreach-Object { $destpath = (Convert-Path .) + '\' + $_.BaseName.Substring(0, 4) + '\' + $_.BaseName.Substring(4, 2) + '\'; Move-Item $_.Name -Destination $destpath }
nextcloud上ファイルの手動スキャン
で、物理コピー完了後NextCloudから見えるかどうか確認した所やっぱり見えなかったので、こういう場合の手動同期コマンドがきっとあるはず!と思って調べたらやっぱりあった。サイレントインストールといい、CUIでの管理もある程度できそうなのはありがたいですな。流石にそれなりに時間かかったけど・・
$ sudo -u <Apacheユーザ名> php occ files:scan <NextCloudユーザ名>
The process control (PCNTL) extensions are required in case you want to interrupt long running commands
- see http://php.net/manual/en/book.pcntl.php
Starting scan for user 1 out of 1 (<NextCloudユーザ名>)
+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 62 | 52121 | 00:08:49 |
+---------+-------+--------------+
データ移行後にAndroid上の画像データを全消しした上で、改めてNextCloudのAndroidクライアントから自動アップロードを有効にしたとこと問題なく動作。ということで無事移行完了と相成りました。大変だった。これに懲りてAndroid(というか携帯端末)上に大量ファイルを蓄積するのは避けるようにします・・
その内各端末ローカルのデータも移行してみようかなと画策中。