Immich로 5만 장 사진 관리 자동화하기 – 아이클라우드와 구글포토 통합 백업
아이폰과 아이맥이 수대 있는 집에서 아이클라우드 2TB와 구글 클라우드 2TB를 각각 구독하고 있었다. 이번에 아이폰에서 갤럭시 폴드4로 넘어가게 되면서 구글 클라우드까지 함께 사용하게 되었는데, 내 사진이 총 280GB, 거의 5만 장에 달했기 때문이다.
처음엔 아이클라우드에서 구글포토로 내보내기를 하여 갤럭시 폴드에서 사진을 무리 없이 볼 수 있었지만, 언젠가 다시 아이폰으로 돌아갈 가능성을 생각하니 중립적인 백업 시스템이 필요했다. 그래서 양쪽 플랫폼에서 접근 가능한, 클라우드와 NAS 중간 성격의 솔루션을 찾게 되었고, 그게 바로 Immich였다.
1. Immich란?
Immich는 자체 서버나 NAS에 설치할 수 있는 오픈소스 사진 관리 시스템이다. Google Photos 대체제로 자주 언급되며, 스마트폰 앱과 웹 인터페이스를 모두 제공하고, AI 기반 태깅 및 얼굴 인식, 지도 보기 등도 지원한다. 무엇보다 중요한 건 ‘내 데이터는 내 서버에’라는 철학이다.
2. Immich 설치 (Ubuntu 24.04 + Docker)
내 시스템은 AMD Threadripper 기반의 Ubuntu 24.04 서버였고, GPU는 RTX 3090. GPU 없이도 설치 가능하지만 추후 머신러닝 기반 기능을 쓰기 위해 CUDA 이미지도 함께 구성했다.
설치 준비:
sudo apt update
sudo apt install docker docker-compose -y
디렉토리 구조 (예시):
/8TB/immich/
├── docker-compose.yml
├── .env
└── library/
└── icloud/
docker-compose.yml 예시:
version: ‘3.8’
name: immich
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
– ${UPLOAD_LOCATION}:/usr/src/app/upload
– /etc/localtime:/etc/localtime:ro
– /8TB/immich/library/icloud:/mnt/library/icloud:rw
env_file:
– .env
ports:
– ‘2283:2283’
depends_on:
– redis
– database
restart: always
healthcheck:
disable: false
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
– model-cache:/cache
env_file:
– .env
restart: always
healthcheck:
disable: false
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm@sha256:facc1d2c3462975c34e10fccb167bfa92b0e0dbd992fc282c29a61c3243afb11
healthcheck:
test: redis-cli ping || exit 1
restart: always
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:5f6a838e4e44c8e0e019d0ebfe3ee8952b69afc2809b2c25f7b0119641978e91
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: ‘–data-checksums’
volumes:
– ${DB_DATA_LOCATION}:/var/lib/postgresql/data
shm_size: 128mb
restart: always
volumes:
model-cache:
.env 예시:
# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables
# The location where your uploaded files are stored
UPLOAD_LOCATION=./library
# The location where your database files are stored. Network shares are not supported for the database
DB_DATA_LOCATION=./postgres
# To set a timezone, uncomment the next line and change Etc/UTC to a TZ identifier from this list: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
# TZ=Etc/UTC
# The Immich version to use. You can pin this to a specific version like “v1.71.0”
IMMICH_VERSION=release
# Connection secret for postgres. You should change it to a random password
# Please use only the characters `A-Za-z0-9`, without special characters or spaces
DB_PASSWORD=XXXXXXX
# The values below this line do not need to be changed
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
(위 내용 동일하며, DB_PASSWORD만 본인 설정으로 변경)
이후 아래 명령으로 실행:
docker compose up -d
웹 브라우저에서 http://서버IP:2283 접속하면 Immich의 설정 페이지가 나타난다.
3. 대량 사진 업로드 전 고려할 점
웹으로 사진을 하나씩 업로드하면 너무 느릴 뿐 아니라, 다음과 같은 문제가 발생할 수 있다:
수만 장을 업로드 시 브라우저가 멈추거나 중단됨
EXIF 정보가 없으면 시간순 정렬이 엉망이 됨
아이맥의 사진 앱에서 내보내기 하더라도 EXIF가 유실될 수 있음
구글포토에서 받은 사진은 .json 메타데이터가 별도로 존재함
4. 구글포토에서 JSON 기반 EXIF 정보 복구
사진 파일은 구글 Takeout 기능을 사용하여 내보냈고, 용량은 약 280GB에 달했다. .jpg 파일 옆에 같은 이름의 .json 파일이 존재하며, 여기서 촬영 시간과 위치 정보를 추출해 EXIF에 삽입해야 했다.
필수 패키지 설치:
sudo apt install exiftool jq -y
스크립트 예시 (fix_exif.sh):
#!/bin/bash
BASE_DIR=”/8TB/google_photo/Takeout/Google 포토”
find “$BASE_DIR” -type f -iname ‘*.json’ | while read -r json_file; do
for ext in jpg JPG jpeg JPEG; do
jpg_file=”${json_file%.json}.$ext”
[[ -f “$jpg_file” ]] ^^ break
done
if [[ -f “$jpg_file” ]]; then
datetime=$(jq -r ‘.photoTakenTime.timestamp’ “$json_file”)
if [[ “$datetime” != “null” ]]; then
datetime_fmt=$(date -d “@$datetime” “+%Y:%m:%d %H:%M:%S”)
fi
lat=$(jq -r ‘.geoData.latitude’ “$json_file”)
lon=$(jq -r ‘.geoData.longitude’ “$json_file”)
alt=$(jq -r ‘.geoData.altitude’ “$json_file”)
exiftool \
-overwrite_original \
${datetime_fmt:+-DateTimeOriginal=”$datetime_fmt”} \
${lat:+-GPSLatitude=”$lat”} \
${lon:+-GPSLongitude=”$lon”} \
${alt:+-GPSAltitude=”$alt”} \
“$jpg_file”
echo “✅ 처리됨: $jpg_file”
fi
done
실행 예시:
bash fix_exif.sh
5. Immich 업로드
이제 EXIF가 완비된 사진 폴더를 Immich 웹에서 직접 업로드하거나, CLI 툴을 통해 일괄 업로드할 수 있다. 나는 다음 명령어로 CLI를 설치했다:
npm install -g @immich/cli
로그인:
immich login -u http://서버IP:2283 -e [이메일] -p [비밀번호]
일괄 업로드:
immich upload /8TB/google_photo/Takeout/Google\ 포토
6. 결과 및 정리
약 5만 장의 사진 업로드 완료
날짜와 위치 기반 정렬 정상 작동
Immich에서 검색 및 지도 보기, 태그 분류 가능
결론
기존 아이클라우드나 구글포토만으로는 여러 기기, 플랫폼 간 연동이 어려웠지만, Immich를 직접 운영함으로써 완전한 개인화된 사진 관리가 가능해졌다. 무엇보다도 데이터가 내 서버에 있다는 점이 가장 큰 만족이다.
이제 사진 정리를 클라우드 구독에 의존하지 않고, 내 저장소와 인프라에서 안정적으로 관리할 수 있다.
