11년 된 맥북으로 구글포토 대체하기: Immich + WD EX2100 홈 사진 서버 구축기

저는 개발자가 아닙니다.

그런데 요즘 자꾸 집에 있는 오래된 장비들을 살려내고 있습니다. 워드프레스도 직접 서버에 올리고, Obsidian 동기화도 직접 만들고, 이번에는 가족 사진 서버까지 만들었습니다.

이번 목표는 단순했습니다. 구글포토를 대체할 수 있는 우리집 사진 서버를 만들어보자.

결론부터 말하면 성공했습니다. 지금은 iPhone에서 찍은 사진이 Immich 앱을 통해 집에 있는 리눅스 맥북 서버로 올라가고, 실제 사진 파일은 WD EX2100 NAS에 저장됩니다.

iPhone Immich 앱
    ↓
Tailscale 또는 집 Wi‑Fi
    ↓
2015 맥북프로 Linux Mint 서버
    ↓
Immich + Docker
    ↓
WD EX2100 NAS

말은 거창하지만, 실제로는 오래된 맥북 하나와 기존 NAS를 재활용한 프로젝트입니다. 비개발자 입장에서는 중간중간 막히는 부분이 많았지만, AI에게 물어보면서 하나씩 해결했습니다. 이게 요즘 제가 말하는 바이브코딩입니다.

이 글은 누구를 위한 글인가요?

  • 구글포토 용량이 꽉 차서 매달 요금을 내고 있는 분
  • 아이 사진, 가족 사진을 외부 클라우드에만 맡기기 찜찜한 분
  • 집에 안 쓰는 노트북이나 NAS가 있는 분
  • 홈서버를 해보고 싶은데 개발자는 아닌 분
  • 명령어를 완벽히 이해하지는 못해도, 한 줄씩 따라가며 구축해보고 싶은 분

최종 구성

  • 서버: 2015년형 맥북프로 13인치
  • 운영체제: Linux Mint
  • 사진 앱: Immich
  • 실제 사진 저장소: WD EX2100 NAS
  • NAS 마운트 경로: /mnt/ex2100-immich
  • Immich 설치 경로: ~/immich-app
  • 접속 포트: 2283
  • 외부 접속: Tailscale 사용

[스크린샷 자리 — Immich 웹 갤러리 메인 화면]

비용 정리

새로 산 건 거의 없습니다. 2015 맥북프로와 WD EX2100 NAS는 기존 장비를 활용했고, 새로 필요한 건 USB 유선랜 어댑터 정도였습니다. Linux Mint, Docker, Immich, Tailscale 개인 사용은 모두 무료 범위에서 썼습니다.

구글포토나 iCloud 용량을 계속 늘리는 방식과 비교하면, 초기 셋업에 시간은 들지만 월 구독료는 줄일 수 있습니다. 물론 완전히 공짜라고 말하긴 어렵습니다. 전기세도 있고, 서버 관리도 제 책임입니다. 대신 데이터는 우리집 안에 있습니다.

전체 시스템 구조

가족 폰들
    ↓
집 Wi‑Fi 또는 Tailscale
    ↓
Linux Mint 맥북 서버
    ├─ Immich Server
    ├─ PostgreSQL
    ├─ Redis / Valkey
    └─ Machine Learning
    ↓ CIFS 마운트
WD EX2100 NAS
    └─ 실제 사진 파일 저장

저는 이 구조를 이렇게 이해했습니다. 맥북은 사진 서버의 두뇌입니다. 목록 관리, 검색, 얼굴 인식, DB 관리를 담당합니다. WD EX2100은 사진 창고입니다. 실제 원본 사진과 썸네일 파일을 보관합니다. Tailscale은 밖에서도 집 서버에 안전하게 접속하게 해주는 통로입니다.

Step 1. 오래된 맥북에 Linux Mint 설치

처음 고민은 “그냥 macOS에서 돌리면 안 되나?”였습니다. 가능은 하겠지만, 오래된 맥북에 최신 macOS는 무겁습니다. 저는 이 맥북을 데스크톱처럼 쓰려는 게 아니라 24시간 켜둘 서버로 쓰려는 것이기 때문에 Linux Mint로 갔습니다.

  • Linux Mint ISO 다운로드
  • USB 설치 디스크 만들기
  • 맥북 부팅 시 Option 키를 누르고 USB 선택
  • Linux Mint 설치
  • 계정 생성
  • 재부팅 후 기본 업데이트

여기서 초반 함정이 있었습니다. 2015 맥북의 무선랜은 Linux에서 바로 잘 안 잡힐 수 있습니다. 그래서 저는 USB 유선랜 어댑터를 사용했습니다. 서버는 어차피 유선이 더 안정적이니 결과적으로는 잘한 선택이었습니다.

Step 2. 맥북을 서버처럼 동작하게 만들기

노트북을 서버로 쓰려면 꼭 해야 하는 설정이 있습니다. 덮개를 닫아도 잠들지 않게 해야 합니다. Linux Mint 전원 관리자에서 덮개 닫을 때 “아무것도 안 함”, 비활성 시 절전 “사용 안 함”으로 바꿨습니다. 이걸 안 하면 사진 서버가 아니라 덮개 닫는 순간 잠드는 노트북이 됩니다.

Step 3. Docker 설치

Immich는 Docker Compose로 설치하는 게 가장 깔끔합니다. 앱마다 필요한 구성요소를 컨테이너라는 박스에 담아 관리한다고 생각하면 됩니다.

sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
docker run hello-world

Step 4. Immich 설치 파일 준비

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

여기서 작은 함정이 있습니다. wget -O의 O는 대문자입니다. 대문자 -O는 저장할 파일명을 지정하는 옵션이고, 소문자 -o는 로그 파일 옵션이라 완전히 다릅니다. 저 같은 사람은 이런 데서 한 번씩 막힙니다.

Step 5. .env 설정

최종적으로 제 서버의 핵심 설정은 이런 방향으로 맞췄습니다. 실제 비밀번호는 절대 블로그에 쓰지 않습니다.

UPLOAD_LOCATION=/mnt/ex2100-immich
DB_DATA_LOCATION=./postgres
IMMICH_VERSION=v2
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
DB_PASSWORD=비밀번호는_비공개

Step 6. Immich 실행

cd ~/immich-app
docker compose up -d
docker ps

현재 제 서버에는 immich_server, immich_postgres, immich_machine_learning, immich_redis 컨테이너가 떠 있습니다. 웹 접속 주소는 http://서버IP:2283 입니다. 집 안에서는 맥북의 내부 IP로 접속했고, 밖에서는 Tailscale IP를 사용했습니다.

Step 7. WD EX2100 NAS 마운트

여기가 핵심입니다. Immich를 맥북 SSD에만 저장하게 두면 금방 용량이 찹니다. 그래서 실제 사진 파일은 WD EX2100 NAS에 저장하게 했습니다.

sudo apt install -y cifs-utils smbclient
sudo mkdir -p /mnt/ex2100-immich

NAS에 immich 공유 폴더를 만들고, CIFS 자격증명을 따로 저장했습니다.

sudo nano /etc/cifs-credentials
sudo chmod 600 /etc/cifs-credentials
username=NAS계정명
password=NAS비밀번호

그 다음 /etc/fstab에 마운트 설정을 추가했습니다. 실제 IP와 계정 정보는 각자 환경에 맞게 바꿔야 합니다.

//NAS-IP/immich /mnt/ex2100-immich cifs credentials=/etc/cifs-credentials,uid=1000,gid=1000,vers=3.0,iocharset=utf8,nofail,_netdev,noperm,file_mode=0777,dir_mode=0777 0 0

여기서 중요한 옵션은 noperm입니다. Docker 컨테이너와 CIFS 권한이 충돌해서 업로드가 실패하는 경우가 있었는데, 이 옵션을 넣고 해결했습니다.

sudo mount -a
mount | grep ex2100

현재 제 NAS는 약 2.7TB 용량으로 마운트되어 있고, Immich 사진 저장소로 사용 중입니다.

Step 8. Immich 저장 위치를 NAS로 변경

Immich의 .env에서 업로드 위치를 NAS 마운트 경로로 바꿨습니다.

UPLOAD_LOCATION=/mnt/ex2100-immich

그리고 Immich에는 중요한 안전장치가 있습니다. 데이터 폴더 안에 .immich 표식 파일이 있어야 합니다. 이게 없으면 Immich가 “여기가 진짜 내 데이터 폴더 맞아?” 하고 시작을 거부할 수 있습니다.

mkdir -p /mnt/ex2100-immich/{thumbs,upload,backups,library,profile,encoded-video}
touch /mnt/ex2100-immich/{thumbs,upload,backups,library,profile,encoded-video}/.immich
cd ~/immich-app
docker compose up -d

Step 9. 진짜 NAS에 저장되는지 확인

설치에서 제일 중요한 건 “된 것처럼 보이는 것”이 아니라 실제로 저장이 되는지 확인하는 겁니다. 웹이나 iPhone 앱에서 사진을 한 장 올린 다음, 서버에서 이렇게 확인했습니다.

find /mnt/ex2100-immich -name "*.jpg" -o -name "*.heic" -o -name "*.png" 2>/dev/null

/mnt/ex2100-immich/library/... 아래에 파일이 보이면 성공입니다. 이 순간 “아, 진짜 내 NAS에 들어가고 있구나” 하는 안도감이 옵니다.

iPhone 앱 연결

집 안: http://맥북내부IP:2283
집 밖: http://Tailscale-IP:2283

집 밖에서 쓰려면 공유기 포트포워딩보다 Tailscale이 편했습니다. 포트 열고 HTTPS 붙이는 것보다, 내 기기끼리 VPN으로 연결하는 방식이 비개발자 입장에서는 훨씬 덜 무섭습니다.

실제로 만난 에러와 해결법

1. Linux Mint에서 Wi‑Fi가 안 잡힘

2015 맥북의 Broadcom 무선랜은 Linux에서 바로 안 잡힐 수 있습니다. 해결은 간단했습니다. USB 유선랜 어댑터를 썼습니다. 어차피 서버는 유선이 안정적입니다. (또 말떨어지면 바로해야되는 스타일이라.. 쿠팡에서 꼬다리 바로하나 샀어요.)

2. CIFS 마운트에서 Device or resource busy

이름만 보면 뭔가 큰일 난 것 같지만, 실제로는 이미 마운트되어 있어서 다시 마운트하려다 막힌 경우였습니다.

mount | grep ex2100
sudo umount -l /mnt/ex2100-immich
sudo mount -a

3. 사진 업로드 실패

처음에는 앱에서 업로드가 되는 듯하다가 실패했습니다. 원인은 Docker 컨테이너와 CIFS 마운트 권한 문제였습니다. /etc/fstabnoperm,file_mode=0777,dir_mode=0777 옵션을 넣고 해결했습니다.

4. Immich 컨테이너 무한 재시작

immich_server가 계속 재시작하는 경우가 있었습니다. 로그를 보니 .immich 표식 파일을 못 찾는 문제였습니다.

docker logs immich_server --tail 50

5. iPhone 앱에서 서버 버전을 확인할 수 없음

iPhone 앱에서 서버 버전이 --로 보이고 저장공간도 0/0으로 보이는 일이 있었습니다. 확인해보니 immich_server 컨테이너가 떠 있긴 하지만 unhealthy 상태였고, API 응답이 timeout이었습니다. 이때는 DB나 사진 파일을 건드리지 않고 서버 컨테이너만 재시작했습니다.

docker restart immich_server

재시작 후 /api/server/ping이 다시 {"res":"pong"}을 반환했고, iPhone 앱도 정상으로 돌아왔습니다.

구형 맥북에서 Immich를 안정적으로 쓰기 위한 조정

Immich는 단순 사진 저장소가 아닙니다. 사진을 올리면 뒤에서 썸네일 생성, 메타데이터 추출, 얼굴 인식, 스마트 검색 인덱싱, OCR, 동영상 변환 같은 작업을 합니다. 구형 맥북에서는 이 작업들이 한꺼번에 몰리면 서버가 버거워질 수 있습니다.

thumbnailGeneration: 2
metadataExtraction: 2
faceDetection: 1
smartSearch: 1
videoConversion: 1
ocr: 1

속도는 조금 느려질 수 있지만, 서버가 뻗는 것보다는 낫습니다. 이미 처리된 사진을 보는 속도보다는, 새로 업로드한 사진의 후처리 속도에 영향을 줍니다.

자동 복구 watchdog도 붙였습니다

한 번 겪고 나니 “서버가 또 응답 안 하면 자동으로 살려주면 안 되나?”라는 생각이 들었습니다. 그래서 간단한 watchdog을 만들었습니다. 5분마다 /api/server/ping을 확인하고, 3회 연속 실패하면 immich_server만 재시작합니다.

정상일 때: 아무 알림 없음
3회 연속 실패: immich_server 재시작
복구 후: 텔레그램 알림

중요한 건 DB나 사진 파일은 건드리지 않는다는 점입니다. API 서버 컨테이너만 재시작합니다. 구형 장비로 홈서버를 운영할 때 이런 자동 복구 장치는 마음의 평화를 줍니다.

자주 쓰는 유지보수 명령어

# 컨테이너 상태 확인
cd ~/immich-app
docker compose ps

# 서버 로그 보기
docker logs immich_server --tail 50

# API 응답 확인
curl http://127.0.0.1:2283/api/server/ping

# Immich 서버만 재시작
docker restart immich_server

# 업데이트
cd ~/immich-app
docker compose pull
docker compose up -d

좋았던 점

  • 월 구독료 없이 가족 사진 서버 운영 가능
  • 사진 데이터가 우리집 안에 있음
  • iPhone 자동 백업 가능
  • 구글포토와 비슷한 타임라인 경험
  • 얼굴 인식과 검색 기능 제공
  • 기존 NAS와 오래된 맥북 재활용

아쉬운 점

  • 초기 셋업은 확실히 손이 갑니다
  • NAS 마운트와 권한 문제에서 막힐 수 있습니다
  • 외부 접속은 Tailscale 같은 추가 구성이 필요합니다
  • 대량 업로드 후 얼굴 인식/검색 처리는 시간이 걸립니다
  • 백업은 결국 본인 책임입니다

마치며

11년 된 맥북이 이렇게 다시 쓸모 있어질 줄 몰랐습니다. 예전에는 “오래된 노트북”이었는데, 지금은 우리집 사진 서버의 두뇌가 됐습니다.

이번 작업도 혼자 다 이해하고 한 건 아닙니다. 중간중간 에러가 나올 때마다 AI에게 물어봤고, 로그를 같이 보고, 명령어를 하나씩 실행했습니다. 개발자는 아니지만, 문제를 쪼개서 물어보고 따라가다 보니 결국 됐습니다.

이게 제가 요즘 계속 말하는 바이브코딩입니다. 완벽히 알고 시작하지 않아도 됩니다. 대신 백업하고, 로그 보고, 한 단계씩 확인하면서 가면 됩니다. 오래된 맥북과 NAS가 있다면, 구글포토 대체 프로젝트로 Immich는 충분히 해볼 만합니다.

참고 자료

댓글 남기기