<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Immich on Chanyeol Dev</title>
    <link>https://chanyeols.com/tags/immich/</link>
    <description>Recent content in Immich on Chanyeol Dev</description>
    <generator>Hugo</generator>
    <language>ko-kr</language>
    <lastBuildDate>Thu, 26 Mar 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://chanyeols.com/tags/immich/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>노트북으로 홈서버 구축하기 - Immich로 구글 포토 대체하기 (4편)</title>
      <link>https://chanyeols.com/posts/part-04-immich/</link>
      <pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://chanyeols.com/posts/part-04-immich/</guid>
      <description>자체 호스팅 사진 관리 서비스 Immich를 Docker Compose로 설치하는 과정과 겪었던 4가지 트러블슈팅을 정리합니다.</description>
      <content:encoded><![CDATA[<h2 id="immich란">Immich란?</h2>
<p>구글 포토와 거의 동일한 UX를 제공하는 자체 호스팅 사진 관리 서비스다. 얼굴 인식, 지도 뷰, 앨범, 공유 기능까지 있고 모바일 앱도 있어서 자동 백업이 된다. 구글 포토 유료 요금제를 쓰고 있었는데 이걸로 완전히 대체했다.</p>
<hr>
<h2 id="설치-과정">설치 과정</h2>
<h3 id="1-디렉토리-생성">1. 디렉토리 생성</h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>mkdir ~/immich <span style="color:#ff7b72;font-weight:bold">&amp;&amp;</span> cd ~/immich
</span></span></code></pre></div><h3 id="2-docker-composeyml-및-env-다운로드">2. docker-compose.yml 및 .env 다운로드</h3>
<p>Immich 공식에서 제공하는 파일을 그대로 받아서 쓴다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
</span></span><span style="display:flex;"><span>wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env
</span></span></code></pre></div><h3 id="3-env-파일-수정">3. .env 파일 수정</h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>vi .env
</span></span></code></pre></div><p>아래 두 경로를 수정한다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>UPLOAD_LOCATION=/mnt/data/immich/photos
</span></span><span style="display:flex;"><span>DB_DATA_LOCATION=/home/your-username/immich-db
</span></span></code></pre></div><blockquote>
<p><code>DB_DATA_LOCATION</code>을 <code>/mnt/data</code>(NTFS) 아래로 잡으면 안 된다. 이유는 아래 트러블슈팅에서 설명한다.</p>
</blockquote>
<h3 id="4-실행">4. 실행</h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose up -d
</span></span></code></pre></div><hr>
<h2 id="트러블슈팅">트러블슈팅</h2>
<p>설치 과정에서 꽤 여러 번 막혔다. 겪은 순서대로 정리한다.</p>
<h3 id="1-docker-compose-up--d--unknown-shorthand-flag-오류">1. <code>docker compose up -d</code> — unknown shorthand flag 오류</h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>unknown shorthand flag: &#39;d&#39; in -d
</span></span></code></pre></div><p><code>apt install docker.io</code>로 설치한 패키지가 구버전이라 <code>docker compose</code> 플러그인을 지원하지 않아서 생기는 문제다.</p>
<p><strong>해결:</strong> Docker 공식 레포에서 설치한다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt install ca-certificates curl gnupg -y
</span></span><span style="display:flex;"><span>sudo install -m <span style="color:#a5d6ff">0755</span> -d /etc/apt/keyrings
</span></span><span style="display:flex;"><span>curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
</span></span><span style="display:flex;"><span>echo <span style="color:#a5d6ff">&#34;deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable&#34;</span> | sudo tee /etc/apt/sources.list.d/docker.list
</span></span><span style="display:flex;"><span>sudo apt update
</span></span><span style="display:flex;"><span>sudo apt install docker-compose-plugin -y
</span></span></code></pre></div><h3 id="2-compose-파일-버전-오류">2. Compose 파일 버전 오류</h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>ERROR: The Compose file &#39;./docker-compose.yml&#39; is invalid because:
</span></span><span style="display:flex;"><span>&#39;name&#39; does not match any of the regexes: &#39;^x-&#39;
</span></span></code></pre></div><p><code>apt install docker-compose</code>로 설치한 구버전(1.29.x)은 최신 Compose 파일 형식을 지원하지 않는다.</p>
<p><strong>해결:</strong> 구버전 제거 후 플러그인 버전으로 교체한다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>sudo apt remove docker-compose -y
</span></span><span style="display:flex;"><span>sudo apt install docker-compose-plugin -y
</span></span></code></pre></div><h3 id="3-docker-compose-plugin-패키지를-찾을-수-없음">3. <code>docker-compose-plugin</code> 패키지를 찾을 수 없음</h3>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>E: Unable to locate package docker-compose-plugin
</span></span></code></pre></div><p>Ubuntu 기본 레포에는 <code>docker-compose-plugin</code>이 없다.</p>
<p><strong>해결:</strong> 1번 해결 방법에서 Docker 공식 레포를 먼저 추가하면 된다.</p>
<h3 id="4-immich_postgres-컨테이너가-계속-재시작됨">4. immich_postgres 컨테이너가 계속 재시작됨</h3>
<p>컨테이너 상태를 확인해보면 <code>Restarting</code> 상태로 계속 재시작만 반복한다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker logs immich_postgres
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>FATAL:  data directory &#34;/var/lib/postgresql/data&#34; has wrong ownership
</span></span><span style="display:flex;"><span>HINT:  The server must be started by the user that owns the data directory.
</span></span></code></pre></div><p><strong>원인:</strong> <code>DB_DATA_LOCATION</code>을 <code>/mnt/data</code>(NTFS) 경로로 설정했기 때문이다. NTFS는 Linux 파일 권한 시스템을 지원하지 않아서 PostgreSQL이 요구하는 소유권을 설정할 수 없다.</p>
<p><strong>해결:</strong> DB 경로를 ext4 파일시스템(Ubuntu 기본 디스크)으로 바꾼다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose down
</span></span><span style="display:flex;"><span>mkdir -p ~/immich-db
</span></span><span style="display:flex;"><span>vi .env
</span></span></code></pre></div><p><code>.env</code> 수정:</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-plain" data-lang="plain"><span style="display:flex;"><span>DB_DATA_LOCATION=/home/your-username/immich-db
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose up -d
</span></span></code></pre></div><p>사진 원본(<code>UPLOAD_LOCATION</code>)은 용량이 크니까 NTFS 드라이브에 둬도 되지만, DB는 반드시 ext4에 둬야 한다.</p>
<hr>
<h2 id="정상-실행-확인">정상 실행 확인</h2>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>docker compose ps
</span></span></code></pre></div><p><img alt="docker compose ps 결과 - 모든 컨테이너 running 상태" loading="lazy" src="/images/homeserver-04-compose-ps.png"></p>
<p>모든 컨테이너가 <code>running</code> 또는 <code>healthy</code> 상태면 성공이다.</p>
<p>브라우저에서 <code>http://100.109.108.36:2283</code> 접속 후 계정을 생성하면 된다.</p>
<hr>
<h2 id="oci-nginx-리버스-프록시-연결">OCI Nginx 리버스 프록시 연결</h2>
<p>3편에서 Filebrowser에 했던 것과 동일하게 Nginx 설정을 추가한다.</p>
<div class="highlight"><pre tabindex="0" style="color:#e6edf3;background-color:#0d1117;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-nginx" data-lang="nginx"><span style="display:flex;"><span><span style="color:#ff7b72">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">listen</span> <span style="color:#a5d6ff">80</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">server_name</span> <span style="color:#a5d6ff">photo.yourdomain.com</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">return</span> <span style="color:#a5d6ff">301</span> <span style="color:#a5d6ff">https://</span><span style="color:#79c0ff">$host$request_uri</span>;
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#ff7b72">server</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">listen</span> <span style="color:#a5d6ff">443</span> <span style="color:#a5d6ff">ssl</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">server_name</span> <span style="color:#a5d6ff">photo.yourdomain.com</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">ssl_certificate</span>     <span style="color:#a5d6ff">/ssl/live/yourdomain.com/fullchain.pem</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">ssl_certificate_key</span> <span style="color:#a5d6ff">/ssl/live/yourdomain.com/privkey.pem</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">ssl_protocols</span> <span style="color:#a5d6ff">TLSv1.2</span> <span style="color:#a5d6ff">TLSv1.3</span>;
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">ssl_prefer_server_ciphers</span> <span style="color:#79c0ff;font-weight:bold">on</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#8b949e;font-style:italic"># Immich는 대용량 파일 업로드가 있으므로 크기 제한 해제
</span></span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">client_max_body_size</span> <span style="color:#a5d6ff">0</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#ff7b72">location</span> <span style="color:#a5d6ff">/</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_pass</span> <span style="color:#a5d6ff">http://100.109.108.36:2283</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_set_header</span> <span style="color:#a5d6ff">Host</span> <span style="color:#79c0ff">$host</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_set_header</span> <span style="color:#a5d6ff">X-Real-IP</span> <span style="color:#79c0ff">$remote_addr</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_set_header</span> <span style="color:#a5d6ff">X-Forwarded-For</span> <span style="color:#79c0ff">$proxy_add_x_forwarded_for</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_set_header</span> <span style="color:#a5d6ff">X-Forwarded-Proto</span> <span style="color:#79c0ff">$scheme</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>        <span style="color:#8b949e;font-style:italic"># 웹소켓 지원 (Immich 실시간 업로드에 필요)
</span></span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_http_version</span> <span style="color:#a5d6ff">1</span><span style="color:#a5d6ff">.1</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_set_header</span> <span style="color:#a5d6ff">Upgrade</span> <span style="color:#79c0ff">$http_upgrade</span>;
</span></span><span style="display:flex;"><span>        <span style="color:#ff7b72">proxy_set_header</span> <span style="color:#a5d6ff">Connection</span> <span style="color:#a5d6ff">&#34;upgrade&#34;</span>;
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Cloudflare에서 <code>photo.yourdomain.com</code> DNS 추가하고 Nginx 적용하면 외부에서 접근 가능하다.</p>
<p><img alt="Immich 외부 접근 성공" loading="lazy" src="/images/homeserver-04-immich-external.png"></p>
<hr>
<h2 id="정리">정리</h2>
<ul>
<li><code>docker.io</code>는 구버전이라 최신 Compose 파일을 못 읽는다. Docker 공식 레포에서 설치하자</li>
<li>PostgreSQL 데이터 디렉토리는 NTFS가 아닌 ext4에 둬야 한다</li>
<li>사진 원본은 NTFS 외장 드라이브, DB는 OS 디스크로 분리하면 된다</li>
<li>Immich Nginx 설정 시 <code>client_max_body_size 0</code>과 웹소켓 설정을 빠뜨리지 말 것</li>
</ul>
<p>다음 편에서는 Vaultwarden으로 비밀번호를 자체 호스팅하는 과정을 다룬다.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
