<?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>Cron on Chanyeol Dev</title>
    <link>https://chanyeols.com/tags/cron/</link>
    <description>Recent content in Cron on Chanyeol Dev</description>
    <generator>Hugo</generator>
    <language>ko-kr</language>
    <lastBuildDate>Wed, 01 Apr 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://chanyeols.com/tags/cron/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>노트북으로 홈서버 구축하기 - PostgreSQL 자동 백업 (pg_dump &#43; cron) (10편)</title>
      <link>https://chanyeols.com/posts/part-10-postgresql-backup/</link>
      <pubDate>Wed, 01 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://chanyeols.com/posts/part-10-postgresql-backup/</guid>
      <description>홈서버에서 운영 중인 Immich의 PostgreSQL DB를 pg_dump로 매일 새벽 자동 백업하는 스크립트를 만든 과정을 정리합니다.</description>
      <content:encoded><![CDATA[<h2 id="왜-백업이-필요한가">왜 백업이 필요한가</h2>
<p>Immich에 사진을 올리기 시작하면서 DB가 날아가면 복구할 방법이 없다는 게 갑자기 걱정됐다. 사진 원본은 <code>/mnt/data</code>에 있으니 파일은 살아있더라도 Immich DB가 날아가면 앨범, 태그, 얼굴 인식 데이터가 전부 사라진다.</p>
<p>백업 전략은 단순하게 잡았다.</p>
<table>
  <thead>
      <tr>
          <th>대상</th>
          <th>방법</th>
          <th>위치</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Immich DB</td>
          <td>pg_dumpall</td>
          <td><code>/backup/immich_db_YYYYMMDD.sql</code></td>
      </tr>
      <tr>
          <td>사진 원본</td>
          <td>추후 rsync 추가 예정</td>
          <td>외장하드 구매 후</td>
      </tr>
  </tbody>
</table>
<p>OS SSD에 204GB 여유가 있어서 DB 덤프는 우선 거기에 보관한다.</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>sudo mkdir -p /backup
</span></span><span style="display:flex;"><span>sudo chown your-username:your-username /backup
</span></span></code></pre></div><p><code>chown</code>으로 소유권을 넘겨줘야 한다. 처음에 <code>sudo mkdir</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>cannot create /backup/immich_db_20260329.sql: Permission denied
</span></span></code></pre></div><p><img alt="/backup 디렉토리 생성 및 권한 설정" loading="lazy" src="/images/homeserver-10-backup-dir.png"></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>mkdir ~/backup_script
</span></span><span style="display:flex;"><span>vi ~/backup_script/postgres_immich_backup.sh
</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><span style="color:#8b949e;font-weight:bold;font-style:italic">#!/bin/bash
</span></span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#79c0ff">BACKUP_DIR</span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#a5d6ff">&#34;/backup&#34;</span>
</span></span><span style="display:flex;"><span><span style="color:#79c0ff">DATE</span><span style="color:#ff7b72;font-weight:bold">=</span><span style="color:#ff7b72">$(</span>date +%Y%m%d<span style="color:#ff7b72">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>mkdir -p <span style="color:#79c0ff">$BACKUP_DIR</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"># DB 덤프 백업</span>
</span></span><span style="display:flex;"><span>echo <span style="color:#a5d6ff">&#34;pg_dump 시작...&#34;</span>
</span></span><span style="display:flex;"><span>docker exec immich_postgres pg_dumpall -U postgres &gt; <span style="color:#79c0ff">$BACKUP_DIR</span>/immich_db_<span style="color:#79c0ff">$DATE</span>.sql
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#8b949e;font-style:italic"># 7일치만 보관 (오래된 것 삭제)</span>
</span></span><span style="display:flex;"><span>find <span style="color:#79c0ff">$BACKUP_DIR</span> -name <span style="color:#a5d6ff">&#34;immich_db_*.sql&#34;</span> -mtime +7 -delete
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>echo <span style="color:#a5d6ff">&#34;백업 완료: </span><span style="color:#79c0ff">$DATE</span><span style="color:#a5d6ff">&#34;</span>
</span></span></code></pre></div><p><img alt="백업 스크립트 작성" loading="lazy" src="/images/homeserver-10-backup-script.png"></p>
<p><code>docker exec</code>으로 <code>immich_postgres</code> 컨테이너 안에서 <code>pg_dumpall</code>을 실행해서 결과를 파일로 저장한다. 컨테이너가 실행 중이면 별도 설치 없이 바로 쓸 수 있다.</p>
<p><code>find ... -mtime +7 -delete</code> 로 7일이 지난 백업 파일은 자동으로 삭제한다. 무한정 쌓이면 디스크가 금방 찬다.</p>
<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-bash" data-lang="bash"><span style="display:flex;"><span>chmod +x ~/backup_script/postgres_immich_backup.sh
</span></span></code></pre></div><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>sh ~/backup_script/postgres_immich_backup.sh
</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>pg_dump 시작...
</span></span><span style="display:flex;"><span>백업 완료: 20260329
</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-bash" data-lang="bash"><span style="display:flex;"><span>ls -lh /backup/
</span></span></code></pre></div><hr>
<h2 id="cron-등록">cron 등록</h2>
<p>매일 새벽 3시에 자동 실행되도록 cron에 등록한다.</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>crontab -e
</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>0 3 * * * /home/your-username/backup_script/postgres_immich_backup.sh &gt;&gt; /backup/backup.log 2&gt;&amp;1
</span></span></code></pre></div><p><img alt="crontab 설정" loading="lazy" src="/images/homeserver-10-crontab.png"></p>
<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-bash" data-lang="bash"><span style="display:flex;"><span>crontab -l
</span></span></code></pre></div><p>로그는 <code>/backup/backup.log</code>에 쌓이니 문제가 생기면 여기서 확인하면 된다.</p>
<hr>
<h2 id="7일-보관-정책">7일 보관 정책</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>find <span style="color:#79c0ff">$BACKUP_DIR</span> -name <span style="color:#a5d6ff">&#34;immich_db_*.sql&#34;</span> -mtime +7 -delete
</span></span></code></pre></div><p>스크립트 안에 이 한 줄이 있어서 7일이 지난 백업 파일은 매일 자동으로 정리된다. 7일치 보관 시 필요한 용량은 DB 크기에 따라 다른데, Immich DB는 사진 수가 늘어도 원본 파일은 <code>/mnt/data</code>에 따로 있으니 DB 자체는 수백 MB 수준이다.</p>
<hr>
<h2 id="추후-개선-계획">추후 개선 계획</h2>
<p>외장하드를 구매하면 rsync로 사진 원본도 자동 백업할 예정이다.</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><span style="color:#8b949e;font-style:italic"># 라이브러리 rsync (외장하드 마운트 후 추가)</span>
</span></span><span style="display:flex;"><span>rsync -av --delete /mnt/data/immich/photos/ /mnt/backup/immich/photos/
</span></span></code></pre></div><hr>
<h2 id="정리">정리</h2>
<ul>
<li><code>docker exec</code>으로 컨테이너 안의 <code>pg_dumpall</code>을 실행하면 별도 PostgreSQL 설치 없이 백업 가능</li>
<li><code>/backup</code> 디렉토리는 <code>chown</code>으로 소유권 설정 필수</li>
<li><code>find -mtime +7 -delete</code>로 오래된 백업 자동 정리</li>
<li>cron 로그를 파일로 남겨두면 백업 실패 여부를 나중에 확인할 수 있다</li>
</ul>
<p>다음 편에서는 TLP + thinkfan으로 CPU 온도를 85°C에서 55°C로 낮추고, swappiness 튜닝으로 불필요한 Swap 사용을 줄인 과정을 다룬다.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
