動機メモ
- iPhoneの写真をバックアップしたい
- Linuxのサーバと別にメイン端末がありWinodwsである
- 既にWindowsで使用していたバックアップHDDがある
- 写真のバックアップが既にある
- NASを整備したいが
- NAS専用のPCは設置したくない
- できるだけ環境は汚したくない
- 環境構築は手軽でありたい
- 堅牢なデータであって欲しい
- 様々な端末からアクセスしたい
DockerでNextcloudを運用しつつ、外部ストレージとしてNTFSフォーマットした既存HDDをNextcloudからアクセスできるようにする
Nextcloud(Docker)でホストストレージを永続共有&外部ストレージ(NTFS)を接続する手順
目的:コンテナを落としてもデータが消えず、ホスト(Ubuntu Server)から直接確認できる構成にする。さらに、NTFS でフォーマットされた外部ディスクを Nextcloud の「外部ストレージ」として見せる。
全体像(アーキテクチャ)
-
Docker Compose で Nextcloud(
nextcloud:apache) と MariaDB を起動 - Nextcloud のアプリデータ・DB データは Bind Mount(ホストの任意パス) に保存
- 外部 NTFS ディスク(例:
/dev/sda1)を/mnt/sda1にマウントし、コンテナに/mnt/sda1として見せる - Nextcloud 32 は UI に「ローカル」外部ストレージが出ないため、
occCLI で登録
前提
- OS:Ubuntu Server(systemd 使用)
- Docker / Docker Compose 利用
- Nextcloud イメージ:
nextcloud:apache - タイムゾーン:Asia/Tokyo
ディレクトリ設計(ホスト側)
/mnt/nvme1n1/nextcloud/
├─ app/ ← Nextcloud 本体(/var/www/html)をBind Mount
└─ db/ ← MariaDB データ(/var/lib/mysql)をBind Mount
/mnt/sda1/ ← 外部 NTFS ディスクのマウントポイント(外部ストレージとして見せる)
/mnt/sda1は NTFS でフォーマットされた外部ディスク。
最悪NextCloudが転んだ時にWindowsで確認できると嬉しいから。
最終版 docker-compose.yml(例)
services:
db:
container_name: nextcloud-db
image: mariadb
restart: always
command: --innodb-fast-shutdown=0 # ← シャットダウン時に完全フラッシュ
stop_grace_period: 60s # ← シャットダウン猶予を60秒に延長
volumes:
- /mnt/nvme1n1/nextcloud/db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${ENV_MYSQL_ROOT_PASSWORD}
- MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
app:
container_name: nextcloud-app
image: nextcloud:latest
restart: always
depends_on:
- db
- redis
stop_grace_period: 45s # ← アプリも猶予を確保
ports:
- "8080:80"
volumes:
- /mnt/nvme1n1/nextcloud/app:/var/www/html
- /mnt/sda1:/mnt/sda1
- /mnt/sdb2:/mnt/sdb2
- /mnt/sdb3:/mnt/sdb3
environment:
- TZ=Asia/Tokyo
- MYSQL_HOST=db
- MYSQL_DATABASE=nextcloud
- MYSQL_USER=nextcloud
- MYSQL_PASSWORD=${ENV_MYSQL_PASSWORD}
redis:
container_name: nextcloud-redis
image: redis:alpine
restart: always
environment:
- REDIS_PASSWORD=${ENV_REDIS_PASSWORD}
command: ["redis-server", "--requirepass", "${ENV_REDIS_PASSWORD}"]
volumes:
- /mnt/nvme1n1/nextcloud/redis:/data
ENV_MYSQL_ROOT_PASSWORD=rootpassword
ENV_MYSQL_PASSWORD=dbpassword
ENV_REDIS_PASSWORD=superpassword
末尾の
volumes:ルート定義(匿名ボリューム)は 不要(Bind Mount を使うため)。
.env(例)
ENV_MYSQL_ROOT_PASSWORD=your_root_pw
ENV_MYSQL_PASSWORD=your_user_pw
1) Nextcloud 用の保存先を作成(Bind Mount)
sudo mkdir -p /mnt/nvme1n1/nextcloud/app
sudo mkdir -p /mnt/nvme1n1/nextcloud/db
# Nextcloud と MariaDB が書き込みできるように所有権を付与(www-data = UID 33, GID 33)
sudo chown -R 33:33 /mnt/nvme1n1/nextcloud/app
sudo chown -R 33:33 /mnt/nvme1n1/nextcloud/db
既存データを移す場合:
sudo rsync -av ./nextcloud_app/ /mnt/nvme1n1/nextcloud/app/
sudo rsync -av ./nextcloud_db/ /mnt/nvme1n1/nextcloud/db/
2) 外部 NTFS ディスクを /mnt/sda1 にマウント(永続化)
2-1. デバイス確認
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
# 例:/dev/sda1 が NTFS
Linux の デバイス名(ブロックデバイス名)について
| デバイス名例 | 種類 | 意味 |
|---|---|---|
/dev/sda |
SATA / USB HDD | 1台目のSCSI互換ディスク |
/dev/sdb |
SATA / USB HDD | 2台目のSCSI互換ディスク |
/dev/sda1 |
パーティション | sdaの1番目の領域 |
/dev/nvme0n1p2 |
NVMe SSD | NVMeコントローラ0、デバイス1のパーティション2 |
/dev/mmcblk0p1 |
eMMC/SD | eMMCまたはSDカードのパーティション1 |
昔は「SCSI ディスクドライバ」で管理していたので:
sd= SCSI disk
a= ディスクの番号(a=1台目、b=2台目…)
1= パーティション番号(1=最初の領域)
- 検出順序(BIOS/UEFIまたはLinuxカーネルが認識した順)によって変わる
- → 早く認識された順に sda, sdb, sdc… と割り当てられる
- → USBを抜き差ししたり起動順が変わると、順序も変わることがある
- 接続ポートやデバイス種別によって変わる
- SATA / USB / NVMe / SD で接頭辞が異なる(sd / nvme / mmcblk)
- NVMeは独自形式(nvme0n1p1 など)
- 順番が変わると /dev/sdb が次回は /dev/sdc になってしまうことがある
- そのため、/etc/fstab では次のように UUID や LABEL で指定するのが安全
- UUID は固定的なので、再起動や抜き差しでも変わらない
# 安定的にマウントする方法
UUID=0000000000000000 /mnt/sda1 fuse.ntfs defaults,uid=33,gid=33,umask=000 0 0
# 確認コマンド:
sudo blkid
2-2. UUID 確認
sudo blkid | grep sda1
# 例: UUID="9602FB2002FB03D1" TYPE="ntfs"
2-3. /etc/fstab に追記(ntfs-3g を明示)
Ubuntu ではカーネルの NTFS3 ドライバだと
uid/gidが効かない場合があるため、FUSE のntfs-3gを明示します。
# /etc/fstab の末尾に追記
UUID=0000000000000000 /mnt/sda1 fuse.ntfs defaults,uid=33,gid=33,umask=000,windows_names 0 0
2-4. マウントポイントの権限と再マウント
# /mnt は必ず root:root 755 に(基本の作法)
sudo chown root:root /mnt
sudo chmod 755 /mnt
# マウントポイントを作成
sudo mkdir -p /mnt/sda1
# 再マウント
sudo umount /mnt/sda1 2>/dev/null || true
sudo mount -a
# 確認(www-data 所有に見えればOK)
ls -ld /mnt/sda1
# drwxrwxrwx 1 www-data www-data ... /mnt/sda1
補足:一時テストマウント(fstab を介さずに)
sudo umount /mnt/sda1 2>/dev/null || true
sudo ntfs-3g /dev/sda1 /mnt/sda1 -o uid=33,gid=33,umask=000
3) Docker Compose 起動
docker compose down
docker compose up -d
# コンテナ内から /mnt/sda1 が見えるか
docker exec -it nextcloud-app bash -lc 'ls -ld /mnt/sda1'
# drwxrwxrwx 1 www-data www-data ... /mnt/sda1
4) Nextcloud 側の設定
4-1. 外部ストレージアプリとローカル許可の確認
# 外部ストレージアプリ(files_external)が有効か
docker exec -u www-data nextcloud-app php occ app:list | grep files_external
# → 例: "- files_external: 1.24.0"
# ローカルストレージ許可
docker exec -u www-data nextcloud-app php occ config:system:set enable_local_storage --value=true --type=bool
Nextcloud 32 の仕様:Web UI のプルダウンには「ローカル」が表示されない。CLI から登録する。
4-2. CLI で「ローカル外部ストレージ」を登録
# マウントポイント /mnt/sda1 を Nextcloud に登録
docker exec -u www-data nextcloud-app php occ \
files_external:create /mnt/sda1 local null::null -c "datadir=/mnt/sda1"
# 登録確認
docker exec -u www-data nextcloud-app php occ files_external:list
出力例:
+----------+-------------+--------+---------------------+------------------------+
| Mount ID | Mount Point |Storage | Authentication Type | Configuration |
+----------+-------------+--------+---------------------+------------------------+
| 1 | /mnt/sda1 | Local | None | datadir: "/mnt/sda1" |
+----------+-------------+--------+---------------------+------------------------+
表示名を分かりやすくしたい場合:
# 表示名を /ExternalHDD に変更(Mount ID は上の list 出力で確認)
docker exec -u www-data nextcloud-app php occ files_external:config 1 mountpoint "/ExternalHDD"
既存のストレージをNoxtcloudから読み込み
docker exec -u www-data nextcloud-app php occ files_external:scan 1
+---------+-------+--------------+
| Folders | Files | Elapsed time |
+---------+-------+--------------+
| 1 | 0 | 00:00:03 |
+---------+-------+--------------+
tips: -hでhelpが閲覧できる
docker exec -u www-data nextcloud-app php occ files_external -h
Nextcloud 32.0.1
Usage:
command [options] [arguments]
Options:
-h, --help Display help for the given command. When no command is given display help for the list command
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi|--no-ansi Force (or disable --no-ansi) ANSI output
-n, --no-interaction Do not ask any interactive question
--no-warnings Skip global warnings, show command output only
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
Available commands for the "files_external" namespace:
files_external:applicable Manage applicable users and groups for a mount
files_external:backends Show available authentication and storage backends
files_external:config Manage backend configuration for a mount
files_external:create Create a new mount configuration
files_external:delete Delete an external mount
files_external:dependencies Show information about the backend dependencies
files_external:export Export mount configurations
files_external:import Import mount configurations
files_external:list List configured admin or personal mounts
files_external:notify Listen for active update notifications for a configured external mount
files_external:option Manage mount options for a mount
files_external:scan Scan an external storage for changed files
files_external:verify Verify mount configuration
5) 既存ファイルを Nextcloud に認識させる(手動配置後)
5-1. Nextcloud のユーザーデータ構造
/mnt/nvme1n1/nextcloud/app/data/
└─ <ユーザー名>/
├─ files/ ← ここに置いたものがUIに出る
├─ files_trashbin/
├─ files_versions/
└─ ...
5-2. 例:Yuzuriha ユーザーにファイルを投入
# HDD → Nextcloud ユーザーfilesへコピー
sudo rsync -av /path/from/ /mnt/nvme1n1/nextcloud/app/data/Yuzuriha/files/
# 所有者を www-data に統一
sudo chown -R 33:33 /mnt/nvme1n1/nextcloud/app/data/Yuzuriha/files/
# Nextcloud にファイル一覧を再スキャン
docker exec -u www-data nextcloud-app php occ files:scan --path="Yuzuriha/files"
# または全ユーザー
# docker exec -u www-data nextcloud-app php occ files:scan --all
トラブルシューティング
A. 「外部ストレージに Local が出ない」
- Nextcloud 32 では UI から「ローカル」が消えている → CLI で登録
-
files_externalが有効か:occ app:list | grep files_external -
enable_local_storageがtrueか:occ config:system:get enable_local_storage - ブラウザ再ログイン / キャッシュクリア
B. /mnt/sda1 が Permission denied
-
/mnt自体の所有者がwww-dataになっていると NG →root:root 755に戻すsudo chown root:root /mnt sudo chmod 755 /mnt -
その上で
/etc/fstabのfuse.ntfs行を見直し、uid=33,gid=33,umask=000を指定して再マウント
C. uid/gid が反映されない(root:root のまま)
-
カーネルの NTFS3 ドライバが使われていると
uid/gidが効かない →fuse.ntfs(ntfs-3g)を明示 -
一時マウントテスト:
sudo umount /mnt/sda1 sudo ntfs-3g /dev/sda1 /mnt/sda1 -o uid=33,gid=33,umask=000
D. デバイス名の取り違え
-
/dev/sdb1ではなく/dev/sda1だった、など →lsblkで要確認 - 可能なら UUID 指定で fstab 記述(デバイス名の変動に強い)
E. Nextcloud にファイルが出ない
- 手動で
data/<ユーザー>/files/に置いた後は、occ files:scanが必須 - 所有者が
www-data:www-dataになっているか要確認
コマンド早見表
# デバイス確認
lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
sudo blkid | grep sda1
# fstab(ntfs-3g 明示)例
# UUID=9602FB2002FB03D1 /mnt/sda1 fuse.ntfs defaults,uid=33,gid=33,umask=000,windows_names 0 0
# 再マウント
sudo umount /mnt/sda1 2>/dev/null || true
sudo mount -a
ls -ld /mnt/sda1
# Docker 再起動
docker compose down && docker compose up -d
# Nextcloud 側(CLI)
docker exec -u www-data nextcloud-app php occ status
# 外部ストレージアプリの確認
docker exec -u www-data nextcloud-app php occ app:list | grep files_external
# ローカルストレージ許可
docker exec -u www-data nextcloud-app php occ config:system:set enable_local_storage --value=true --type=bool
# ローカル外部ストレージ登録(Nextcloud 32)
docker exec -u www-data nextcloud-app php occ files_external:create /mnt/sda1 local null::null -c "datadir=/mnt/sda1"
# 一覧
docker exec -u www-data nextcloud-app php occ files_external:list
# 表示名変更(Mount ID は list で確認)
docker exec -u www-data nextcloud-app php occ files_external:config 1 mountpoint "/ExternalHDD"
# ファイルスキャン
docker exec -u www-data nextcloud-app php occ files:scan --all
セキュリティと運用メモ
-
umask=000は誰でも書込可。運用で制限したい場合はumask=022(所有者書込、他は読取のみ)などへ調整。 - 外部ディスクを取り外す際は、Nextcloud がそのパスを参照中でないか確認の上、
umount。 - バックアップ:
/mnt/nvme1n1/nextcloud/{app,db}を rsync / borg / restic 等で定期バックアップ推奨。
付録:よくある落とし穴と対処
- /mnt の所有者を www-data にしてしまう → マウント失敗や Permission denied の温床。root:root 755 に戻す。
-
デバイス名の取り違え(sdb1 と勘違い) →
lsblkとblkidで必ず確認。UUID 指定が安全。 -
Nextcloud 32 で「ローカル」が UI に無い → 仕様。
occ files_external:createで登録する。 -
NTFS3 だと uid/gid が効かない →
fuse.ntfs(ntfs-3g) をfstabに明示。