有馬総一郎のブログ

(彼氏の事情)

2025年01月10日 06:56:28 JST - 13 minute read - Linux

Nextcloudより同期が速いと言われるSeafileをDocker+Non-Root Domain Subdirectory構成で試してみる

Nextcloudを初期化して、同期をやりなおしていると、同期エラーになったり、そもそも同期が遅いこと1が不満だったので、 Seafileを試してみることにした。

Seafile

手順は公式に沿ったつもりだったが…投稿内容を確認すると、どうも 11 バージョンを参考に構築してしまった2みたいだ(草)。 11 と最新の 12 でそれなりの変更点3があるので、後で試すとしよう。


追記 2025-01-11

11 のデータ全て削除して一から Introduction - Seafile Admin Manualを参照しつつう 12 で作り直してみた。公式サイトの見た目、ドキュメント構成は変わったが、Caddyがデフォルトになったこと以外は余り変更がないようだ。

Seafile Server

違いとしては環境変数としてJWT_PRIVATE_KEYSEAFILE_MYSQL_DB_PASSWORDが必須になったことぐらいか。

12 のnginxの設定例では、/seafhttp/seafmediaについでの記載がなく、不要になったと思いきや 11 と同じで必要だった。nginx設定、seahub設定ともに 11 と同じでOK。

追記ここまで


Docker

docker-compose.yml

  mariadb:
    image: mariadb:10.11
    container_name: seafile-mysql
    environment:
      - MYSQL_ROOT_PASSWORD=MYSQL rootのパスワード # Required, set the root's password of MySQL service.
      - MYSQL_LOG_CONSOLE=true
      - MARIADB_AUTO_UPGRADE=1
    volumes:
      - ./seafile/db:/var/lib/mysql  # Required, specifies the path to MySQL data persistent store.
    networks:
      - app-net

  memcached:
    image: memcached:1.6.18
    container_name: seafile-memcached
    entrypoint: memcached -m 256
    networks:
      - app-net 

  seafile:
    image: seafileltd/seafile-mc:11.0-latest
    container_name: seafile
    ports:
      - "8000:80"  
      - "8082:8082"
    volumes:
      - /mnt/hdd/seafile-data:/shared   # Required, specifies the path to Seafile data persistent store.
    environment:
      - DB_HOST=mariadb
      - DB_ROOT_PASSWD=MYSQL rootのパスワード(mariadbの`MYSQL_ROOT_PASSWORD`と同じになる)  # Required, the value should be root's password of MySQL service.
      - TIME_ZONE=Asia/Tokyo  # Optional, default is UTC. Should be uncomment and set to your local time zone.
      - SEAFILE_ADMIN_EMAIL=Seafile管理者メールアドレス # Specifies Seafile admin user, default is 'me@example.com'.
      - SEAFILE_ADMIN_PASSWORD=Seafile管理者パスワード     # Specifies Seafile admin password, default is 'asecret'.
      - SEAFILE_SERVER_LETSENCRYPT=false   # Whether to use https or not.
      - SEAFILE_SERVER_HOSTNAME=ホスト名 # Specifies your host name if https is enabled.
      - SEAFILE_SERVER_PROTOCOL=https

    depends_on: 
      - mariadb
      - memcached
    networks:
      - app-net

networks:
  app-net:
    driver: bridge

メールアドレス、ホスト名、パスワードといった個別設定以外は、殆ど変えてないが、 Let’s Encryptは使ってないのでSEAFILE_SERVER_LETSENCRYPT=falseとしている。また、/seafhttpの入口がいるのでportに8082:8082を追加している。

Nginx

リバースプロキシの設定については、最新 12 バージョンからは Caddyを使っているらしい。私の場合、Non-Root Domain Subdirectory構成(https://example.com/seafileみたいな)で起動したいので、 11 バージョンのマニュアルとなるが Deploy Seahub at Non-root domain or on custom port - Seafile Admin Manualを参考に、以下のようにした。

nginx.conf

    ###
    # seafile
    ###
    location /seafile {
        proxy_pass         http://127.0.0.1:8000;
        proxy_set_header   Host $http_host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout  1200s;
 
        # used for view/edit office file via Office Online Server
        client_max_body_size 0;
 
        access_log      /var/log/nginx/seahub.access.log;
        error_log       /var/log/nginx/seahub.error.log;
    }
    
    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8000/seafhttp;
        client_max_body_size 0;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
    }
        
    location /seafmedia {
        rewrite ^/seafmedia(.*)$ /media$1 break;
        proxy_pass http://127.0.0.1:8000/seafmedia;
        root /opt/seafile/latest/seahub;
    }

公式のマニュアルと違うのは/seafile/seafmediaの部分。これをしないと管理画面開けてもスタイルシートとかが適用されなかった。

    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
-       proxy_pass http://127.0.0.1:8082;
+       proxy_pass http://127.0.0.1:8000/seafhttp;
・・・中略・・・
    location /seafmedia {
        rewrite ^/seafmedia(.*)$ /media$1 break;
+       proxy_pass http://127.0.0.1:8000/seafmedia;
Seafile
/seafmedia配下のファイルが読み込めない

seahub設定

SeafileのWebフロントエンドとなるseahubの設定する。 seahub_settings.py だが、Seafileを起動すると自動で /seafile-data/配下に設定ファイルが作成されるので、自動作成後に編集すれば良い。

./seafile-data/seafile/conf/seahub_settings.py

# -*- coding: utf-8 -*-
SECRET_KEY = "自動書き込み"
SERVICE_URL = "自動書き込み"
 
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'seahub_db',
        'USER': 'seafile',
        'PASSWORD': '自動生成',
        'HOST': 'mariadb',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}
 
 
CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'memcached:11211',
    },
    'locmem': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    },
}
COMPRESS_CACHE_BACKEND = 'locmem'
TIME_ZONE = 'Asia/Tokyo'
FILE_SERVER_ROOT = "自動書き込み"
## add
MEDIA_URL = '/seafmedia/'
COMPRESS_URL = MEDIA_URL
STATIC_URL = MEDIA_URL + 'assets/'
SITE_ROOT = '/seafile/'
LOGIN_URL = '/seafile/accounts/login/'
CSRF_TRUSTED_ORIGINS = ['https://seafileサーバホスト名']
DEBUG = True
ENABLE_TWO_FACTOR_AUTH = True
TWO_FACTOR_DEVICE_REMEMBER_DAYS = 120 # optional, default 90 days.

追加したのは## add以降となる。 Deploy Seahub at Non-root domain or on custom port - Seafile Admin Manualを参考にして、そのままのはず。

以下の部分は、これを追加しないとシステム管理画面のログイン(POST処理)で、 CRSFの検証に失敗してアクセス禁止 (403) CSRF検証に失敗したため、リクエストは中断されました。とのエラー画面が表示される。

CSRF_TRUSTED_ORIGINS = ['https://seafileサーバホスト名']
DEBUG = True

Forbidden (403) CSRF verification failed - on docker 11.0.1 - Seafile Server - Seafile Community Forum

Seafile

seafhttpの疎通確認

/seafhttpが疎通できていないと以下のようなログが出力される。

[12/28/24 20:10:41] clone-mgr.c(964): Worktree path conflicts with seafile system path.
[12/28/24 20:16:35] clone-mgr.c(700): Transition clone state for 815ad7bf from [init] to [check server].
[12/28/24 20:16:35] http-tx-mgr.c(1287): Bad response code for GET https://Seafileサーバホスト名/seafhttp/protocol-version: 404.

upgraded to new client (4.2.0) bad response 404 for protocol version · Issue #570 · haiwen/seafile-clientなど読みつつ、以下のように、docker-compose.yml へポート追加、 nginx.conf の修正などを行なった。

  seafile:
    image: seafileltd/seafile-mc:11.0-latest
    container_name: seafile
    ports:
      - "8000:80"  
      - "8082:8082"
    volumes:
    location /seafhttp {
        rewrite ^/seafhttp(.*)$ $1 break;
        proxy_pass http://127.0.0.1:8082/seafhttp;
        client_max_body_size 0;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout  36000s;
        proxy_read_timeout  36000s;
    }

簡易的に疎通確認するにはhttps://Seafileサーバホスト名/seafhttp/protocol-versionを叩くだけでいい。レスポンスとして{"version": 2}と返ってきたら正常ということになる。

二要素認証

二要素認証も Two-factor Authentication - Seafile Admin Manualとおり設定すれば簡単に設定できる。

管理画面から設定 -> Two-Factor Authentication と進んで Enable Two-Factor Authentication ボタンをクリックすれば、そのユーザーでは二要素認証が有効となる。

Seafile
Seafile
Seafile

分かりにくいのはBackup Tokensの部分で、一度Generate Tokenしたら、そのコードをコピペすなりしたら、 バック すればいい。完了画面とか バックアップトークンをダウンロードする みたいなボタンはない。

Seafile

デスクトップアプリ

公式ではAppImage形式のデスクトップアプリが配布されている。最新版ではないがflatpak版もある。

  1. 同期フォルダの選択

    ここらへんがNextcloudと異なる4Seafileというフォルダを何処のフォルダに作るか?という意味になる。ここで/home/arimasou16/Seafileというフォルダを選択すると/home/arimasou16/Seafile/Seafileというフォルダが作られる。デフォルトだと、そのフォルダ内で同期を取ることになる。

    Seafile Client
    Seafileフォルダを選択
  2. アカウント追加

    1. サーバー、メールアドレス、パスワード、コンピュータ名を入力
    Seafile Client
    アカウントを追加
    1. 二要素認証が有効になっていればここで認証トークンを入力
    Seafile Client
    認証トークン入力
  3. 同期ライブラリを選択する

    選択した/Seafile配下で勝手に同期が始まるかと思いきや、Nextcloudと異なり、そうではない。サーバのライブラリ(フォルダ)をどのフォルダと同期させるかを選択して初めて、同期される。

    Seafile Client
    メインウィンドウ
    Seafile Client
    同期ライブラリの場所を選択

    最初にSeafileフォルダを選択するのは、単なるデフォルトのためで、/home/arimasou16/Seafile配下外の/home/arimasou16/Documentといったフォルダを選択することは可能。ここでも注意なのは/home/arimasou16/Documentとした場合、その配下の/home/arimasou16/Document/ライブラリ名のフォルダが作られて、そのフォルダが同期される。

    Seafile Client
    同期ライブラリの場所の確認

    同期するライブラリがサーバと同じ構造で良いなら、各ライブラリを同期するときの場所は、全て/home/arimasou16/Seafileとすれば

    $ tree -L 1 /home/arimasou16/Seafile
    /home/arimasou16/Seafile
    ├── ライブラリA
    ├── ドキュメント
    ├── フォト写真
    └── 秘密
    

    とした形で同期される。

    既存のフォルダと同期 とした場合は/home/arimasou16/Seafile/ライブラリAを選択すればそのままそのフォルダが同期される。

    Seafile Client
    既存のフォルダと同期
  4. サーバ側にライブラリを追加する

    この場合も同期フォルダを選択する。ファイルダイアログで選択すると、パスと名称が設定される。名称がライブラリ名となる。

    Seafile Client
    ライブラリを作成

    この時に一つ一つフォルダを同期するのは面倒だ!と/home/arimasou16/Seafileとするとパス"/home/arimasou16/Seafile"がシステムパスと競合していますとエラーになるので出来ない。

    Seafile Client
    システムパスと競合

使ってみて

慣れないと、操作に迷うところもあるが、同期フォルダを一つのフォルダ配下でなく、あちこちに配置したい場合、こうした操作のほうが都合が良いだろう。また、間違えてディレクトリを削除したとき、それがライブラリ、つまり同期フォルダの最上位の場合は、同期が解除されるだけでライブラリまるごと削除されない。安全に配慮した設計とも言える。

Seafile Client
ライブラリの同期を自動解除してくれる

そして、同期するファイルがMOVといったギガを超える大きな動画ファイルであっても、特にクライアントやサーバの設定を変えることなく同期された。そして、同期はNextcloudよりも圧倒的に速い!ちょっと正確な数字は出せないが、120GBぐらいのフォルダを同期するならSeafileなら1、乃至、2時間で終わるが、Nextcloudならその3倍以上はかかる。

ちょっとしたテキストファイルなら一瞬でおわる。余計な機能がないのもあるが、管理画面の遷移もきびきびしてるしストレスフリー。Windows、Mac、Androidアプリもちゃんとあるので、マルチプラットフォーム対応がされている。

これは乗り換えるしかない!と1週間ぐらい使い続けてみたのだけど…やはり気になるところがあった。

気になるところ

クラウドで表示の遷移でエラー

PCのクライアントから"クラウドで表示"とすると、https://Seafileサーバホスト名/seafile/seafile/library/d27f0b78-a8d9-412f-a9e1-bc07e6aa94cd/ライブラリA/と遷移してしまう。seafile/が一個余計なので、一個削れば正しく遷移できる。

Seafile Client
他のコンテキストメニューの操作は問題ない
Seafile
クラウドで表示で遷移するとPage not found404

SERVICE_URL = "https://Seafileサーバホスト名/seafile"としているせいかと、システム管理画面から変更、もしくは seahub_settings.py から削っても変わらない、というか付けても付けなくても動作は何も変わらない。

Seafile
SERVICE_URLを変更しても解消されず

issueやcommitヒストリなど見ると、ルートドメインでない場合の修正などがあったりして、サブディレクトリ構成が考慮されてないわけではないのだけど、設定方法が分からない。最初クライアント側の設定なのか思ったりしたが、アクセスログは以下のようになっているので、サーバー側の設定が間違っているようだ。ソースなど見たが、やはり分からなかった。

192.168.0.2 - - [05/Jan/2025:18:33:35 +0900] "GET /seafile/api2/repos/ HTTP/1.1" 200 6178 "-" "Mozilla/5.0"
192.168.0.2 - - [05/Jan/2025:18:33:38 +0900] "POST /seafile/api2/client-login/ HTTP/1.1" 200 2 "-" "Mozilla/5.0"
192.168.0.2 - - [05/Jan/2025:18:33:39 +0900] "GET /seafile/seafile/library/d27f0b78-a8d9-412f-a9e1-bc07e6aa94cd/ライブラリA/ HTTP/1.1" 404 7927 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"

12 バージョンだと環境変数にNON_ROOT=${NON_ROOT:-false}とあるのでNON_ROOT=true追記してみたけど、駄目だった。まあ、 11 バージョンの設定方法見て構築したので、最新のを見直して構築し直せばいけるかも知れないけど。


追記 2025-01-11
12 でもこの問題は解決できなかった。

そして、上のNON_ROOTはrootユーザで実行するかどうかでNon-Root Domainという意味ではなかった。ノンルートユーザの場合は./seafile-data/seafile/ディレクトリをchmod -R a+rwx ./seafile-data/seafile/して777にしなければならない。

追記ここまで


クラウドで表示する って操作自体、ほぼ使わない。また、他の操作とかでは問題なくいけてるので、どうでもいいといえばどうでも良いのだけど。

対応アプリが狭まる

勿論、PC、モバイルといった純正アプリは Download - Seafileに見られるように十分に揃っている。

しかし、 FolderSyncといった同期アプリは対応してない。また、 Nextcloud (unofficial) - Chrome ウェブストアといった拡張機能はない。

しかし、 RcloneはSeafileは対応しているようだ。また、WebDAVは対応しているので、それを使えば対応アプリが少ない、といった問題はある程度、解決される。

WebDAV対応する場合、以下のように設定ファイルに追記が必要となる。

nginx.conf

    location /seafdav {
        rewrite ^/seafdav$ /seafdav/ permanent;
    }   
    
    location /seafdav/ {
        proxy_pass         http://127.0.0.1:8000/seafdav/;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout  1200s;
        client_max_body_size 0;
        access_log      /var/log/nginx/seafdav.access.log;
        error_log       /var/log/nginx/seafdav.error.log;  
    }
     
    location /:dir_browser {
        proxy_pass         http://127.0.0.1:8000/:dir_browser;
    }
}

seafile-data/seafile/conf/seafdav.conf

[WEBDAV]
enabled = true
port = 8080
share_name = /seafdav

二要素認証のときはアプリパスワード使うのか?と思ったら、WebDAV経由だと認証トークンなしで承認できた(良いのか?)。

$ sudo apt install davfs2
$ sudo mount -t davfs -o uid=arimasou16 https://Seafileホスト名/seafdav /home/arimasou16/Documents/seafdav
Please enter the username to authenticate with server
https://Seafileホスト名/seafdav or hit enter for none.
  Username: ユーザメールアドレス
Please enter the password to authenticate user ユーザメールアドレス with server
https://Seafileホスト名/seafdav or hit enter for none.
  Password:  
$

WebDAVは遅すぎてあまり使い物にならないが…


追記 2025-01-11

システム管理画面だと/seafile/seafdavと表示されいるが、実際は上のとおりhttps://Seafileホスト名/seafdavで合っている。 また、WebDAV用のパスワードを設定できるようだ。

Seafile
システム管理画面と実際のURLが一致していない

追記ここまで


デスクトップアプリの挙動がたまに不安定

起動・終了を繰り返しとき、たまにトレイアイコンからは消えているが、プロセスが残っていたりする。または、逆にトレイアイコンにアプリが二つ表示されて、同期が動かなかったりする。まあ、起動・終了を繰り返すことはまれだし、データが削除されたとか、競合ファイルが大量発生したとかではないので、問題ないかも知れない。

同期速度についていえば、圧倒的にSeafileなんだけど、利用ユーザ数などによる拡張性、将来性など考えると、やはりNextcloudを使い続けた方がいいのかな、と思ったりして乗り換えるかの判断が難しい。


  1. Intel NUC Pentium N3700搭載の2015年製のベアボーン使っていることもあるが。 ↩︎

  2. こちらが参考にしたであろうドキュメント。 Seafile Community Installation - Seafile Admin Manual ↩︎

  3. ぱっと見、docker-compose.xmlに直書きしていた環境変数が、 .env 環境変数ファイルに書くようになったり、 Caddy - The Ultimate Server with Automatic HTTPSのdockerも一緒に使うようになっている。 ↩︎

  4. “直感的でない"という言い方は単なる慣れの問題を、誤魔化しているようで好きではないが、ちょっと分かりにくい。 ↩︎