Nextcloud Docker 檔案儲存位置與備份指南
解析 Nextcloud 在 Docker 容器內的資料目錄路徑,並說明如何透過 docker inspect 查詢宿主機掛載點。本指南涵蓋具名 Volume 與 Bind mount 的差異,確保您能完整備份資料庫與設定檔,而非僅複製使用者檔案。
Nextcloud 在 Docker 中的檔案儲存位置
Nextcloud 在 Docker 中將檔案儲存於容器內的資料目錄,而其實際存放於伺服器上的位置,取決於您所掛載的 volume 或 bind mount。若使用 linuxserver.io 的映像檔,lscr.io/linuxserver/nextcloud,使用者檔案位於 /data,而包含 config.php 的 Nextcloud 安裝目錄則位於 /config。這兩者皆為容器內的絕對路徑。透過指令即可查出對應的宿主機路徑,而本指南其餘部分將探討問題中較困難的部分:即資料目錄以外的所有內容。
請鎖定映像檔標籤(tag)。路徑屬於映像檔而非 Nextcloud 本身,若使用浮動標籤,版本可能會在您不知情下變更。截至 2026 年 8 月,此映像檔目前的穩定標籤為 34.0.3。
services:
nextcloud:
image: lscr.io/linuxserver/nextcloud:34.0.3
container_name: nextcloud
environment:
- PUID=1000
- PGID=1000
- TZ=Etc/UTC
volumes:
- nextcloud_config:/config
- nextcloud_data:/data
ports:
- 443:443
restart: unless-stopped
nextcloud-db:
image: mariadb:11.8
container_name: nextcloud-db
environment:
- MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD}
- MARIADB_DATABASE=nextcloud
- MARIADB_USER=nextcloud
- MARIADB_PASSWORD=${NEXTCLOUD_DB_PASSWORD}
volumes:
- nextcloud_db:/var/lib/mysql
restart: unless-stopped
volumes:
nextcloud_config:
nextcloud_data:
nextcloud_db:這兩組密碼來自於 compose 檔案旁的 .env 檔案,因此不會直接寫入 compose 檔案中。上述解答共涉及三個 volume,其中僅有一個存放使用者檔案。
這些容器路徑源自該特定映像檔的說明文件。不同的 Nextcloud 映像檔其檔案系統配置各異,並將安裝目錄置於各自的網頁根目錄下,因此直接複製論壇文章中的路徑僅是猜測。請從您實際執行的容器中確認真實路徑。
docker inspect nextcloud該輸出的 Mounts 區段會列出所有掛載點,其中 Source 為宿主機端路徑,Destination 為容器端路徑。無論您選擇哪種映像檔,此列表皆能為您的設定提供正確答案。
如何找出 Volume 背後的實際主機路徑?
具名 Volume 由 Docker 管理,因此您無法自行指定路徑,必須透過查詢取得。
docker volume ls
docker volume inspect nextcloud_nextcloud_data名稱至關重要。Docker Compose 會在 Volume 名稱前加上專案名稱(預設為包含 compose 檔案的目錄名稱),因此在檔案中寫為 nextcloud_data 的 Volume,在磁碟上通常會以 nextcloud_nextcloud_data 存在。docker volume ls 可顯示實際名稱。inspect 的輸出結果如下(已刪減):
[
{
"CreatedAt": "2026-08-18T09:12:44Z",
"Driver": "local",
"Mountpoint": "/var/lib/docker/volumes/nextcloud_nextcloud_data/_data",
"Name": "nextcloud_nextcloud_data",
"Scope": "local"
}
]Mountpoint 即為答案。請直接從指令讀取,不要預設路徑,因為它可能會變動。在 rootless Docker 下,整個 Docker 資料根目錄位於執行 daemon 的使用者家目錄內,因此該路徑會從其他位置開始。
使用 Bind mount 則無此問題。在 compose 檔案中寫入 - /srv/nextcloud/data:/data,主機路徑即為您輸入的路徑,docker inspect 會將其回報為 Source。此選擇不僅影響路徑,因為 具名 Volume 與 Bind mount 在擁有權與備份處理上的行為有所不同。
為何資料目錄不等於備份
Nextcloud 手冊列出了備份必須包含的五個項目:設定檔資料夾、自訂應用程式資料夾、資料目錄、佈景主題資料夾以及資料庫。在此映像檔中,設定檔、應用程式與佈景主題資料夾皆位於 /config 下,而資料庫則在各自的容器中運行並擁有獨立的 volume。若僅複製 /data,您只保存了問題中最不重要的一部分。
資料庫至關重要,因為網頁介面並非直接列出目錄內容,而是列出檔案快取中的資料列;這也是為何手冊要求在手動複製檔案至資料目錄後,必須執行掃描的原因。若將 /data 還原至一個空的資料庫,您將得到一堆沒有索引的位元組:沒有使用者、沒有分享連結,檔案清單中空無一物。反之,若將資料庫還原至一個空的 /data,則每一筆資料列都會指向不存在的檔案。
config.php 存放了資料庫憑證與信任網域。它同時也存放了 instance id,這正是資料目錄內應用程式資料夾的名稱。請直接詢問正在執行的實例,不要憑記憶使用任何數值。
docker exec -it nextcloud occ config:system:get datadirectory
docker exec -it nextcloud occ config:system:get instanceid第一行指令會印出此實例實際使用的資料目錄,在此處為 /data。此映像檔在路徑中內建了 occ 包裝器,因此請直接透過 docker exec 執行。請勿複製 Nextcloud 手冊中較長的 sudo 與 php occ 格式,該格式是針對容器外安裝環境所撰寫的。
是什麼佔用了資料磁碟區的空間?
預覽圖與使用者歷史紀錄存放在與檔案相同的磁碟區中,但這兩者都不會顯示在使用者於網頁介面看到的儲存空間統計中。
- 預覽圖是系統產生的縮圖。它們位於資料目錄下的應用程式資料夾中,名稱為
appdata_後接執行個體 ID。 - 刪除的檔案會保留在垃圾桶中。
trashbin_retention_obligation預設值為auto,系統會保留這些檔案 30 天,僅在空間不足時才會將其移除。刪除的檔案仍會計入使用者配額;當配額超標時,系統會忽略保留設定,並持續清理垃圾桶直到配額恢復正常。 - 舊版本檔案也會被保留。
versions_retention_obligation的預設值同樣為auto。Versions 應用程式佔用的空間絕不會超過使用者目前剩餘空間的 50%;當系統進行清理時,會優先刪除最舊的版本,但會保留最近的兩個版本。使用者手動命名的版本則永遠不會被刪除。
在刪除任何資料前,請先進行測量。
docker exec -it nextcloud sh -c 'du -sh /data/*'
docker exec -it nextcloud sh -c 'du -sh /data/appdata_*'第一行指令會針對每個使用者資料夾以及應用程式資料夾各顯示一個數值。如果應用程式資料夾的數值過大,原因即為預覽圖。下方記載的清理指令皆為刻意刪除資料的操作。
docker exec -it nextcloud occ trashbin:cleanup --all-users
docker exec -it nextcloud occ versions:cleanup alice
docker exec -it nextcloud occ preview:cleanuppreview:cleanup 會移除所有已產生的預覽圖。當使用者開啟檔案時,Nextcloud 會重新產生這些預覽圖,因此空間會逐漸回填,且會消耗 CPU 資源。如果磁碟區空間不足只是更廣泛磁碟問題的一部分,舊映像檔與過期的建置快取 通常是另一個原因。
為什麼我複製到主機的檔案沒有出現在 Nextcloud 中?
因為 Nextcloud 是讀取資料庫中的檔案快取,而非直接讀取目錄。您直接複製檔案到磁碟時,資料庫中並無對應的記錄,因此網頁介面無法列出這些檔案。手冊中明確提到了這種情況:將檔案直接複製到資料目錄後,必須執行掃描。
docker exec -it nextcloud occ files:scan --path="/alice/files/Photos"
docker exec -it nextcloud occ files:scan --unscanned -v
docker exec -it nextcloud occ files:scan --all--path 參數也能顯示資料目錄內的配置:每個使用者都有一個以其帳號命名的資料夾,而其中的 files 存放著網頁介面上所見的內容。若您知道檔案存放的位置,請掃描該路徑。--all 會遍歷所有使用者,在大型執行個體上會耗費很長時間。--unscanned 僅處理尚未完全掃描的檔案。-v 會在處理每個檔案時進行輸出,這能讓您區分指令是卡住還是正在運作中。
檔案擁有權決定了掃描是否足夠。若容器使用者無法寫入該檔案,系統在索引後將無法移動它,這會導致檔案列表看起來正常,但從網頁介面進行重新命名或刪除時會失敗。
為什麼設定 PUID 和 PGID 後寫入會失敗?
因為核心比對的是數字,而非名稱。PUID 和 PGID 設定了容器處理程序執行時所使用的數值使用者 ID (uid) 與群組 ID (gid)。主機上的每個檔案也都帶有數值擁有者。當這兩個數字不一致時,寫入就會被拒絕,無論兩端的名稱看起來為何。
docker exec -it nextcloud id abc
sudo ls -ln /var/lib/docker/volumes/nextcloud_nextcloud_data/_dataid abc 會印出容器實際使用的 uid 與 gid,也就是您設定的 PUID 與 PGID。ls -ln 會印出數值擁有者,而 -n 很重要:單純的 ls -l 會透過主機自身的使用者列表轉換這些數字,並顯示一個在容器內部毫無意義的名稱。請比對這兩個數字。
接著請直接測試寫入,不要憑空猜測。
docker exec -u abc -it nextcloud touch /data/writetest使用 Permission denied 指定 /data 進行測試即可確認。請從容器內部修正擁有權,然後再次執行相同的測試。
docker exec -u 0 -it nextcloud chown -R abc:abc /data
docker exec -u abc -it nextcloud touch /data/writetest
docker exec -u abc -it nextcloud rm /data/writetest從內部執行是有原因的。在 rootless Docker 下,容器的使用者 ID 會透過 /etc/subuid 中的從屬範圍進行映射,因此容器內的 uid 1000 在主機上對應的是一個更大的 uid。此時若在主機端執行 chown 1000:1000,會設定一個容器無法使用的擁有者,導致寫入依然失敗。在容器內部執行 chown 會經過與 Nextcloud 處理程序本身相同的映射機制,因此數字會自動對齊。這也是為什麼在開始進行任何其他除錯前,PUID 和 PGID 必須與磁碟上的擁有者相符 的原因。
如何確保備份在還原時確實有效?
請在同一時間點取得資料庫備份與檔案目錄。維護模式(maintenance mode)會停止登入,確保在執行資料庫傾印(dump)與檔案複製期間,不會有新的上傳資料寫入。
docker exec -it nextcloud occ maintenance:mode --on
docker exec nextcloud-db mariadb-dump --single-transaction -u nextcloud -p"$NEXTCLOUD_DB_PASSWORD" nextcloud > nextcloud-sqlbkp.sql
docker run --rm -v nextcloud_nextcloud_data:/data:ro -v "$PWD":/backup alpine:3.22 tar czf /backup/nextcloud-data.tgz -C /data .
docker run --rm -v nextcloud_nextcloud_config:/config:ro -v "$PWD":/backup alpine:3.22 tar czf /backup/nextcloud-config.tgz -C /config .
docker exec -it nextcloud occ maintenance:mode --off請注意傾印指令中缺少了 -t 旗標。TTY 會重寫換行符號,若 SQL 傾印檔經過此處理將會損毀,且該問題通常僅在還原時才會發現。此外,請注意在指令列輸入密碼會顯示於 ps 輸出中,因此建議從 .env 檔案讀取密碼並傳入 shell,而非直接輸入。舊版的資料庫映像檔使用 mysqldump 而非 mariadb-dump,相關說明請參閱手冊。
還原時,請將傾印檔載入至空的資料庫,將兩個封存檔解壓縮至全新的儲存空間,啟動容器,最後關閉維護模式。若檔案目錄與資料庫傾印的時間點不一致,檔案快取與磁碟內容將會衝突,而 occ files:scan --all 僅能修復單一方向的錯誤。它能找出存在但無對應資料列的檔案,但無法找回資料列指向但已遺失的檔案。
請將備份結果存放在伺服器外部。存放在同一台 VPS 內的備份會隨該 VPS 一同損毀,這就是為什麼 使用 restic 備份至外部儲存庫 是此流程的必要環節,也是為什麼 供應商快照與備份是不同的工具。若您仍在建構服務堆疊,在 VPS 上完整安裝 Nextcloud 一文涵蓋了本指南未提及的反向代理與 TLS (transport layer security) 憑證設定。
FAQ
Docker 容器中的 Nextcloud 資料目錄在哪裡?
若使用 linuxserver.io 映像檔,容器內的路徑為 /data,而使用 config.php 安裝時則位於 /config。上述均為容器內路徑。若要查詢宿主機路徑,請執行 docker inspect nextcloud 並讀取 Mounts 區段中的 Source 值,或對該 volume 執行 docker volume inspect 並讀取 Mountpoint。其他 Nextcloud 映像檔可能使用不同的容器路徑,請查閱您所鎖定標籤(tag)的說明文件,並透過 docker exec -it nextcloud occ config:system:get datadirectory 確認。
為什麼我複製到 volume 的檔案在 Nextcloud 中看不到?
Nextcloud 是從資料庫的檔案快取(file cache)讀取列表,而非直接讀取目錄,因此未經由 Nextcloud 上傳的檔案因資料庫中沒有記錄而無法顯示。請針對單一資料夾執行 docker exec -it nextcloud occ files:scan --path="/alice/files/Photos",或針對所有使用者執行 occ files:scan --all。若檔案出現但無法移動或刪除,原因通常是擁有權問題:容器內的使用者必須具備寫入權限。
備份資料 volume 足以還原 Nextcloud 嗎?
不足夠。資料 volume 僅儲存檔案內容。資料庫儲存了檔案索引、使用者與分享資訊,而 config.php 則儲存了資料庫憑證與實例 ID(instance id)。完整的還原作業需要資料夾、設定檔資料夾、資料庫,以及您所使用的自訂應用程式與佈景主題資料夾。請確保所有備份均來自同一時間點,否則較新的資料庫會指向不存在的檔案。
為什麼我的資料 volume 大小遠大於使用者看到的檔案總和?
預覽圖、已刪除檔案與舊版本皆存放在同一個 volume 中,且不會計入使用者看到的空間統計。請使用 docker exec -it nextcloud sh -c 'du -sh /data/*' 進行測量。資源回收桶預設保留已刪除檔案 30 天,僅在空間不足時才會提前清除;而 Versions 應用程式最多可佔用使用者目前剩餘空間的一半。您可透過 occ trashbin:cleanup --all-users、occ versions:cleanup alice 與 occ preview:cleanup 進行清理,但請注意,隨著使用者開啟檔案,預覽圖空間會再次增長。
我可以將 Nextcloud 資料目錄移至其他磁碟嗎?
請將新位置掛載至相同的容器路徑,而非修改 Nextcloud 認知的路徑。請停止容器,使用保留擁有權的方式(cp -a 或 rsync -aAX)將舊內容複製到新磁碟,在 compose 檔案中將 volume 或 bind mount 指向新位置,最後重新啟動容器。由於 Nextcloud 看到的仍是 /data,因此無須修改資料庫中的任何記錄。最後請透過 docker exec -it nextcloud occ config:system:get datadirectory 與一次測試上傳來驗證。