Docker上で実行しているNextCloudで”Updates between multiple major versions and downgrades are unsupported. Update failed.”が発生してアップデートに失敗する。

Dockerを使ってNextCloudを運用して居る。久しぶりにNextCloudバージョン画面を見たところ、「保守終了したバージョン」との警告が。あわててアップデートを行ったところ、ずっとメンテナンスモードから戻らなくなってしまった。そう、うっかりとversion 23→version 25にアップデートを掛けてしまったため、処理が正常に終了せずに環境が壊れてしまったのだ。

以下のコマンドを実行してメンテナンスモードを強制的に解除してNextCloudをWERBで開くがUpgradeの確認画面になり、そしてUpgradeは失敗してしまう。

$ sudo docker exec -u www-data <container name> php occ maintenance:mode --off

以下のコマンドを実行してコマンドラインからUpgradeを実施するが、「Updates between multiple major versions and downgrades are unsupported. Update failed.」のエラーになってしまう。

$ sudo docker exec -u www-data <container name> php occ upgrade

リカバリ方法がないかと探していたところ「How to fix an accidental Nextcloud docker image update」にたどり着いたので、こちらの方法でリカバリを試みることにする。

まずhtml/config/config.phpを開き、正確なバージョンを確認する。ここでは「’version’ => ‘23.0.0.10’,」とあるとおり、23.0.0.10が正確なージョンになる。

  'datadirectory' => '/var/www/html/data',
  'dbtype' => 'mysql',
  'version' => '23.0.0.10',
  'overwrite.cli.url' => 'https://example.net',
  'dbname' => 'nextcloud',

次にhtml/version.phpを編集する。既にversion 25のファイルに置き換わってしまっているため、これを書き換えて23→24へのアップグレードを通すために、$OC_Versionをarray(25,0,2,3)からarray(23,0,0,10)に、$OC_VersionStringを’25.0.2’から’23.0.0’に、array (‘24.0’ => true, ‘25.0’ => true,)をarray (‘23.0’ => true, ‘24.0’ => true,)に、下記の通りに書き換えます。

<?php
$OC_Version = array(23,0,0,10);
$OC_VersionString = '23.0.0';
$OC_Edition = '';
$OC_Channel = 'stable';
$OC_VersionCanBeUpgradedFrom = array (
  'nextcloud' =>
  array (
    '23.0' => true,
    '24.0' => true,
  ),
  'owncloud' =>
  array (
    '10.11' => true,
  ),
);
$OC_Build = '2022-12-08T11:32:17+00:00 9c791972de9c2561a9b36c1a60e48c25315ecca5';
$vendor = 'nextcloud';

続いてdocker-compose.ymlを編集します。下記のようにnextcloud:24のようにアップデート先となる旧バージョンのdockerイメージを指定します。

  nextcloud:
    image: nextcloud:24

これで23→24にアップデートする環境が整うので、以下のコマンドを実行してNextCloudを起動し、23から24へのアップデートを実行します。

$ sudo docker-compose up --build -d
$ sudo docker exec -u www-data <container name> php occ upgrade

version 24へのアップデートが正常に終了したら、再びdocker-compose.ymlを編集して元に戻します。その後に再び下記のコマンドを実行すれば、24から25へのバージョンアップを行えます。

$ sudo docker-compose up --build -d
$ sudo docker exec -u www-data <container name> php occ upgrade

PowershellからBITS(Background Intelligent Transfer Service)を使用して大容量ファイルを配布する

BITSはMicrosoftがWindowsに標準機能として載せている分散ダウンロード機能です。WindowsUpdateもバックグラウンドでBITSを利用しており、LAN内の複数のPCからWindowsUpdateをダウンロードする場合には、他のパソコンが自動的にキャッシュサーバーとなることで、インターネットとの通信負荷を押させてくれます。このBITSはWindowsUpdate専用の機能というわけではなく、簡単なプログラムを用意すれば、大容量ファイルを配布するときに自由に活用することができます。

昨今、プログラムやセキュリティパッチのフットプリント(ファイルサイズ)が大きく鳴り続ける、パッチ配布のネットワーク負荷が原因でインターネットが輻輳するなんて事件もありましたね。社内ネットワーク(WAN)はその構造上、どうしても一か所に負荷が集中しやすく、分散ダウンロードができると随分と助かりますね。

BITSでダウンロードするための一連の流れは次のようになります。

  1. HTTPサーバー上にダウンロード元となるファイルを用意します。
  2. Start-BitsTransferでBITSに新しいダウンロード要求を登録します。
  3. 定期的にGet-BitsTransferを呼び出しダウンロードの完了を待ちます。
  4. ダウンロード完了後にComplete-BitsTransferでファイルに書き出します。

上記をPowershell Scriptで記述したのが下記です。このスクリプトをダウンロードが完了するまで定周期で実行します。

$displayName = 'BITS_Sample'; # BITSにダウンロード要求を登録する時の表示名
$fromURL = 'http://www.example.co.jp/BITS_Sample.zip'; # ダウンロード元のURL
$destFile = 'C:\TEMP\BITS_Sample.zip'; # ダウンロード先のファイル名
$logFile = 'C:\TEMP\BITS_Sample.log' # ログ出力先のファイル名

$noBitsInstance = $true;
$completeDownload = $false;

Add-Content -Path $logFile -Value ('Start Script:' + (Get-Date));

# ダウンロード先フォルダが無ければ作成しておく
if ($false -eq (Test-Path 'C:\TEMP')){
    mkdir 'C:\TEMP';
}

# ダウンロードファイルが
if ($false -eq (Test-Path $destFile)){
    # BITSへのダウンロード要求を列挙する
    Get-BitsTransfer | Where-Object {
        Add-Content -Path $logFile -Value ('BITS Status:' + $_.DisplayName + '-' + $_.JobState);
        # 表示名の一致しているダウンロード要求が転送終了になるまで待機
        if ($_.DisplayName -eq $displayName){
            $noBitsInstance = $false;
            if ($_.JobState -eq "Transferred") {
         # ダウンロード完了した転送要求を完了させる
                Complete-BitsTransfer $_;
                $completeDownload = $true;
            }
        }
    }

    # BITSにダウンロード要求が登録されていなければ、新たに登録する。
    if ($noBitsInstance -eq $true){
        $delayMinute = Get-Random -Maximum 240;
        $kickDateTime = (Get-Date).AddMinutes($delayMinute);

        # 新規ダウンロード登録までランダムに待機する
        Add-Content -Path $logFile -Value ('Wait ' + $delayMinute + ' Minutes');
        While ($kickDateTime -ge (Get-Date)){
            Add-Content -Path $logFile -Value ('delay - ' + (Get-Date));
            sleep 60;
        }

        # 新規にダウンロードを登録する
        Add-Content -Path $logFile -Value ('Start BitsTransfer:' + $displayName + '-' + $destFile);
        Start-BitsTransfer -Source $fromURL -Destination $destFile -Asynchronous -Priority Normal -DisplayName $displayName
    }

    if ($completeDownload -eq $true){
        # ダウンロード完了後の処理
        Add-Content -Path $logFile -Value ('Complte Download:' + $displayName + '-' + $destFile);
    }
}
Add-Content -Path $logFile -Value ('End Script:' + (Get-Date));

私はActive Directoryのグループポリシーでログオンスクリプトとして登録しました。コントロールパネルのタスクで定周期に起動してもよいでしょう。

BITSで使用する帯域の制限などはレジストリに記述するか、ActiveDirectoryのグループポリシーで定義します。

Nextcloudに大きなファイルをアップロードするとRequestTimeTooSkewedが発生する

NextcloudでストレージにS3を使用している場合に、約500MBを超える大きなファイルをアップロードすると、以下のようなエラーが発生する場合がある。

An exception occurred while uploading parts to a multipart upload. The following parts had errors:
- Part 1: Error executing "UploadPart" on "https://nextcloud-xxxx.s3.us-west-1.wasabisys.com/xxxx"; AWS HTTP error: Client error: `PUT https://nextcloud-xxxx.s3.us-west-1.wasabisys.com/xxxx` resulted in a `403 Forbidden` response:
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>RequestTimeTooSkewed</Code><Message>The difference between the reque (truncated...)
RequestTimeTooSkewed (client): The difference between the request time and the current time is too large. - <?xml version="1.0" encoding="UTF-8"?>
<Error><Code>RequestTimeTooSkewed</Code><Message>The difference between the request time and the current time is too large.</Message><RequestTime>20220101T141414Z</RequestTime><ServerTime>2022-01-01T14:32:28Z</ServerTime><MaxAllowedSkewMilliseconds>900000</MaxAllowedSkewMilliseconds><RequestId>xxxx</RequestId><HostId>xxxx/xxxx</HostId></Error>

この問題を解決するには./html/config/config.phpに以下の行を追加し、500MBよりも適当に小さなサイズで分割してアップロードするように設定する。下記の例では約20MBに設定を変更している。

    array (
      'bucket' => 'nextcloud-bucket',
      'key' => '{key}',
      'secret' => '{secret}',
      'region' => 'us-west-1',
      'hostname' => 's3.us-west-1.wasabisys.com',
      'port' => '443',
      'objectPrefix' => 'urn:oid:',
      'autocreate' => false,
      'use_ssl' => true,
      'use_path_style' => false,
      'legacy_auth' => false,
      'uploadPartSize' => 20971520,
    ),

S3にsinglepartでアップロードできるファイルサイズの上限は5GBとなり、より大きなファイルをアップロードするときにはmultipartでアップロードする必要がある。標準設定のNextcloudでは約500MBを超えるファイルをアップロードするときにはmultipartアップロード を使用する。

S3のmultipartアップロードがもつ仕様上の問題で、通信帯域の不足等によりデータのアップロードに約15分以上かかると、HTTPヘッダに記載されている時刻とAWS側サーバーとの時刻の差がMaxAllowedSkewMillisecondsを超えるために”RequestTimeTooSkewed: The difference between the reque (truncated…)
RequestTimeTooSkewed (client): The difference between the request time and the current time is too large.”のエラーが発生する。

MaxAllowedSkewMillisecondsは900000msに固定されいる。HTTPのリクエストデータを複製することによる第三者の攻撃を防ぐために設けられている値で、ユーザー側でこの値を任意に変更する事は出来ない。この問題を避けるには15分以内にアップロードが終わる程度の適当なサイズに分割してアップロードする必要がある。

ただし小さく分割するとS3にアップロードできる最大ファイルサイズが小さくなる事にも注意しなくてはならない。S3には最大で5TBのファイルを保管できるが、 multipart アップロード時には10,000分割以上に分ける事ができない。仮に上記のように20MBで分割した場合には、200GBを超えるファイルをアップロード出来ない。(Amazon S3 multipart upload limits

NextcloudでRedisによるLock管理を有効にする

NextcloudのWindowsアプリからフォルダの同期を行っている途中、~ Locked errorが度々表示されていました。Nextcloudはデフォルトだとmysqlを使用してロック管理をしていますが、高負荷時に問題がおこる場合があるようです。ファイルのロックにかかる問題を回避するために、Redisを導入してTransactional file lockingを有効にします。

Docker環境でRedisを有効にするにはdocker-conpose.ymlに、redisのイメージを追加し、nextcloudのenvironemntにREDIS_HOST、REDIS_HOST_PORT、REDIS_HOST_PASSWORDを、下記の様に追加します。

version: '3'

volumes:
  nextcloud:
  nextcloud-db:
  nextcloud-redis:

services:
  nextcloud-redis:
    image: redis
    ports:
      - 6379:6379
    volumes:
      - ./redis:/data

  nextcloud-db:
    image: mariadb
      ...

  nextcloud:
    image: nextcloud
      ...
    environment:
      - REDIS_HOST=nextcloud-redis
      - REDIS_HOST_PORT=6379
      - REDIS_HOST_PASSWORD=${redis_password}

その後、以下のコマンドを実行します。

$ sudo docker-compose up -d

docker-compose.ymlの設定だけでは Transactional file locking は有効になっていません。./html/config/config.phpを編集して、「’filelocking.enabled’ => true,」を追記します。

  'filelocking.enabled' => true,
  'memcache.distributed' => '\\OC\\Memcache\\Redis',
  'memcache.locking' => '\\OC\\Memcache\\Redis',
  'redis' =>
  array (
    'host' => 'nextcloud-redis',
    'password' => '',
    'port' => 6379,
  ),

Nextcloudの暗号化を有効にするときの覚書

Nextcloud:Encryption configuration

暗号鍵の保存場所

暗号化を有効にしたとき、暗号鍵は./html/data/files_encryptionおよび ./html/data/ユーザー名/files_encryptionに保存されます。基本的にアップロードしたデータと同じ場所に鍵も保管されるため、プライマリストレージをS3等のストレージに変更しているか、あるいは外部ストレージを使用していない限り暗号化によるセキュリティ向上の恩恵はありません。

またこれらの暗号鍵を安全な場所にバックアップしておく必要があります。

回復パスワードの保存

上記フォルダの暗号鍵はログインパスワードを元にして暗号化されているため、ログインパスワードが分からなくなった場合に、パスワードの初期化を行うと暗号化したファイルを読むことが出来なくなります。

これを避ける為には事前に回復パスワードを作成しておく必要があります。

LDAPなど外部の認証システムとの連携

前項の理由により、LDAPなど外部の認証システムと連携している場合に、ファイブのシステム上でパスワードの変更を行う場合、そのままでは暗号ファイルを読み取ることが出来なくなります。Nextcloud上で新旧のパスワード入力を求められるため、そこで旧パスワードを入力する必要があります。

NextCloudでアップロード時に不明なエラーが発生する。

大きなファイルをアップロードしていると「不明なエラー」が発生します。ログを見ると以下の様なエラーが発生していました。どうも帯域が狭いために、アップロード中にタイムアウトエラーが発生しているようです。

Sabre\DAV\Exception\BadRequest: Expected filesize of 10485760 bytes but read (from Nextcloud client) and wrote (to Nextcloud storage) 5368032 bytes. Could either be a network problem on the sending side or a problem writing to the storage on the server side.

10,485,760 bytesは標準のチャンクサイズです。Nextcloudではアップロードをチャンクサイズのデータに分解して処理しています。10MB分送信する前にタイムアウトが発生してしまっていたようです。

タイムアウトを長くしても良いのですが、設定対象が多岐に渡るので、ここはチャンクサイズを5MBに調整する方向で対処します。occコマンドで設定を変更できますので、以下のコマンドを実行してチャンクサイズを変更します。

$ sudo docker-compose exec --user www-data nextcloud php occ config:app:set files max_chunk_size --value 5242880
Config value max_chunk_size for app files set to 5242880

再度ファイルをアップロードしたところ、エラーになる事無く上手く動いているようです。

NextCloudのアクセスログ管理

Nextcloudには標準で監査ログ機能があります。インターネットから接続出来る状態で運用するなら、監理者の責任としてログぐらいは残して起きたいところです。Docker上で動作させているNextCloudのログ設定をおこないます。

監査ログ出力のための設定

「Auditing / Logging」プラグインが有効になっていることを確認して下さい。標準で有効になっているはずです。

以下のコマンドを実行してログの設定をログレベル:1、タイムズーんを日本に変更します。現時点(バージョン23.0.0)では–rotate-sizeの設定は機能しません。明示的にNextcloudのLog Rotateを無効にしておき、別にlogrotateを設定する事にします。

$ sudo docker-compose exec --user www-data nextcloud php occ log:manage --level=info --timezone Asia/Tokyo
Enabled logging backend: file
Log level: Info (1)
Log timezone: Asia/Tokyo

$ sudo docker-compose exec --user www-data nextcloud php occ log:file --rotate-size=0
Log backend file: enabled
Log file: /var/www/html/data/nextcloud.log
Rotate at: disabled

これで./html/data/audit.logに監査ログが出力されるようになるはずです。

Log Rotateの設定

/etc/logrotate.d/nextcloudを以下の通り作成します。パス名の/var/docker-nextcloudは自信の環境に置き換えて下さい。

/var/docker-nextcloud/html/data/nextcloud.log {
  monthly
  rotate 12
  missingok
  notifempty
  compress
  delaycompress
  postrotate
    touch /var/docker-nextcloud/html/data/nextcloud.log
    chown www-data:www-data /var/docker-nextcloud/html/data/nextcloud.log
    chmod 640 /var/docker-nextcloud/html/data/nextcloud.log
  endscript
}

/etc/logrotate.d/nextcloudauditを以下の通り作成します。

/var/docker-nextcloud/html/data/audit.log {
  monthly
  rotate 12
  missingok
  notifempty
  compress
  delaycompress
  postrotate
    touch /var/docker-nextcloud/html/data/audit.log
    chown www-data:www-data /var/docker-nextcloud/html/data/audit.log
    chmod 640 /var/docker-nextcloud/html/data/audit.log
  endscript
}

以下の通りlogrotateデーモンを再起動します。

$ sudo service logrotate restart

以上で毎月ログが圧縮されて別ファイルとなり、12ヶ月でローテーションされます。

NextCloud設定画面のセキュリティ&セットアップ警告に対応する

NextCloudでWEBストレージサービスを自前で作成する」でNextCloudのDocker環境を構築しましたが、そのままだと設定→概要でセキュリティ警告が表示されています。消せる警告は消していきたいと思います。

信頼できるプロキシーの設定

docker-compose.ymlにTRUSTED_PROXIESとOVERWRITEHOSTを追加します。

services:
  nextcloud:
    ...
    environment:
      ...
      - TRUSTED_PROXIES=127.0.0.1
      - OVERWRITEHOST=next.code-lab.net
      - OVERWRITEPROTOCOL=https
      ...

以下のコマンドを実行して設定を反映します。

sudo docker-compose up -d

「リバースプロキシヘッダーの構成が正しくないか、信頼できるプロキシからNextcloudにアクセスしています。そうでない場合、これはセキュリティに問題があり、攻撃者がNextcloudを表示できるようにIPアドレスを偽装することができます。詳細については、ドキュメント↗をご覧ください。」の警告が消えて居ることを確認して下さい。

Strict-Transport-Securityの設定

リバースプロキシサーバーにはNginxを使用しているので、/etc/nginx/sites-available/next.code-lab.net.confを編集して「add_header Strict-Transport-Security ‘max-age=15552000; includeSubDomains; preload’;」を追加します。

server {
    ...
    add_header Strict-Transport-Security 'max-age=15552000; includeSubDomains; preload';
    ...
}

以下のコマンドを実行して設定を反映します。

sudo service nginx restart

「Strict-Transport-Security “HTTP ヘッダーの秒数が少なくとも”15552000” に設定されていません。セキュリティを強化するには、セキュリティのヒント↗で説明されているようにHSTSを有効にすることをお勧めします。」 の警告が消えて居ることを確認して下さい。

default_phone_regionの設定

./html/config/config.phpを編集してdefault_phone_regionを追加します。残念ながらDockerの環境変数から指定する事はできないようです。

<?php
$CONFIG = array (
 ...
 'default_phone_region' => 'JP',
 ...
);

以下のコマンドを実行して設定を反映します。

sudo docker-compose restart

「ご使用のシステムには、デフォルトの電話地域が設定されていません。これは、国コードなしでプロファイル設定の電話番号を検証するために必要です。国コードなしで番号を許可するには、地域のそれぞれの ISO3166-1コード↗とともに “default_phone_region” を設定ファイルに追加してください。」 の警告が消えて居ることを確認して下さい。

DBにインデックスを作成する

以下のコマンドを実行します。

$ sudo docker-compose exec --user www-data nextcloud php occ db:add-missing-indices
Check indices of the share table.
Check indices of the filecache table.
Adding additional size index to the filecache table, this can take some time...
Filecache table updated successfully.
Adding additional path index to the filecache table, this can take some time...
Filecache table updated successfully.
Check indices of the twofactor_providers table.
Check indices of the login_flow_v2 table.
Check indices of the whats_new table.
Check indices of the cards table.
Check indices of the cards_properties table.
Check indices of the calendarobjects_props table.
Check indices of the schedulingobjects table.
Check indices of the oc_properties table.

「データベースにいくつかのインデックスがありません。~」 の警告が消えて居ることを確認して下さい。

「php-imagickモジュールはSVGをサポートしていません。」の警告が残っています。Dockerイメージを更新すれば良さそうですが、メリットが薄そうなのでこの警告は容認する事とします。

Nextcloudにアップロードできるファイルサイズ上限を増やす

デフォルトの設定のままだと512MBを超えるファイルサイズを扱うことが出来ません。以下の設定を変更してアップロードできるファイルサイズの上限を変更します。

Nginxの.confにclient_max_body_size 51200M;を追加します。

 server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ...
    client_max_body_size 51200M;
    ...
}

以下の通りdocker-compose.ymlにPHP_MEMORY_LIMIT=512MとPHP_UPLOAD_LIMIT=51200Mを追加します。

version: '3'

volumes:
  nextcloud:
  nextcloud-db:

services:
  nextcloud-db:
    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
    restart: always
    ports:
      - 3307:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD}
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  nextcloud:
    image: nextcloud
    ports:
      - 8081:80
    links:
      - nextcloud-db
    volumes:
      - ./html:/var/www/html
    restart: always
    environment:
      - NEXTCLOUD_TRUSTED_DOMAINS='next.code-lab.net'
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_HOST=nextcloud-db:3306
      - OBJECTSTORE_S3_HOST=ewr1.vultrobjects.com
      - OBJECTSTORE_S3_BUCKET=nextcloud-root
      - OBJECTSTORE_S3_KEY=S3_KEY
      - OBJECTSTORE_S3_SECRET=S3_SECRET
      - OBJECTSTORE_S3_PORT=443
      - OBJECTSTORE_S3_SSL=true
      - OVERWRITEPROTOCOL=https
      - PHP_MEMORY_LIMIT=512M
      - PHP_UPLOAD_LIMIT=51200M

NginxとDockerコンポーネントを再起動します。

sudo service nginx restart
sudo docker-compose stop
duso docker-compose up -d

その後にNextcloud上で設定→システムを参照すると以下の様に最大アップロードサイズが大きくなっているかと思います。

NextCloudでWEBストレージサービスを自前で作成するよ

リモートワークや非PPAP対応のために、WEBストレージサービスが使われることが増えています。でもWEBストレージサービスの多くはユーザーライセンス方式・・・消費する容量が少なくとも、使用頻度が低くとも、ユーザー数が増えるとライセンス料がかさんでしまいます。そこでオープンソースのNextCloudを活用して時前のWEBストレージサービスを構築することを考えてみます。

NextCloudのインストール

NextCloudをインストールする方法はいくつかあります。AWSにはNextCloud公式のAMIファイル(355428426254/Nextcloud-21.0.1-RHEL8-ja_JP)があるので、これを使っても容易にサーバーを作ることが出来ます。

今回は運用の容易さを考えてNextCloud公式のDocker Image(https://hub.docker.com/_/nextcloud)を使って構築したいと思います。DockerおよびDocker-Composeが動作する環境を構築するところは割愛します。

NextCloudにアップロードしたファイルはプライマリストレージ(通常は”./html/data”)に保存されます。今回はストレージコストを抑えるために、プライマリストレージにはAWS S3を指定することにします。

docker-compose.ymlを用意します。

version: '3'

volumes:
  nextcloud:
  nextcloud-db:

services:
  nextcloud-db:
    image: mariadb
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
    restart: always
    ports:
      - 3306:3306
    volumes:
      - ./mysql:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD}
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud

  nextcloud:
    image: nextcloud
    ports:
      - 8081:80
    links:
      - nextcloud-db
    volumes:
      - ./html:/var/www/html
    restart: always
    environment:
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
      - MYSQL_HOST=nextcloud-db:3306
      - OBJECTSTORE_S3_HOST=s3.region.amazonaws.com
      - OBJECTSTORE_S3_BUCKET=bucketname
      - OBJECTSTORE_S3_KEY=[accesskey]
      - OBJECTSTORE_S3_SECRET=[secretkey]
      - OBJECTSTORE_S3_PORT=443
      - OBJECTSTORE_S3_SSL=true
      - OVERWRITEPROTOCOL=https

.envファイルを用意します。

# docker-compose内で利用する環境変数をここで設定します。
# 下記2つの環境変数に、適当な文字列を設定してください。
ENV_MYSQL_ROOT_PASSWORD=root_password
ENV_MYSQL_PASSWORD=user_password

nginxでリバースプロキシを構成すためのconfファイル(/etc/nginx/sites-available/next.example.net.conf)を作成します。

server {
    listen 80;
    listen [::]:80;

    server_name next.example.net;
    return 301 https://$host$request_uri;
 }

 server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/next.example.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/next.example.net/privkey.pem;

    server_name next.example.net;

    client_max_body_size 20M;
    client_header_buffer_size 64k;
    large_client_header_buffers 4 64k;

    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-Proto  https;
    proxy_set_header    X-Forwarded-Host   $host;
    proxy_set_header    X-Forwarded-Server $host;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    proxy_redirect      off;
    proxy_connect_timeout       3600;
    proxy_send_timeout          3600;
    proxy_read_timeout          3600;
    send_timeout                3600;

    location / {
        proxy_pass    http://localhost:8081/;
    }

    location /.well-known/carddav {
        return 301 $scheme://$host/remote.php/dav;
    }

    location /.well-known/caldav {
        return 301 $scheme://$host/remote.php/dav;
    }
}

以上、必要な設定の記述が終わりましたので、以下のコマンドを実行して起動します。

# sites-enabledにシンボリックリンクを作成
sudo ln -s /etc/nginx/sites-available/next.example.com /etc/nginx/sites-enabled/next.example.com
# nginxサービスを再起動
sudo service nginx restart
# dockerを起動
sudo docker-compose up

WEBブラウザでhttps://next.example.net/を開きます。

以下の画面で監理者アカウントのユーザー名とパスワードを指定しして「セットアップを完了します」をクリックしてください。しばらく待つと初期設定が終わり、NextCloudにログインできます。

NextCloudの基本的な初期設定

メールサーバーの指定

右上の○アイコンからメニューを開き設定を選択します。最初に個人情報タブのメールを設定しておきます。ここを設定しておかないとSMTPサーバーの設定をできません。

続いて基本設定タブを選択します。メールサーバーの設定を行います。

多要素認証の設定

右上の○アイコンからメニューを開き アプリを選択します。セキュリティタブから’OpenOTP Two Factor Authentication’と’Two-Factor Email’をダウンロードして有効にします。

これで設定のセキュリティタブに二要素認証の項目が追加されます。

Enabled Two Factor Emailをクリックすると認証用のメールが届きますので、認証コードを入力します。

TOTPの有効化のチェックをするとQRコードが表示されるので、TOTPに対応したGoogle Authenticater等のアプリでQRコードを読み取り、ワンタイムパスワードを入力して認証します。

外部ストレージの有効化

NextCloud上にアップロードしたファイルは’urn:oid:100’といったファイル名に保管されます。これらのファイルは NextCloud 上で無ければ確認する事ができません。これに対して外部ストレージのファイルは、画面上に表示されているファイル名そのままで保存されています。

外部ストレージ上のファイルはNextCloud以外からも読み書き出来ます。既存NASからのデータ移行や、NextCloud以外のシステムとの連携など、便利に使用する事ができます。ユーザー単位やユーザーグループ単位でアクセス制限をかける事が出来るので、部署単位での共有フォルダなども外部ストレージを使用すると便利です。

外部ストレージを使用するにはメニューからアプリを選択して無効なアプリタブにある’External storage support’を有効にします。その後、メニューから設定を開くと外部ストレージタブが追加されています。

上記では標準共有という名称でS3のバケットに接続しています。