Nextcloud 는 설치 직후에는 잘 돌다가 사진이 수만 장 쌓이면서 느려지는 일이 잦다. 병목은 대체로 세 곳이다. 데이터 디렉터리 권한, 미리보기(썸네일) 생성, 그리고 파일 잠금과 캐시다. 이 문서는 설치 단계에서 걸리는 권한 문제와 운영 단계의 튜닝을 함께 다룬다.
설치 화면에서 data 디렉터리를 만들 수 없다는 오류가 나오면 웹 서버 프로세스가 그 경로에 쓸 수 없다는 뜻이다. 컨테이너로 올린 경우가 특히 헷갈리는데, 호스트의 디렉터리 소유자와 컨테이너 안 사용자의 UID 가 일치해야 한다.
공식 Nextcloud 이미지는 www-data 로 돌고 UID 와 GID 는 33 이다.
docker exec -it nextcloud id www-data
호스트 쪽 디렉터리를 그 UID 에 맞춘다.
mkdir -p /srv/nextcloud/data
chown -R 33:33 /srv/nextcloud/data
chmod -R 750 /srv/nextcloud/data
베어메탈 설치라면 배포판에 따라 계정 이름이 다르다. 실제로 도는 프로세스의 계정을 확인한다.
ps -eo user,comm | grep -E 'httpd|apache2|nginx|php-fpm' | sort -u
RHEL 계열 httpd 는 apache, Debian 계열은 www-data, nginx 는 nginx 인 경우가 많다. SELinux 가 켜져 있으면 소유자를 맞춰도 막히므로 컨텍스트도 함께 본다.
ls -Zd /srv/nextcloud/data
semanage fcontext -a -t httpd_sys_rw_content_t "/srv/nextcloud/data(/.*)?"
restorecon -Rv /srv/nextcloud/data
사진과 영상은 금방 수백 MB 를 넘긴다. PHP · 웹 서버 · 리버스 프록시 셋 중 가장 작은 값이 실제 상한이 되므로 같이 올린다.
upload_max_filesize = 16G
post_max_size = 16G
memory_limit = 512M
max_execution_time = 3600
max_input_time = 3600
nginx 를 앞에 두면 client_max_body_size 를 같은 값으로 두고, 업로드가 오래 걸리므로 proxy_read_timeout 도 늘린다. memory_limit 은 업로드 크기와 같게 둘 필요가 없다. Nextcloud 는 청크 업로드를 쓰므로 512M 이면 대개 충분하다.
사진 갤러리가 느린 가장 큰 이유는 화면을 열 때마다 미리보기를 즉석에서 만들기 때문이다. Preview Generator 앱을 넣고 미리 만들어 두면 체감이 크게 달라진다.
occ app:install previewgenerator
occ preview:generate-all
처음 한 번은 오래 걸린다. 이후에는 새로 올라온 것만 주기적으로 만든다.
occ preview:pre-generate
config.php 에서 만들 크기를 제한해 두지 않으면 원본 해상도대로 여러 벌을 만들어 디스크를 잡아먹는다.
'enable_previews' => true,
'preview_max_x' => 2048,
'preview_max_y' => 2048,
'preview_max_memory' => 512,
HEIC 는 아이폰 기본 형식이다. 미리보기 제공자 목록(enabledPreviewProviders)에 HEIC 를 넣지 않으면 썸네일이 비어 보인다. 서버의 imagick 이 HEIC 를 지원해야 한다.
Redis 를 붙이면 메타데이터 조회와 파일 잠금이 DB 를 거치지 않는다. 동기화 클라이언트가 여럿이면 효과가 크다. 로컬 캐시는 APCu, 분산 캐시와 잠금은 Redis 로 두는 것이 공식 문서가 권하는 조합이다. 잠금만 Redis 로 옮겨도 파일이 잠겨 있다는 오류가 줄어든다.
'memcache.local' => '\OC\Memcache\APCu',
'memcache.distributed' => '\OC\Memcache\Redis',
'memcache.locking' => '\OC\Memcache\Redis',
'filelocking.enabled' => true,
'redis' => [
'host' => 'redis',
'port' => 6379,
],
파일 수가 늘면 인덱스가 없는 조회가 느려진다. 업그레이드 뒤에는 빠진 인덱스를 채운다.
occ db:add-missing-indices
occ db:add-missing-columns
occ db:add-missing-primary-keys
MariaDB 는 버퍼 풀을 데이터 크기에 맞춰 올린다.
innodb_buffer_pool_size = 1G
innodb_file_per_table = 1
파일을 서버 파일 시스템에 직접 복사하면 Nextcloud 는 그 존재를 모른다. 스캔을 돌려야 목록에 나타난다.
occ files:scan --all
occ files:cleanup
files:scan --all 은 파일 수에 비례해 오래 걸린다. 사용자 한 명이나 한 경로만 필요하면 --path 로 범위를 좁힌다.
자동 업로드는 Wi-Fi 연결 시에만, 충전 중에만으로 제한하면 배터리와 데이터 소모가 줄어든다. 이미 올린 파일을 건너뛰는 옵션을 켜 두면 재설치 뒤 중복 업로드를 막을 수 있다.
occ 는 반드시 웹 서버와 같은 계정으로 돌린다. root 로 돌리면 새로 만든 파일의 소유자가 어긋나 나중에 쓰기 오류가 난다. 컨테이너에서는 docker exec -u www-data 를 쓴다.data/appdata_*/preview 의 크기를 주기적으로 본다.