経緯
現在我が家では自宅サーバが一機稼働している1のだが、諸々の理由2により、将来的にraspberry pi のような省電力で安価なSBCとコンテナを利用したクラスタ構成にしたいと思っている。
その際、バックアップやセキュリティの都合上、オブジェクトストレージやデータベースといった、永続化したいサービスのみファイルサーバで動かし、それ以外のウェブアプリケーションは別のホストに分離したい。
ということで、今回はその第一歩として、MinIOというS3互換のオブジェクトストレージを起動し、Nextcloudのストレージとして使えるようにしてみる。
初めに
本記事で扱うこと
- minioのインストール、起動、Nextcloud用の各種設定(ユーザ作成、ポリシー、バケットの設定)
- コンテナの操作はpodmanを、設定はminio公式のCLIクライアントである
mc
(Manjaroではmcli
)コマンドを利用する
- コンテナの操作はpodmanを、設定はminio公式のCLIクライアントである
- Nextcloudのメインのストレージ(プライマリストレージ)としてminioを使うよう設定の変更
本記事で扱わないこと
- Nextcloudのインストール
- Nextcloudのオブジェクトストレージへのデータ移行
- プライマリストレージを変更した場合、元のファイルは無視されるため、Nextcloud上ではファイルが空になってしまう。(この記事によると設定を戻せば戻るらしい、今回は検証してない。)
- プライマリストレージとしてオブジェクトストレージを使う場合とそうでない場合でファイル名の形式が異なる(後者はクライアント側とおなじディレクトリ構造のためわかりやすい)ため、
mv
コマンド等で簡単に移動はできない。 - 今回はユーザーが自分一人であり、当然同期済みのデータがローカルにあるので、サーバー側での対応は行わず、ローカルのファイルを控えて入れなおす方向で対処した。
バージョン情報
$ uname -a
Linux fox 5.4.169-1-MANJARO #1 SMP PREEMPT Wed Dec 29 18:08:59 UTC 2021 x86_64 GNU/Linux
$ podman --version
podman version 3.4.4
$ mcli --version
mcli version RELEASE.2021-12-10T00-14-28Z
- Nextcloud: Nextcloud Hub II (23.0.0)
- MinIO server: RELEASE.2022-01-08T03-11-54Z
Minioの起動
公式の例ではコンテナを扱うコマンドとして、docker
ではなく podman
というのを使っていた。 podman
は初見ではあったが docker
もたいして使ったことがあるわけでもないので公式のマニュアル通り無難に podman
を使う。
$ sudo pacman -S podman
podmanでminioを起動する。
各引数は-d
でバックグラウンド化、-p
でポートを、-v
でホストのボリュームをマウント、-e
で環境変数を指定している(基本的にはDockerと同じはず)。
$ sudo podman run -d \
-p 9000:9000 \
-p 9001:9001 \
-v /bottle/minio:/data \
-e "MINIO_ROOT_USER=minioadmin" \
-e "MINIO_ROOT_PASSWORD=<miniopassword>" \
quay.io/minio/minio server /data --console-address ":9001"
ちなみに、上記の管理ユーザや後で作成するnextcloud
ユーザもそうだが、MinIOでのユーザ名とパスワードは、S3でいうところのAccess key Id, Secret Access Keyと共用となっている模様。
9000
ポートでオブジェクトストレージに、9001
ポートでコンソールにアクセスできる。
Minioの設定
MinIO Client (mc) — MinIO Baremetal Documentation
Webコンソールも使えるのだが、基本的な設定はCLIでできるようにしたいので、今回はmc
(mcli
)というMinIO用のクライアントコマンドを使って設定していく。
$ sudo pacman -S minio-client
サーバの登録
mcli alias set
で、9000ポートを local
という名前に紐づける。git
でいうところのgit remote add
のような感じ。
$ mcli alias set local http://localhost:9000
Enter Access Key: minioadmin
Enter Secret Key:
Added `local` successfully.
パスワードやIDは podman run
時に指定した管理用の物を入力する。
バケットの作成
mcli mb
でバケットの作成
$ mcli mb local/nextcloud
Bucket created successfully `local/nextcloud`.
mcli ls
で確認できる
$ mcli ls local
[2022-01-23 11:34:02 JST] 0B nextcloud/
ポリシーの作成
Amazon S3公式の例(S3 バケットのオブジェクトへの読み取りおよび書き込みアクセスを許可する)を参考に nextcloud
バケット用のポリシーを作成する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListObjectsInBucket",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::nextcloud"
]
},
{
"Sid": "AllObjectActions",
"Effect": "Allow",
"Action": [
"s3:*Object*"
],
"Resource": [
"arn:aws:s3:::nextcloud/*"
]
}
]
}
このjsonを nextcloud
ポリシーとして読み込む
$ mcli admin policy add local nextcloud nextcloud.json
ユーザの作成、ポリシーの割り当て
nextcloud
ユーザを作成する
$ mcli admin user add local nextcloud nextcloudpasswd
Added user `nextcloud` successfully.
nextcloud
ユーザに nextcloud
ポリシーを紐づける。
$ mcli admin policy set local nextcloud user=nextcloud
Policy `nextcloud` is set on user `nextcloud`
これでnextcloudユーザがnextcloudバケットの読み書きができるようになったはず。
Nextcloud の設定
今回はNextcloud内部に全くデータを置かないというのが理想なので、data
ディレクトリ(マニュアル曰くPrimary Storage)を丸々オブジェクトストレージに差し替える設定をする。3
設定ファイルに objectstore
の追記
以下のようにNextcloudの設定ファイルの最後に objectstore
を追加する
<?php
$CONFIG = array (
/* 中略 */
'objectstore' => array (
'class' => 'OC\\Files\\ObjectStore\\S3',
'arguments' =>
array (
'bucket' => 'nextcloud', //MinIOのバケット名
'autocreate' => true, // 未検証、おそらくバケットがない場合作るものと思われるが、今回は作成済みのため関係ないはず。
'key' => 'nextcloud', // MinIO上の`nextcloud`用ユーザ
'secret' => '****************************************', // MinIO上の`nextcloud`ユーザのパスワード
'hostname' => 'localhost', //MinIOのホスト名
'port' => 9000, //MinIOのポート
'use_ssl' => false, //ssl を使うかどうか、今回はローカルなので不要。
'use_path_style' => true, // バケットをパスで指定するかドメインで指定するか。今回は手っ取り早くlocalhostでアクセスするためパスで指定する。なお、本家AWS S3ではパス指定は非推奨
),
),
);
設定自体はこれだけで完了、MinIOにアクセスできるようになっている。
結果
設定直後のNextcloud Filesの様子がこちら、Nextcloud Notes
アプリが作成した Documents/Note
フォルダ以外は空っぽになっていることがわかる。
Minioのコンソールで確認すると、すでに多数のファイルが追加されていることがわかる。
ちゃんと読み書きできている模様。
ファイル名はすべてIDらしきものになっており、これだけだとどれがどのファイルなのかはわからない。
参考までに、以下がデフォルト(objectstore
未設定時)のdata
ディレクトリの中身、上記のMinioとは全く異なっていることがわかる。
sudo tree -L 3 /usr/share/webapps/nextcloud/data
/usr/share/webapps/nextcloud/data
├── appdata_************
│ #中略
├── files_external
│ └── rootcerts.crt
├── fluo10
│ ├── cache
│ ├── files
│ │ ├── Documents
│ │ ├── InstantUpload
│ │ ├── Nextcloud intro.mp4
│ │ ├── Nextcloud Manual.pdf
│ │ ├── Nextcloud.png
│ │ ├── Notes
│ │ ├── Pictures
│ │ ├── Reasons to use Nextcloud.pdf
│ │ └── Talk
│ ├── files_trashbin
│ │ ├── files
│ │ ├── keys
│ │ └── versions
│ ├── files_versions
│ │ ├── Documents
│ │ ├── InstantUpload
│ │ └── Pictures
│ └── uploads
├── index.html
├── nextcloud.log
└── nextcloud.log.1
パスの構造が全く違うため、通常のバックアップやリストアのように、単にディレクトリをコピペして移行するのは無理そう。今回はユーザーが筆者一人であり、クライアント側にあるデータを同期し直せば済む(タイムスタンプは残らなそうだが)ので、サーバ側での作業はこれでヨシとする。