SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor

Immich 셀프 호스팅 RAM과 안전한 업그레이드

Immich 운영에 필요한 RAM은 실제로 얼마일까요? 6 GB 기준과 4 GB+스왑 하한, HTTPS 뒤 2283 포트, exit 137 메모리 종료, pgvecto.rs에서 Immich v3가 시작되지 않는 문제와 복구 절차를 설명합니다.

구축할 서비스

Immich는 Google Photos를 대체할 수 있는 자가 호스팅 사진 및 동영상 백업 서비스입니다. 휴대폰 앱을 통해 카메라 롤을 백업하고, 타임라인, 앨범, 얼굴 인식 및 머신러닝 기반 검색 기능을 제공합니다. 별도의 태그 작업 없이도 "해변"이나 특정 인물을 검색할 수 있습니다. 직접 소유한 VPS에서 실행하므로 원본 파일은 본인의 디스크에 저장되며, 광고 수익을 위해 데이터를 스캔하는 주체도 없습니다. 다른 대안과 비교 중이라면 PhotoPrism과 Immich 비교 문서를 통해 최소 RAM 요구 사항, 모바일 앱 기능, 백업 명령어를 확인하십시오.

설치는 프로젝트에서 제공하는 Docker Compose 파일을 사용하여 4개의 컨테이너를 올리는 방식으로 진행되며, 이 과정은 10분 정도 소요됩니다. 이 가이드의 나머지 부분은 실제 운영 시 발생할 수 있는 문제들을 다룹니다. 머신러닝 컨테이너는 저사양 서버에서 많은 메모리를 점유하며, 원본 파일은 디스크 용량을 빠르게 소모합니다. 모바일 앱은 정확한 서버 URL을 필요로 하며, 외부 네트워크로 노출하기 전에 반드시 HTTPS를 적용해야 합니다. 또한 Immich는 잦은 업데이트로 인해 호환성이 깨지는 변경 사항이 발생할 수 있으므로, 부주의한 docker compose pull 실행은 서버를 구동 불능 상태로 만들 수 있습니다. 이 네 가지 사항을 주의 깊게 관리하면 Immich는 매우 안정적으로 동작합니다. 이를 간과하면 주말 내내 복구 작업에 매달려야 할 수도 있습니다.

사전 요구 사항 및 주의 사항

  • RAM: 공식 문서에서는 최소 6 GB, 권장 8 GB를 명시하지만, 4 GB와 스왑(swap) 조합을 절대적인 하한선으로 간주하십시오. immich-server 및 Postgres 컨테이너는 리소스를 적게 사용합니다. immich-machine-learning 컨테이너는 메모리 점유율이 높으며, 검색 인덱스를 생성하기 위해 CLIP 및 얼굴 인식 모델을 RAM에 로드합니다. 2 GB 환경에서는 커널이 해당 프로세스를 강제 종료(OOM kill)합니다. 4 GB를 사용하더라도 스왑을 추가하십시오.
  • 디스크: 전체 라이브러리 용량보다 넉넉하게 할당하십시오. 원본 파일이 그대로 복사되며, Immich가 생성하는 썸네일과 미리보기 이미지로 인해 원본 대비 약 10–20%의 추가 공간이 필요합니다. 200 GB 규모의 사진 컬렉션이라면 300 GB 볼륨을 권장합니다. Postgres가 차지하는 용량은 상대적으로 작습니다.
  • CPU: 최신 KVM VPS라면 충분하지만, CPU 기반의 머신러닝은 속도가 느립니다. 대량의 사진을 가져와 스마트 검색 인덱싱을 수행하면 백그라운드에서 몇 시간 동안 작업이 진행될 수 있습니다. 이는 정상적인 동작이며, 반드시 GPU가 필요한 것은 아닙니다.
  • VPS를 가리키는 도메인 이름. 모바일 앱은 HTTPS 엔드포인트를 강력히 요구하며, 앞단에 리버스 프록시를 두는 것이 좋습니다. 이는 Docker, TLS, 백업을 사용하는 자가 호스팅 Nextcloud 인스턴스와 동일한 구성 방식이며, Immich는 해당 파일 서버에 대응하는 사진 관리 서비스입니다.
  • Docker 및 Compose 플러그인 설치. Docker Compose 기초 가이드에서 다룬 내용과 동일하게, Docker 공식 apt 저장소에서 제공하는 Docker Engine과 Compose v2 플러그인을 설치하십시오.

1단계: 다른 작업에 앞서 스왑 추가하기

소규모 VPS에서 Immich가 실패하는 가장 흔한 원인은 ML 컨테이너가 OOM-killed 되는 것입니다. 커널이 여유를 가질 수 있도록 먼저 공간을 확보하십시오.

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -h

이제 free -h를 실행하면 4.0Gi 크기의 Swap: 항목이 표시되어야 합니다. 이것이 ML의 속도를 높여주지는 않으며 보장된 성능이라기보다는 완충 장치에 가깝지만, 4 GB 메모리를 가진 장비에서 인덱싱 도중 컨테이너가 종료될 가능성을 크게 낮춰줍니다.

2단계: 공식 compose 및 env 파일 가져오기 (복사본 대신 원본 사용)

Immich는 배포 파일 내부에 서비스 버전과 데이터베이스 이미지를 고정(pin)합니다. 블로그(본 문서 포함)에 있는 compose 파일을 복사하여 진실의 원천으로 삼지 마십시오. 릴리스 에셋을 직접 다운로드하십시오:

sudo mkdir -p /opt/immich && cd /opt/immich
sudo wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
sudo wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

이 파일들은 태그가 지정된 릴리스에서 제공되므로 이미지 참조가 일치합니다. compose 파일은 4개의 서비스를 정의하며, 설정을 변경하기 전에 각 서비스의 역할을 이해하는 것이 좋습니다:

  • immich-server (ghcr.io/immich-app/immich-server, 컨테이너 immich_server): API 및 웹 UI이며, 2283 포트에서 대기합니다. 업로드된 파일을 /data 경로에 마운트합니다.
  • immich-machine-learning (ghcr.io/immich-app/immich-machine-learning, 컨테이너 immich_machine_learning): CLIP 검색 및 얼굴 인식 기능을 수행합니다. 다운로드한 모델을 model-cache 볼륨에 캐싱합니다. 이 서비스는 메모리 사용량이 많습니다.
  • database (컨테이너 immich_postgres): VectorChord 벡터 확장이 포함된 Postgres이며, 유사도 검색 기능을 제공합니다. 이미지 태그는 compose 파일 내에 다이제스트로 고정되어 있습니다(예: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:...). 이전 설정에서는 pgvecto.rs을 사용했으나, Immich v3.0부터 지원이 중단되었습니다. 따라서 현재 설치하는 모든 환경은 VectorChord를 사용합니다. 이 태그를 직접 수정하지 마십시오.
  • redis (컨테이너 immich_redis): 작업 큐를 위한 Valkey/Redis 인스턴스입니다.

3단계: 사진과 데이터베이스가 위치할 .env 구성하기

.env을 열고 다음 네 가지 항목을 설정합니다. 표시된 줄 아래의 모든 내용은 그대로 유지하십시오.

# Where original uploads are stored on the host
UPLOAD_LOCATION=/opt/immich/library

# Where the Postgres data lives. NEVER put this on an NFS/network share.
DB_DATA_LOCATION=/opt/immich/postgres

# "v3" is a floating tag that tracks the latest v3.x. Pin a full tag like
# v3.0.2 instead; then you upgrade on purpose, not by surprise.
IMMICH_VERSION=v3.0.2

# Change this to a long random string. Letters and digits only.
DB_PASSWORD=REPLACE_WITH_A_LONG_RANDOM_STRING

# Set your timezone so timestamps and "on this day" line up
TZ=Europe/London

###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich

문제를 방지하기 위한 두 가지 규칙이 있습니다. UPLOAD_LOCATION는 대용량 디스크를 가리켜야 합니다. 나중에 데이터 볼륨을 추가할 계획이라면 처음부터 해당 마운트 경로로 설정하십시오. 나중에 옮기려면 썸네일 이동과 자산 경로 업데이트가 필요하기 때문입니다. 또한 DB_DATA_LOCATION은 반드시 로컬 디스크에 있어야 합니다. NFS나 SMB 공유 드라이브에서 Postgres를 실행하면 데이터가 손상되며, 이는 문서에도 명시되어 있습니다. DB_PASSWORD에 영문자와 숫자만 사용하면 연결 문자열 이스케이프와 관련된 버그를 방지할 수 있습니다.

4단계: 첫 실행 및 관리자 계정 생성

cd /opt/immich
sudo docker compose up -d
sudo docker compose ps

정상적으로 실행되면 4개의 컨테이너가 모두 running 상태가 되며, 최종적으로는 healthy 상태가 됩니다.

NAME                      STATUS
immich_machine_learning   Up (healthy)
immich_postgres           Up (healthy)
immich_redis              Up (healthy)
immich_server             Up (healthy)

첫 번째 up 실행 시 수 기가바이트의 이미지를 내려받으므로 충분한 시간을 기다려야 합니다. sudo docker compose logs -f immich-server 명령으로 진행 상황을 확인하십시오. 서버가 준비되면 포트 2283에서 대기 중이라는 로그가 출력됩니다. 이제 브라우저에서 http://YOUR_SERVER_IP:2283에 접속하십시오. 처음 접속하면 Getting Started 마법사가 나타나며, 여기서 생성하는 첫 번째 계정이 관리자 계정이 됩니다. 강력한 암호를 설정하십시오. 이 계정은 서버 설정, 사용자 관리, 그리고 추후 필요한 ML 구성을 관리하는 권한을 가집니다.

5단계: 모바일 앱 및 백그라운드 백업

App Store나 Play Store에서 Immich를 설치합니다. 로그인 화면에서 Server Endpoint URL을 입력하라는 메시지가 나타납니다. 스키마를 포함한 전체 URL을 입력하십시오(예: https://photos.example.com). 앱이 자동으로 /api를 덧붙입니다. 방금 생성한 계정으로 로그인한 뒤, 앱의 Backup 화면을 열어 보호할 앨범(보통 Camera 및 Screenshots)을 선택하고 Background backup을 활성화합니다. iOS의 백그라운드 백업은 운영체제에 의해 제한됩니다. 포그라운드 업로드는 항상 실행되지만, 백그라운드 업로드는 운영체제가 허용할 때만 수행됩니다.

이 단계에서 막히는 경우가 많으므로, 앱과 씨름하기 전에 6단계를 먼저 읽어보시기 바랍니다.

단계 6: 리버스 프록시를 통한 HTTPS 설정 및 전체 URL 규칙

모바일 앱은 홈 네트워크를 벗어나면 반드시 HTTPS 연결을 요구합니다. 2283 포트 앞에 리버스 프록시를 배치하고 해당 지점에서 TLS를 종료하십시오. 이미 여러 컨테이너를 운영 중이라면 여러 Docker 앱을 위한 자동 TLS 설정이 포함된 Traefik이 가장 깔끔한 선택입니다. 라벨 블록 하나로 photos.example.com을 immich-server 컨테이너로 라우팅하고 인증서까지 자동으로 발급받을 수 있습니다. nginx를 선호한다면 Certbot과 nginx를 이용한 Let's Encrypt 가이드를 통해 인증서를 획득하고 proxy_pass http://127.0.0.1:2283; 블록을 구성하십시오. 프록시가 준비되면 새로운 서비스를 추가하는 것은 대부분 새로운 서브도메인을 설정하는 작업으로 끝납니다. Jellyfin을 위한 90년대 비디오 가게 스타일 스킨인 Halcyon과 같은 미디어 프론트엔드가 Immich와 같은 서버에서 나란히 운영되는 방식이 바로 이것입니다. Codex와 Claude Code를 하나의 API 뒤에 배치하는 자체 호스팅 HarnessRouter도 마찬가지입니다. 이 서비스는 의도적으로 루프백 주소에 바인딩되며 프록시가 TLS를 종료해야만 외부에서 접근할 수 있으므로, 서브도메인을 연결하기 전에 기본 로그인 정보를 변경하십시오. 하지만 모든 컨테이너에 공개 호스트네임이 필요한 것은 아닙니다. 자체 호스팅 open-kritt 보안 스캐너와 같은 관리자 전용 도구는 프록시에서 제외하고, UI를 열어야 하는 드문 경우에만 SSH 터널을 통해 접근하는 것이 더 안전합니다. HTTP를 사용하지 않는 서비스는 프록시를 거치지 않습니다. 자체 호스팅 RustDesk 릴레이 서버가 대표적인 예로, 이 서비스는 여러 개의 원시 TCP 및 UDP 포트에서 대기하므로 서브도메인보다는 방화벽 규칙 설정이 필요합니다. Immich 운영 시 한 가지 프록시 설정이 중요합니다. 휴대폰 영상은 용량이 크므로 업로드 제한을 높여야 합니다. nginx의 경우 서버 블록 내에 client_max_body_size 50000M;을 설정하십시오. 기본값인 1 MB를 그대로 두면 영상 업로드 시 413 Request Entity Too Large 오류가 발생합니다. 프록시가 Let's Encrypt의 HTTP-01 챌린지 응답도 처리한다면, /.well-known/immich 경로가 챌린지 핸들러가 아닌 Immich로 라우팅되도록 설정해야 합니다.

앱이 강제하는 규칙은 다음과 같습니다. 엔드포인트는 사용자가 입력한 URL과 정확히 일치해야 접근 가능합니다. 앱은 일반 http://YOUR_SERVER_IP:2283 주소(앱 자체 로그인 힌트는 http://your-server-ip:port입니다)를 허용하지만, 인터넷을 거치는 모든 연결은 HTTPS여야 합니다. 잘못된 스킴을 사용하거나 포트 번호를 생략한 채 IP로 직접 접속하면 "앱이 서버에 연결할 수 없습니다"라는 오류가 발생하며, 이에 대한 내용은 아래 실패 사례에서 다룹니다.

7단계: 외부 라이브러리와 업로드, 기존 사진 트리 가져오기

Immich에 사진을 추가하는 방법은 두 가지가 있으며, 이 둘은 서로 다릅니다.

  • 업로드(Uploads)는 Immich가 소유하는 에셋입니다. 앱이나 웹 업로더가 파일을 UPLOAD_LOCATION으로 복사합니다. Immich는 이 파일들의 이름을 변경하거나 이동, 삭제할 수 있습니다.
  • 외부 라이브러리(External libraries)는 서버의 특정 폴더, 예전 Pictures 트리, NAS 익스포트 등에 이미 존재하는 파일을 읽기 전용으로 가져오는 방식입니다. Immich는 해당 위치에서 파일을 인덱싱하여 타임라인에 표시하지만, 원본 파일을 수정하거나 삭제하지 않습니다.

기존 사진 트리를 가져오려면 해당 경로를 서버 컨테이너에 읽기 전용으로 마운트하십시오. immich-server: 아래의 docker-compose.yml를 편집하여 볼륨을 추가합니다.

  immich-server:
    volumes:
      - ${UPLOAD_LOCATION}:/data
      - /etc/localtime:/etc/localtime:ro
      - /srv/photos:/mnt/media/photos:ro

:ro는 Immich가 원본 파일에 절대 접근할 수 없음을 보장합니다. sudo docker compose up -d를 사용하여 컨테이너를 다시 생성한 다음, 웹 UI에서 아바타 → 관리(Administration) → 외부 라이브러리(External Libraries) → 라이브러리 생성(Create Library)으로 이동합니다. 소유할 사용자를 선택하고 폴더 아래의 추가(Add)를 클릭한 뒤, 호스트 경로인 /srv/photos이 아닌 컨테이너 경로인 /mnt/media/photos을 입력하십시오. 스캔(Scan)을 클릭합니다. 컨테이너 경로 대신 호스트 경로를 사용하는 것은 외부 라이브러리 설정 시 가장 흔히 발생하는 실수입니다. 이 경우 스캔 결과가 아무것도 나오지 않으며 에셋이 0개로 보고됩니다.

8단계: Immich가 요구하는 업그레이드 원칙

이 단계는 Immich를 안정적으로 운영하는 핵심입니다. Immich는 릴리스 주기가 빠르며, 이전 버전으로의 패치 백포트나 다운그레이드를 지원하지 않습니다. 유동적인 v3 태그는 공식적으로 지원하는 릴리스 추적 방식이며, Immich는 주요 버전에서만 파괴적인 변경 사항을 적용하려 노력합니다. 하지만 이미지를 pull하는 순간 사용자가 릴리스 노트를 읽었는지와 관계없이 업그레이드가 진행되며, 계획에 없던 업그레이드는 되돌릴 수 없습니다. 이러한 '버전 고정 후 릴리스 노트 확인' 습관은 서버의 모든 장기 실행 컨테이너에 적용하는 것이 좋습니다. 이것이 바로 KiroCrew 에이전트가 특정 버전 태그에 고정되는 이유이며, 재시작 시 임의로 버전이 변경되지 않도록 방지합니다. 준수해야 할 원칙은 다음과 같습니다.

  1. 버전을 고정하십시오. IMMICH_VERSION를 항상 최신 v3.x를 가져오는 유동적인 v3 대신, v3.0.2과 같은 구체적인 태그로 설정하십시오.
  2. 업그레이드 전에는 반드시 릴리스 노트를 읽으십시오. 파괴적인 변경 사항, 특히 데이터베이스나 벡터 확장 관련 변경 사항은 릴리스 노트에 명시됩니다. v3.0 릴리스가 대표적인 예입니다. 해당 버전에서 pgvecto.rs가 완전히 제거되었으므로, 이전 확장을 사용하던 사용자는 업그레이드 전에 반드시 VectorChord 마이그레이션(v1.133에서 도입됨)을 완료해야 했습니다.
  3. 먼저 데이터베이스를 백업하십시오 (9단계). 항상 백업해야 하지만, 릴리스 노트에 데이터베이스 관련 내용이 있다면 더욱 주의해야 합니다.
  4. 새로운 compose 파일을 함께 가져오십시오. IMMICH_VERSION는 서버와 ML 이미지만 고정합니다. Postgres 이미지는 docker-compose.yml 내부에서 다이제스트로 고정되므로, 더 새로운 데이터베이스 확장이 필요한 버전은 새로운 compose 파일을 함께 배포합니다. 두 릴리스 에셋을 모두 다시 다운로드하고, .env 값을 다시 적용한 뒤 업그레이드하십시오.
  5. 모바일 클라이언트를 먼저 업데이트하십시오. 서버는 동일한 메이저 버전과 통신하며, 앱은 일반적으로 현재 및 이전 메이저 버전과 호환됩니다. 서버 버전이 앱보다 높을 경우, 현재 릴리스(v3.3.1, 2026-10-10 기준)에서는 휴대폰에 App update is available 알림과 Update 버튼이 표시됩니다. Immich는 서버보다 모바일 클라이언트를 먼저 업그레이드할 것을 권장합니다.

새로운 파일을 준비한 후 실행할 실제 명령어는 다음과 같습니다.

cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune

9단계: 백업, 데이터베이스 덤프와 원본 파일, 그리고 복구 테스트

Immich 백업은 두 가지 요소로 구성되며, 하나라도 빠지면 무용지물입니다. 데이터베이스에는 앨범 구조, 얼굴 인식 정보, 검색 인덱스, 자산과 파일 간의 매핑 정보가 저장됩니다. 원본 디렉터리(originals directory)에는 실제 사진 파일이 저장됩니다. 둘 중 하나만 복구하면 조직화되지 않은 사진만 남거나, 존재하지 않는 파일을 가리키는 빈 껍데기만 남게 됩니다. 이러한 이중 구조는 Immich만의 특성이 아닙니다. 자체 호스팅 Chatwoot 지원 데스크 역시 Postgres 덤프와 업로드 디렉터리를 함께 백업해야 하며, 그렇지 않으면 복구된 받은 편지함에서 모든 첨부 파일이 누락됩니다. Postgres 데이터 디렉터리를 파일 트리 형태로 복사하는 것은 덤프 단계를 우회하는 지름길처럼 보이지만, 이는 올바른 백업 방식이 아닙니다. 전체 Immich 백업 및 복구 가이드에서는 이러한 함정을 다루며, 이를 간과할 경우 타임라인이 비어 있는 상태로 복구되는 실수를 범하게 됩니다.

Postgres 컨테이너 내부에서 pg_dump 명령을 사용하여 데이터베이스를 덤프하십시오. 이때 전체 클러스터가 아닌 immich 데이터베이스만 지정해야 합니다.

sudo docker exec -t immich_postgres pg_dump --clean --if-exists \
  --dbname=immich --username=postgres | gzip > /opt/immich/immich-db-$(date +%F).sql.gz

그다음 UPLOAD_LOCATION, 즉 전체 /opt/immich/library 트리를 백업하십시오. 특히 library/, upload/, profile/ 하위 폴더를 restic, rsync 또는 borg를 사용하여 다른 머신이나 오브젝트 스토리지로 전송하십시오. 이 작업을 수행하는 스케줄러(cron 항목이나 systemd 타이머)는 실패 시 알림을 보낼 수 있어야 합니다. systemd OnFailure= 유닛을 자체 ntfy 푸시 서버와 연결하면, 덤프 작업이 실패한 밤에 즉시 휴대폰으로 알림을 받을 수 있어 복구 시점에 문제를 발견하는 상황을 방지할 수 있습니다. 데이터베이스를 먼저 백업하고 파일을 나중에 백업하십시오. 그래야 파일 백업이 복사하지 않은 사진을 덤프가 참조하는 일이 발생하지 않습니다. 외부 라이브러리는 Immich가 관리하지 않으므로 실제 원본 위치에서 별도로 백업해야 합니다.

이제 모두가 건너뛰는 단계인 복구 테스트를 수행할 차례입니다. 복구는 서버가 한 번도 실행된 적 없는 새로운 스택을 대상으로 수행해야 합니다. 또한 덤프와 호환되는 벡터 확장(vector extension)이 포함된 Postgres 이미지를 사용해야 하므로, DB 이미지 태그를 임의로 변경해서는 안 됩니다. 동일한 compose 파일과 .env을 사용하는 별도의 환경에서 기존 상태를 모두 삭제하고, 데이터베이스만 실행한 뒤 덤프를 로드하십시오.

cd /opt/immich
sudo docker compose down -v
sudo docker compose pull
sudo docker compose create
sudo docker start immich_postgres
sleep 10
gunzip --stdout immich-db-2026-07-15.sql.gz |
  sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" |
  sudo docker exec -i immich_postgres psql --dbname=immich --username=postgres --single-transaction --set ON_ERROR_STOP=on
sudo docker compose up -d

VectorChord 데이터베이스에서 search_path를 sed로 다시 쓰는 과정은 선택 사항이 아닙니다. 이 과정을 생략하면 복구 도중 작업이 중단됩니다. 스택이 다시 시작되고 원본 파일들이 제자리에 배치되면 웹 UI를 열어 확인하십시오. 사진과 앨범이 정상적으로 보인다면 백업이 성공한 것입니다. 이 과정을 한 번도 수행해 본 적이 없다면, 당신은 백업을 가진 것이 아니라 희망을 가진 것뿐입니다.

실패 유형 및 관련 메시지

ML 컨테이너가 OOM-killed 되는 경우. sudo docker compose logs immich-machine-learning이 갑자기 종료되고, docker compose ps에서 Restarting을 확인할 수 있으며, 종료 코드는 137입니다. sudo dmesg | grep -i oom를 통해 Out of memory: Killed process ... (python3)임을 확인할 수 있습니다. 이 경우 검색 및 얼굴 인식 작업이 중단됩니다. 원인은 모델을 구동하기 위한 RAM 부족입니다. 해결 방법은 순서대로 다음과 같습니다: 스왑 메모리 추가(1단계), VPS RAM 증설, 또는 도저히 불가능한 경우 Administration → Settings → Machine Learning Settings로 이동하여 최상위 머신러닝 토글을 끕니다. 이 설정은 모든 ML 기능을 한 번에 비활성화합니다. Smart Search와 Facial Recognition만 끄는 것으로는 부족합니다. OCR 및 기타 모델 유형이 기본적으로 활성화된 상태로 유지되기 때문입니다. 백업과 앨범은 유지되지만, 콘텐츠 기반 검색 기능은 사용할 수 없게 됩니다. compose 파일에서 immich-machine-learning 서비스를 제거해도 동일한 효과가 나타납니다.

업그레이드 후 Immich 서버가 시작되지 않는 경우. Postgres 컨테이너는 정상 작동할 수 있으나, 시작 시 벡터 확장 버전(vector extension version)을 확인하고 실행을 거부하는 것은 immich_server입니다. 로그에는 The database currently has VectorChord 0.5.3 activated, but the Postgres instance only has 0.4.2 available. This most likely means the extension was downgraded.과 같은 메시지가 반복되거나, 이전 버전 스택의 경우 The pgvecto.rs extension is not available in this Postgres instance.이 나타납니다. 원인은 데이터가 업그레이드된 버전보다 낮은 버전의 데이터베이스 이미지를 사용했기 때문입니다. 이는 주로 이미지 태그를 수동으로 수정했거나, 더 최신 버전의 덤프를 이전 버전 이미지에 복원했을 때 발생합니다. 해결 방법은 일치하는 Postgres 이미지를 사용하고, 데이터베이스와 호환되는 릴리스의 compose 파일을 사용하는 것입니다. 다운그레이드는 하지 마십시오. 호환되는 이미지에만 복원을 진행해야 합니다.

모바일 앱이 서버에 연결되지 않는 경우. URL 입력 후 로그인 화면에 Could not connect to server와 같은 연결 오류가 표시됩니다. 일반적인 원인은 다음과 같습니다: 프록시는 https://만 제공하는데 http://을 입력한 경우, 백엔드에 직접 연결하면서 포트를 생략하여 example.com:2283 대신 example.com(포트 443)으로 시도한 경우, 리버스 프록시가 /api를 전달하지 않는 경우, 또는 Let's Encrypt HTTP-01 챌린지를 처리하는 프록시가 /.well-known/immich을 Immich가 아닌 다른 곳으로 라우팅하는 경우입니다. 해결하려면 전체 https://photos.example.com URL을 입력하고, 먼저 휴대폰 브라우저에서 정상적으로 로드되는지 확인하십시오. 브라우저에서는 작동하지만 앱에서만 안 된다면 프록시가 경로를 제거하거나 /.well-known/immich를 잘못 라우팅하고 있을 가능성이 큽니다. 또는 인증서가 자체 서명된 경우 앱이 핸드셰이크 오류로 거부할 수 있으므로, 앱 설정에서 자체 서명 인증서 지원을 활성화해야 합니다.

가져오기 도중 디스크 공간이 부족한 경우. 업로드가 실패하고 썸네일이 표시되지 않으며, 로그에 ENOSPC: no space left on device 또는 Postgres로부터 could not extend file ... No space left on device이 출력됩니다. df -h을 확인하면 UPLOAD_LOCATION 볼륨이 100% 사용 중임을 알 수 있습니다. 이것이 대규모 라이브러리를 가져오기 전에 디스크 크기를 미리 산정해야 하는 이유입니다. 복구하려면 더 큰 볼륨을 연결하고, 스택을 중지한 뒤 UPLOAD_LOCATION을 해당 볼륨으로 이동하고, .env을 업데이트한 후 다시 시작하십시오. 클라우드 제공업체가 지원한다면 기존 디스크를 확장할 수도 있습니다. 디스크가 꽉 차면 Postgres가 멈출 수 있으므로, 공간을 확보하고 데이터베이스 컨테이너를 재시작한 뒤 데이터 손상 여부를 판단하십시오.

FAQ

Immich는 어느 정도의 RAM과 디스크 용량이 필요한가요?

Immich의 공식 최소 요구 사양은 RAM 6 GB이며, 8 GB를 권장합니다. 소규모 라이브러리의 경우 swap을 포함하여 4 GB가 실질적인 하한선입니다. 머신러닝 컨테이너에서 리소스 사용량이 급증하므로 어떤 경우든 swap을 설정하십시오. 디스크 용량은 전체 라이브러리 크기에 썸네일 및 미리보기 생성을 위한 10–20%의 여유 공간을 더해 산정하십시오. 로컬 스토리지를 사용해야 하며, Postgres 데이터 디렉터리는 절대 네트워크 공유 드라이브에 두지 마십시오. 다른 서비스 운영을 고민 중이라면 2026년 셀프 호스팅 가이드에서 Immich의 리소스 점유율을 다른 서비스와 비교해 볼 수 있습니다.

GPU 없이 Immich를 실행할 수 있나요?

네, 가능합니다. 머신러닝 컨테이너는 CPU에서도 원활하게 작동합니다. GPU는 스마트 검색 인덱싱 속도를 높이거나, 적절한 이미지 변형을 사용할 경우 비디오 트랜스코딩 속도를 높이는 용도로만 사용됩니다. CPU 환경에서 대규모 라이브러리를 처음 인덱싱할 때는 백그라운드에서 수 시간이 소요될 수 있지만, 백업이나 사진 탐색 기능이 차단되지는 않습니다. 만약 시스템 사양이 낮아 머신러닝을 실행하기 어렵다면, 관리자 설정의 최상단 토글을 통해 머신러닝 기능을 완전히 끄고 나머지 기능만 사용할 수 있습니다.

Immich를 안전하게 업그레이드하는 방법은 무엇인가요?

IMMICH_VERSION를 v3.0.2와 같은 특정 태그로 고정하고, 업그레이드 전마다 릴리스 노트를 읽은 뒤 반드시 데이터베이스를 백업하십시오. Postgres 이미지는 IMMICH_VERSION가 아닌 docker-compose.yml 내부에 고정되어 있으므로, 대상 릴리스의 compose 파일과 example.env을 새로 다운로드하여 값을 다시 적용한 후 docker compose pull && docker compose up -d을 실행하십시오. 버전을 자동으로 업데이트되도록 방치하지 마십시오. Immich는 다운그레이드를 지원하지 않으므로, 내용을 확인하지 않고 진행한 업그레이드는 되돌릴 수 없습니다.

정확히 무엇을 백업해야 하나요?

두 가지를 함께 백업해야 합니다. immich 데이터베이스의 pg_dump 파일과 전체 UPLOAD_LOCATION 원본 디렉터리입니다. 데이터베이스에는 앨범, 얼굴 정보, 자산과 파일 간의 매핑 정보가 저장되며, 디렉터리에는 실제 사진 파일이 저장됩니다. 복구 시에는 이 두 가지와 호환되는 벡터 확장이 포함된 데이터베이스 이미지가 모두 필요합니다. 데이터베이스 덤프를 먼저 수행하고 파일 복사를 나중에 진행하십시오. 또한 테스트하지 않은 백업은 백업이 아니므로, 반드시 별도의 테스트 환경에서 복구 과정을 최소 한 번 이상 검증하십시오.

기존 사진 폴더를 가져오려면 어떻게 하나요?

해당 폴더를 읽기 전용으로 immich-server 컨테이너에 추가 볼륨(예: - /srv/photos:/mnt/media/photos:ro)으로 마운트한 뒤 컨테이너를 재생성하십시오. 그 후 Administration → External Libraries에서 라이브러리를 생성하고 컨테이너 경로인 /mnt/media/photos을 추가하십시오. Immich는 파일을 제자리에서 인덱싱하며, 원본 파일을 수정하거나 삭제하지 않습니다. 가장 흔한 실수는 컨테이너 경로 대신 호스트 경로를 입력하는 것이며, 이 경우 스캔 시 아무것도 찾지 못하게 됩니다.