본문 바로가기
카테고리 없음

Immich로 구글 포토 없이 가족 사진 무제한 백업 (도메인 연결까지) — 홈랩 입문 10편

by DDlabx 2026. 7. 9.

Immich는 구글 포토를 대체하는 셀프호스팅 사진 서버로, 휴대폰 사진을 우리 집 서버에 자동 백업하고 날짜별 타임라인과 얼굴 인식까지 제공합니다. 용량 제한도, 월 구독료도 없이 내 디스크가 허락하는 만큼 아이 사진을 쌓을 수 있죠. 이 글에서는 Immich 설치부터 앞선 편들에서 만든 도메인·SSL 인프라에 연결해 휴대폰 앱으로 실제 백업하기까지, 제가 직접 구축하며 겪은 과정을 정리합니다.

이 글은 9편(AdGuard Home)에서 이어집니다. 7편(리버스 프록시)8편(SSL)의 인프라가 준비돼 있어야 외부 접속까지 완성할 수 있습니다.

설치 전 자원 확인과 Immich의 구조

Immich는 지금까지 설치한 앱들과 난이도가 다릅니다. AdGuard나 Portainer가 컨테이너 하나였다면, Immich는 서버, 머신러닝, PostgreSQL, Redis 네 개의 컨테이너로 구성됩니다. 특히 얼굴 인식을 담당하는 머신러닝 컨테이너가 메모리를 제법 쓰기 때문에, 설치 전 자원부터 확인하는 것이 좋습니다.

free -h
df -h /

제 가상머신 환경은 RAM 총 7.3GB에 사용 가능 6.5GB, 디스크는 59GB 중 51GB가 비어 있었고, 이 정도면 머신러닝을 포함해 네 개 컨테이너를 모두 돌리기에 충분했습니다. 한 가지 눈여겨볼 점은 Swap이 0B였다는 것입니다. 스왑이 없으면 메모리가 순간적으로 부족할 때 컨테이너가 강제 종료(OOM)될 수 있는데, 제 경우 RAM 여유가 넉넉해 문제가 없었습니다. 만약 컨테이너가 자꾸 죽는다면 스왑을 추가하거나 머신러닝 컨테이너를 제외하는 방법을 고려하면 됩니다. 사진을 저장할 공간이므로 디스크 여유는 넉넉할수록 좋습니다.

 

설치 — 긴 URL 붙여넣기의 함정

Immich는 공식 docker-compose 파일을 받아 쓰는 것이 표준입니다. 직접 작성하면 버전이 안 맞아 깨지기 쉽습니다. 작업 폴더를 만들고 공식 파일 두 개를 내려받습니다.

mkdir ~/immich && cd ~/immich
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"

여기서 제가 실제로 겪은 함정이 있습니다. 처음엔 큰따옴표 없이 명령을 붙여넣었는데, 긴 URL이 중간에서 줄바꿈으로 쪼개지면서 ERROR 404: Not Found가 뜨고, 뒤쪽 조각은 별도 명령으로 실행돼 No such file or directory 에러까지 났습니다. 결과적으로 docker-compose.yml과 .env가 0바이트 빈 파일로 생성됐죠. 해결은 간단합니다. 빈 파일을 지우고(rm docker-compose.yml .env), 위처럼 URL을 큰따옴표로 감싸서 한 줄로 실행하면 됩니다. ls -la로 파일 크기가 0이 아닌지 꼭 확인하세요.

이어서 nano .env로 환경변수를 확인합니다. UPLOAD_LOCATION은 사진이 저장될 경로이고, DB_PASSWORD는 기본값이므로 바꿔주는 것이 좋습니다. 저장 후 docker compose up -d를 실행하면 이미지 네 개를 받느라 몇 분 걸립니다. 완료 후 docker compose ps로 확인해 immich_server, immich_machine_learning, immich_postgres, immich_redis가 모두 healthy로 뜨면 성공입니다. 이제 http://내서버IP:2283으로 접속해 관리자 계정을 만들면 대시보드에 진입합니다.

 

도메인 연결 — Scheme과 업로드 용량 설정

여기서부터 앞선 편들의 인프라가 빛을 발합니다. NPM 관리 화면에서 'Add Proxy Host'를 눌러 Immich를 도메인에 연결합니다. Domain Names에 photo.ddlabx-home.duckdns.org, Scheme에 http, Forward Hostname/IP에 172.30.1.51, Forward Port에 2283을 넣고, Websockets Support를 켭니다. 7편의 Portainer는 https(9443)였던 것과 달리 *Immich는 http(2283)*이므로 Scheme을 혼동하지 않도록 주의해야 합니다.

그다음이 Immich 특유의 필수 설정입니다. 리버스 프록시를 거치면 Nginx가 업로드 파일 크기를 기본 1MB로 제한하기 때문에, 동영상이나 고화질 사진 업로드가 413 Request Entity Too Large 에러로 실패합니다. 이를 막으려면 커스텀 Nginx 설정에 아래 한 줄을 넣어야 합니다.

client_max_body_size 50000M;

이 입력창의 위치가 자료마다 다른데, 최신 NPM에서는 예전처럼 'Advanced' 탭이 따로 있지 않습니다. 제 버전에서는 편집 창 오른쪽 상단의 톱니바퀴(⚙️) 아이콘을 눌러야 'Custom Nginx Configuration' 입력란이 나타났습니다. 예전 글을 보고 Advanced 탭을 찾다가 없어서 헤매기 쉬운 부분입니다. 세미콜론까지 포함해 입력하고 저장한 뒤, SSL 탭에서 'Request a new Certificate'와 Force SSL, HTTP/2를 켜고 저장하면 8편과 동일하게 인증서가 발급됩니다.

 

휴대폰 앱 자동 백업 — 시리즈가 하나로 이어지는 순간

설정을 마친 뒤 휴대폰 데이터(5G)로 https://photo.ddlabx-home.duckdns.org에 접속하니, 자물쇠와 함께 Immich 로그인 화면이 정상적으로 열렸습니다. 이 시점이 이 시리즈의 클라이맥스입니다. 6편에서 만든 고정 주소(DDNS), 6-2편에서 연 포트, 7편의 리버스 프록시, 8편의 SSL 인증서가 모두 합쳐져야 비로소 '집 밖에서 안전하게 내 사진 서버에 접속'이 가능해지기 때문입니다.

이제 앱스토어에서 Immich 앱을 설치하고 서버 주소에 https://photo.ddlabx-home.duckdns.org를 입력한 뒤 계정으로 로그인합니다. 백업 설정에서 앨범을 고르고 백업을 켜면 사진이 올라가기 시작합니다. 처음에는 전체 카메라 롤 대신 앨범 하나만 골라 테스트하는 것을 권합니다. 실제로 몇 장을 올린 뒤 웹에서 확인하니, 사진이 촬영 날짜별로 자동 정렬된 타임라인으로 표시됐습니다. 구글 포토와 동일한 사용 경험이 내 서버 위에서 구현된 것입니다.

몇 가지 실전 팁을 덧붙입니다. 서버에 실제로 파일이 쌓이는지는 du -sh ~/immich/library로 확인할 수 있습니다. 그리고 아이폰은 iOS의 백그라운드 실행 제한 때문에 백그라운드 백업이 즉시 이뤄지지 않고, 앱을 가끔 열어줘야 밀린 사진이 올라갑니다. 이는 Immich의 문제가 아니라 iOS 정책이니 참고하세요. 마지막으로 가장 중요한 것은 백업입니다. 사진은 무엇보다 소중한 데이터인데, 지금 구성은 서버 한 곳에만 저장돼 있어 디스크가 고장 나면 그대로 잃습니다. 다음 편에서 이 데이터를 안전하게 지키는 3-2-1 백업 전략을 다루겠습니다. → 11편. Vaultwarden — 내 비밀번호는 내 서버에


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 블로그 이름