SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-21

Docker Nextcloud 데이터 저장 경로 확인 방법

Docker 컨테이너 내 Nextcloud 데이터 디렉토리와 호스트 볼륨 매핑 경로를 찾는 방법을 설명합니다. 사용자 파일 외에 백업 시 반드시 포함해야 할 설정 파일과 데이터베이스 위치를 확인하여 데이터 유실을 방지하는 구체적인 가이드를 제공합니다.

Docker에서 Nextcloud가 파일을 저장하는 위치

Docker에서 실행 중인 Nextcloud는 컨테이너 내부의 데이터 디렉터리에 파일을 저장하며, 서버상의 실제 위치는 연결된 볼륨이나 바인드 마운트 경로에 따라 결정됩니다. linuxserver.io 이미지를 사용하는 경우, lscr.io/linuxserver/nextcloud를 통해 사용자 파일은 /data에 위치하며, config.php를 포함한 Nextcloud 설치 파일은 /config에 위치합니다. 이 두 경로는 모두 컨테이너 내부 경로입니다. 특정 명령어를 사용하면 이 경로들에 대응하는 호스트 경로를 확인할 수 있으며, 이 가이드의 나머지 부분에서는 데이터 디렉터리에 포함되지 않는 나머지 요소들에 대해 다룹니다.

이미지 태그를 고정하십시오. 경로는 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 파일 본문에는 노출되지 않습니다. 이 답변에는 세 개의 볼륨이 포함되어 있으며, 그중 하나만이 사용자 파일을 보관합니다.

위의 컨테이너 경로는 해당 이미지의 문서에 명시된 내용입니다. 다른 Nextcloud 이미지는 파일 시스템 구조가 다를 수 있으며 설치 파일을 자체 웹 루트 아래에 보관할 수도 있으므로, 포럼 게시물에서 복사한 경로는 정확하지 않을 수 있습니다. 실행 중인 컨테이너에서 직접 확인하는 것이 가장 정확합니다.

docker inspect nextcloud

해당 출력의 Mounts 섹션에는 모든 마운트 정보가 나열되며, 호스트 측의 Source와 컨테이너 측의 Destination가 표시됩니다. 이 목록을 확인하면 어떤 이미지를 선택했든 상관없이 현재 설정에 대한 답을 얻을 수 있습니다.

볼륨 뒤에 숨겨진 실제 호스트 경로를 어떻게 찾습니까?

네임드 볼륨은 Docker가 관리하므로 사용자가 경로를 직접 지정하지 않습니다. Docker에 경로를 요청해야 합니다.

docker volume ls
docker volume inspect nextcloud_nextcloud_data

이름이 중요합니다. Docker Compose는 볼륨 이름 앞에 프로젝트 이름을 접두사로 붙입니다. 프로젝트 이름은 기본적으로 compose 파일이 위치한 디렉터리 이름이므로, 파일에 nextcloud_data로 작성된 볼륨은 일반적으로 디스크상에서 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 데이터 루트가 데몬을 실행하는 사용자의 홈 디렉터리 내부에 위치하므로, 해당 경로는 다른 곳에서 시작됩니다.

바인드 마운트를 사용하면 이 문제는 사라집니다. compose 파일에 - /srv/nextcloud/data:/data를 작성하면 호스트 경로는 사용자가 입력한 경로가 되며, docker inspect은 이를 Source로 보고합니다. 이 선택은 단순히 경로 이상의 차이를 만듭니다. 네임드 볼륨과 바인드 마운트는 소유권 및 백업 처리 방식에서 서로 다르게 동작하기 때문입니다.

데이터 디렉터리가 백업이 아닌 이유

Nextcloud 매뉴얼은 백업에 포함해야 할 5가지 항목으로 config 폴더, custom apps 폴더, data 폴더, theme 폴더, 그리고 데이터베이스를 명시합니다. 이 이미지 환경에서 config, apps, theme 폴더는 모두 /config 하위에 위치하며, 데이터베이스는 별도의 볼륨을 사용하는 독립된 컨테이너에서 실행됩니다. /data만 따로 복사하는 것은 문제의 핵심에서 가장 중요하지 않은 부분만 저장하는 셈입니다.

데이터베이스가 중요한 이유는 웹 인터페이스가 디렉터리 목록을 직접 나열하지 않기 때문입니다. 웹 인터페이스는 파일 캐시의 행을 읽어 표시하므로, 매뉴얼에서 data 디렉터리에 파일을 수동으로 복사한 뒤 스캔을 실행하라고 안내하는 것입니다. /data을 빈 데이터베이스와 함께 복원하면 인덱스가 없는 데이터 덩어리만 남게 됩니다. 즉, 사용자 정보, 공유 설정, 파일 목록 등 아무것도 나타나지 않습니다. 반대로 빈 /data과 함께 데이터베이스를 복원하면 모든 행이 존재하지 않는 파일을 가리키게 됩니다.

config.php에는 데이터베이스 자격 증명과 신뢰할 수 있는 도메인 정보가 들어 있습니다. 또한 인스턴스 ID도 포함되어 있는데, 이는 data 디렉터리 내부에 있는 앱 데이터 폴더의 이름이기도 합니다. 메모리에 의존하지 말고 실행 중인 인스턴스에 직접 질의하여 확인하십시오.

docker exec -it nextcloud occ config:system:get datadirectory
docker exec -it nextcloud occ config:system:get instanceid

첫 번째 명령은 현재 인스턴스가 실제로 사용하는 데이터 디렉터리를 출력하며, 여기서는 /data이 해당합니다. 이 이미지는 경로상에 occ 래퍼를 포함하고 있으므로 docker exec를 통해 직접 실행하십시오. 컨테이너 외부 설치를 기준으로 작성된 Nextcloud 매뉴얼의 긴 sudophp occ 형식은 사용하지 마십시오.

데이터 볼륨을 조용히 채우고 있는 것은 무엇입니까?

미리보기(preview)와 사용자별 기록은 파일과 동일한 볼륨에 저장되며, 웹 인터페이스에서 사용자가 확인하는 저장 공간 수치에는 포함되지 않습니다.

  • 미리보기는 생성된 썸네일입니다. 이 파일들은 데이터 디렉터리 내의 앱 데이터 폴더에 저장되며, appdata_ 뒤에 인스턴스 ID가 붙는 이름으로 생성됩니다.
  • 삭제된 파일은 휴지통에 남습니다. trashbin_retention_obligation의 기본값은 auto이며, 이 설정은 파일을 30일 동안 보관하고 그 이후에는 공간이 필요할 때만 삭제합니다. 삭제된 파일도 사용자 할당량(quota)에 포함되며, 할당량을 초과하면 보관 설정은 무시되고 할당량 범위 내로 들어올 때까지 휴지통이 정리됩니다.
  • 이전 버전 파일도 마찬가지로 유지됩니다. versions_retention_obligation의 기본값 역시 auto입니다. Versions 앱은 사용자가 현재 확보한 여유 공간의 50% 이상을 사용하지 않으며, 정리 시에는 가장 최근 버전 2개를 제외하고 가장 오래된 버전부터 삭제합니다. 사용자가 직접 이름을 지정한 버전은 절대 삭제되지 않습니다.

무언가를 삭제하기 전에 먼저 측정하십시오.

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:cleanup

preview: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/_data

id 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에 정의된 하위 범위(subordinate range)를 통해 매핑되므로, 컨테이너 내부의 uid 1000은 호스트에서는 훨씬 더 큰 uid에 해당합니다. 따라서 호스트 측에서 chown 1000:1000을 실행하면 컨테이너가 사용할 수 없는 소유자가 설정되어 쓰기 작업이 여전히 실패하게 됩니다. 컨테이너 내부에서 chown을 실행하면 Nextcloud 프로세스가 사용하는 것과 동일한 매핑 과정을 거치므로, 숫자가 구조적으로 일치하게 됩니다. 이것이 바로 다른 문제를 디버깅하기 전에 PUID와 PGID가 디스크상의 소유자와 일치해야 하는 이유입니다.

복구 작업이 실제로 성공하려면 어떻게 백업해야 합니까?

데이터베이스와 폴더를 동일한 시점에 백업하십시오. 유지보수 모드는 로그인을 차단하므로 덤프와 복사 작업 사이에 업로드가 발생하지 않습니다.

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 파일에서 셸로 읽어오십시오. 구형 데이터베이스 이미지는 mariadb-dump 대신 mysqldump를 사용하며, 매뉴얼에는 두 방식이 모두 기재되어 있습니다.

복구하려면 빈 데이터베이스에 덤프를 로드하고, 두 아카이브를 새로운 볼륨에 압축 해제한 뒤 컨테이너를 시작하고, 마지막으로 유지보수 모드를 끄십시오. 폴더와 덤프의 시점이 다르면 파일 캐시와 디스크 상태가 일치하지 않게 되며, occ files:scan --all은 한쪽 방향으로만 복구가 가능합니다. 이 도구는 데이터베이스 행은 없는데 파일만 존재하는 경우는 찾을 수 있지만, 데이터베이스 행이 가리키는 파일이 누락된 경우에는 복구할 수 없습니다.

백업 결과물은 서버 외부에 보관하십시오. 동일한 VPS 내부에 저장된 사본은 해당 VPS가 손실될 때 함께 사라집니다. 이것이 바로 외부 저장소로 restic 백업을 이 과정에 포함해야 하는 이유이며, 제공업체의 스냅샷이 백업과는 다른 도구인 이유입니다. 스택을 구축하는 중이라면, 이 가이드에서 다루지 않는 리버스 프록시와 TLS(전송 계층 보안) 인증서 설정은 VPS에 Nextcloud 전체 설치 문서를 참조하십시오.

FAQ

Docker 컨테이너에서 Nextcloud 데이터 디렉터리는 어디에 있습니까?

linuxserver.io 이미지를 사용하는 경우 컨테이너 내부는 /data이며, config.php를 통한 설치 시 경로는 /config입니다. 이는 컨테이너 내부 경로입니다. 호스트 경로를 확인하려면 docker inspect nextcloud을 실행하여 Mounts 섹션의 Source 값을 읽거나, 볼륨에 대해 docker volume inspect을 실행하여 Mountpoint을 확인하십시오. 다른 Nextcloud 이미지는 컨테이너 내부 경로가 다를 수 있으므로 사용 중인 태그의 문서를 확인하고 docker exec -it nextcloud occ config:system:get datadirectory로 직접 확인하십시오.

볼륨에 복사한 파일이 왜 Nextcloud에 나타나지 않습니까?

Nextcloud는 디렉터리를 직접 읽는 대신 데이터베이스의 파일 캐시 행을 나열합니다. 따라서 Nextcloud를 거치지 않고 추가된 파일은 데이터베이스에 행이 생성되지 않아 보이지 않습니다. 특정 폴더에 대해서는 docker exec -it nextcloud occ files:scan --path="/alice/files/Photos"을, 모든 사용자에 대해서는 occ files:scan --all를 실행하십시오. 파일이 나타나지만 이동이나 삭제가 되지 않는다면 소유권 문제입니다. 컨테이너 사용자가 해당 파일에 대한 쓰기 권한을 가지고 있어야 합니다.

데이터 볼륨만 복사하면 Nextcloud를 복구할 수 있습니까?

아니요. 데이터 볼륨에는 파일 내용만 저장됩니다. 데이터베이스에는 파일 인덱스, 사용자 정보, 공유 정보가 저장되며, config.php에는 데이터베이스 자격 증명과 인스턴스 ID가 저장됩니다. 정상적인 복구를 위해서는 데이터 폴더, 설정 폴더, 데이터베이스, 그리고 사용하는 경우 커스텀 앱 및 테마 폴더가 모두 필요합니다. 데이터베이스가 파일보다 최신 상태이면 존재하지 않는 파일을 가리키게 되므로, 모든 항목을 동일한 시점에 백업해야 합니다.

데이터 볼륨이 사용자가 보는 파일 용량보다 훨씬 큰 이유는 무엇입니까?

미리보기 이미지, 삭제된 파일, 이전 버전 파일이 모두 같은 볼륨에 저장되며, 이들은 사용자가 확인하는 용량에 포함되지 않습니다. 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 파일에서 볼륨이나 바인드 마운트 경로를 새 위치로 수정하고 컨테이너를 다시 시작하십시오. Nextcloud는 여전히 /data를 바라보고 있으므로 데이터베이스의 행을 수정할 필요가 없습니다. docker exec -it nextcloud occ config:system:get datadirectory과 테스트 업로드를 통해 확인하십시오.