NextCloud on Dockerで外付けSSD/HDDをマウントする

これまでの記事では、NextCloudの公式サンプルを利用してHTTPS通信が可能なDockerイメージの作成を行ってきました。

今回は、少しだけdocker-compose.yamlを変更することで、NextCloudで利用するデータを外付けSSD/HDDに保存する方法を紹介します。

ディレクトリ構成

今回のディレクトリ構成はこちらです。

.
├── docker-compose.yaml
├── env
│   └── db.env
├── proxy
│   ├── Dockerfile
│   └── uploadsize.conf
└── volume
    ├── nextcloud
    │   └── var
    │       └── www
    │           └── html
    └── postgresql
        └── var
            └── lib
                └── postgresql

ポイントは、volumeディレクトリ下のnextcloudフォルダに外付けSSD/HDDをマウントしています。

下記でdocker-compose.yamlを載せていますが、NextCloudのデータは基本的にnextcloud/var/www/htmlディレクトリ以下に保存するようにしています。

外付けSSD/HDDのマウント

外付けSSDをマウントする方法を紹介します。ここでは、デバイスのPARTUUIDを利用してマウントしています。

注意点

PARTUUIDでマウントするのは、Ubuntuを想定しています。CentOSでは単純なUUIDなので、お使いの環境に合わせて変更してください。

また、PARTUUIDはデバイスのフォーマットを行うと変更されます。NextCloudのデータ保存用よして利用する場合、HDDのファイルシステムを変更・フォーマットすることはあまり無いかと思いますが、PARTUUIDは変わりうる値ということに注意してください。

USBなどで外付けSSDを取り付けたら、デバイス番号(/dev/sda等)を確認します。下記の例では、/dev/sdaになっていますね。

$ lsblk
...
sda           8:0    0 931.5G  0 disk 
└─sda1        8:1    0 931.5G  0 part 
...

次に、volume/nextcloud/var/www/htmlにマウントします。マウントはPARTUUIDを利用して行います。(/dev/sdaは、デバイスの接続状況に応じて変更される可能性が高いので、デバイスに対して一意なPARTUUIDを利用します。)

# プロジェクトのルートディレクトリで実行

$ ROOT_DIR=`pwd`

$ TARGET_DIR=$ROOT_DIR/volume/nextcloud/var/www/html

$ mkdir -p $TARGET_DIR

# check UUID of /dev/sda1
$ DEV_UUID=`sudo blkid | grep /dev/sda1 | sed -n 's/.*PARTUUID="\([^"]*\)".*/\1/p'`

$ sudo mount -t ext4 PARTUUID=$DEV_UUID $TARGET_DIR

$ sudo chown -R $USER:$USER $TARGET_DIR

上記では、blkidコマンドでPARTUUIDを取得しています。また、chownコマンドでマウント後のディレクトリの所有者を現在のログインユーザーに変更しています。

chownコマンドによる所有権の変更は必須ではないのですが、mountコマンドはデフォルトでrootユーザが所有者になるので、ファイルの編集時にsudoコマンドが必要になっていまいます。所有権を変更しておくことをおすすめします。

ここまでで、外付けSSDのマウントは完了です。

docker-compose.yamlの作成

メインとなるdocker-compose.yamlはこちらです。

version: '3.4'

x-logging: 
  &default-logging
  options:
    max-size: '25M'
    max-file: "4"

services:
  db:
    image: postgres:15.3-alpine3.18
    restart: always
    volumes:
      - ./volume/postgresql/var/lib/postgresql/data:/var/lib/postgresql/data:Z
      - /etc/group:/etc/group:ro
      - /etc/passwd:/etc/passwd:ro
    env_file:
      - ./env/db.env
    user: 1000:1000
    logging: *default-logging

  redis:
    image: redis:7.0.11-alpine3.18
    restart: always
    logging: *default-logging

  app:
    image: nextcloud:25.0.7-apache
    restart: always
    volumes:
      - ./volume/nextcloud/var/www/html:/var/www/html:z
      - /etc/group:/etc/group:ro
      - /etc/passwd:/etc/passwd:ro
    environment:
      - VIRTUAL_HOST=<your-domain.com>
      - LETSENCRYPT_HOST=<your-domain.com>
      - LETSENCRYPT_EMAIL=<your email address>
      - POSTGRES_HOST=db
      - REDIS_HOST=redis
    env_file:
      - ./env/db.env
    depends_on:
      - db
      - redis
    networks:
      - proxy-tier
      - default
    user: 1000:1000
    logging: *default-logging

  cron:
    image: nextcloud:25.0.7-apache
    restart: always
    volumes:
      - ./volume/nextcloud/var/www/html:/var/www/html:z
      - /etc/group:/etc/group:ro
      - /etc/passwd:/etc/passwd:ro
    entrypoint: /cron.sh
    depends_on:
      - db
      - redis
    user: 1000:1000
    logging: *default-logging

  proxy:
    build: ./proxy
    restart: always
    ports:
      - 80:80
      - 443:443
    labels:
      com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy: "true"
    volumes:
      - certs:/etc/nginx/certs:z,ro
      - vhost.d:/etc/nginx/vhost.d:z
      - html:/usr/share/nginx/html:z
      - /var/run/docker.sock:/tmp/docker.sock:z,ro
    networks:
      - proxy-tier
    logging: *default-logging

  letsencrypt-companion:
    image: nginxproxy/acme-companion:2.2.8
    restart: always
    volumes:
      - certs:/etc/nginx/certs:z
      - acme:/etc/acme.sh:z
      - vhost.d:/etc/nginx/vhost.d:z
      - html:/usr/share/nginx/html:z
      - /var/run/docker.sock:/var/run/docker.sock:z,ro
    networks:
      - proxy-tier
    depends_on:
      - proxy
    logging: *default-logging

volumes:
  certs:
  acme:
  vhost.d:
  html:

networks:
  proxy-tier:

基本的に、公式で公開されているサンプル通りですが、下記について特に変更を行っています。

参考:公式のサンプル

ロギングの設定

version3.4を利用することで、loggingの設定を外で定義し、各サービス内でその定義を参照するようにしています。

x-logging: 
  &default-logging
  options:
    max-size: '25M'
    max-file: "4"

services:
  db:
    logging: *default-logging

Docker Composeでは、デフォルトでは無限にログを残し続けるため、ログの最大容量を決めておくことをおすすめします。

マウントするボリュームの所有者設定

Dockerでは、マウントするボリュームの所有者がデフォルトでrootユーザになります。設定ファイルを編集するたびにsudoコマンドを利用するのは面倒なので、ボリュームの所有者をログインユーザーに変更しています。

services:
  app:
    volumes:
      - /etc/group:/etc/group:ro
      - /etc/passwd:/etc/passwd:ro
    user: 1000:1000

上記の部分が設定箇所です。

マウントした外付けSSDをDockerコンテナにマウントする

上記で、外付けSSDをvolume/nextcloud/var/www/htmlにマウントしましたが、このディレクトリをDockerコンテナにマウントしています。

services
  app:
    image: nextcloud:25.0.7-apache
    volumes:
      - ./volume/nextcloud/var/www/html:/var/www/html:z

上記の設定を行うことで、外付けSSDにデータを保存することが可能です。

その他のファイル(envディレクトリやproxyディレクトリ)

これらは公式のサンプルをそのまま利用しているので、気になる方は前回の記事か、公式のサンプルを参考にしてください。

公式のサンプルは下記です。

https://github.com/nextcloud/docker/tree/master/.examples/docker-compose/with-nginx-proxy/postgres/apache

コンテナの起動

ルートディレクトリで、下記コマンドを実行します。

$ docker compose up -d

起動したら、ブラウザでhttps://<your-domain.com>にアクセスすると、NextCloudのトップ画面が表示されます。

終了したいときは、下記のコマンドで終了します。

$ docker compose down

まとめ

この記事ではNextCloud on Dockerの環境で、外付けSSD/HDDをデータの保存先として利用する方法を紹介しました。

これ以降は下記について紹介していく予定です。

  • NextCloudの設定について(2段階認証や、各設定値)
  • クラウドへのデータのバックアップ方法
  • 外付けHDDのRAID化

  • この記事を書いた人

たかさん

犬と暮らすクラウドエンジニア。GCPが好きだけど良く触るのはAWSとAzureです。

-NextCloud
-, ,