|

사이트 제작기 3부 – 매일 밤 도는 자동화 파이프라인

사이트 제작기 시리즈 · 1부 — 왜 정적 홈페이지인가 / 2부 — 콘텐츠 3구역 / 3부 (이 글) — 자동화 파이프라인 / 4부 — 커스터마이징과 관리자 패널


2부 마지막에서 “AI가 매일 자동으로 글을 올린다”고 했습니다. 이번 편은 그 무인 자동화 라인을 통째로 열어 봅니다. 사람이 잠든 밤사이 이 사이트에서는 세 개의 톱니바퀴가 맞물려 돌아갑니다.

하나씩 뜯어보겠습니다.


1. 톱니바퀴 ① — AI가 IT뉴스를 쓴다

매일의 IT뉴스(content/blog/daily-it-news/)는 AI가 씁니다. 매일 밤, AI 도구가 그날의 AI·IT 주요 소식을 정리해 마크다운 파일 한 장을 만들어 이 폴더에 떨어뜨립니다.

이때 글이 항상 같은 형식으로 나오도록 틀(템플릿)이 준비되어 있습니다. Hugo에서는 이런 새 글 템플릿을 archetypes/ 폴더에 둡니다. 실제 IT뉴스 전용 템플릿(archetypes/daily-it-news.md)은 이렇게 생겼습니다.

{{ .Date.Format "2006년 1월 2일" }} 부분이 재미있는데, Hugo(Go 언어)에서는 날짜 형식을 “2006년 1월 2일”이라는 기준 날짜로 표기합니다. 이 자리에 실제 오늘 날짜가 자동으로 채워져 “2026년 7월 7일 IT뉴스” 같은 제목이 만들어집니다.

이 틀 덕분에 AI는 매일 “내용”만 채우면 되고, 제목·날짜·카테고리·태그 같은 뼈대는 항상 일관되게 유지됩니다.


2. 톱니바퀴 ② — 밤 11시 30분, 스케줄러가 자동으로 올린다

AI가 파일을 만들어 두어도, 누군가 GitHub에 올려(push) 주지 않으면 사이트에는 반영되지 않습니다. 이 “올리는” 일을 사람 대신 해 주는 것이 macOS의 launchd 스케줄러와 자동 푸시 스크립트입니다.

자동 푸시 스크립트 (scripts/auto_push.sh)

핵심 로직만 추리면 이렇습니다.

똑똑한 점은 “바뀐 게 있을 때만 움직인다”는 것입니다. git status --porcelain으로 변경 사항을 검사해, 새 글이 없으면 조용히 종료합니다. 덕분에 의미 없는 빈 커밋이 쌓이지 않습니다. 또 맨 처음에 git pull --rebase를 먼저 해서, 다른 곳(예: 관리자 패널)에서 생긴 변경과 충돌하는 것도 예방합니다.

이 스크립트를 매일 부르는 스케줄러

이 스크립트를 사람이 매일 밤 실행할 수는 없으니, macOS의 백그라운드 스케줄러인 launchd에 등록해 뒀습니다.

  • 등록 파일: ~/Library/LaunchAgents/com.jiwumission.autopush.plist
  • 실행 시각: 매일 밤 11시 30분(23:30)
  • 하는 일: auto_push.sh를 무인으로 호출

작동 여부는 scripts/auto_push.log에 기록됩니다. 스케줄러를 다시 등록하거나 해제하려면 다음 명령을 씁니다.

정리하면, 밤 11시경 AI가 글을 쓰고 → 11시 30분에 스케줄러가 자동으로 올린다는 흐름입니다. 사람은 아무것도 누르지 않습니다.


3. 톱니바퀴 ③ — 아침 6시, 예약된 글이 스스로 공개된다

여기서 정적 홈페이지 특유의 문제가 하나 생깁니다. 정적 사이트는 “빌드하는 그 순간”의 상태로 굳어집니다. 그래서 미래 날짜로 예약해 둔 글은, 그 날짜가 되어도 사이트를 다시 빌드하지 않으면 계속 숨어 있습니다.

이 문제를 풀기 위해 GitHub Actions에 매일 아침 6시 자동 재빌드 워크플로우(.github/workflows/scheduled-publish.yml)를 두었습니다.

원리는 단순하고 영리합니다. 내용이 텅 빈 커밋(--allow-empty)을 하나 만들어 push합니다. 그러면 Cloudflare Pages가 “저장소에 변화가 생겼다!”고 감지해 사이트를 새로 빌드하고, 그 시점에 날짜가 도래한 예약 글들이 자연스럽게 공개됩니다.

💡 cron: "0 21 * * *"이 왜 아침 6시일까요? GitHub Actions는 세계 표준시(UTC)로 돕니다. 한국은 UTC보다 9시간 빠르므로, UTC 21시는 한국 시간으로 다음 날 오전 6시입니다.


4. 톱니바퀴 ④ — 접속하면 오늘의 QT가 팝업으로

이제 이 사이트에서 가장 눈에 띄는 기능, 오늘의 QT 팝업 모달입니다. 방문자가 첫 페이지에 들어오면 그날 날짜에 해당하는 성경 묵상이 부드럽게 떠오릅니다. 2부에서 봤듯 QT는 367개나 미리 쌓여 있는데, 그중 정확히 오늘 것만 골라 보여주는 겁니다. 어떻게 할까요?

4-1. 각 QT를 “작은 데이터 API”로 만든다

핵심 아이디어는 이렇습니다. QT 글 하나하나를, 보통의 HTML 페이지뿐 아니라 JavaScript가 읽기 좋은 데이터 파일(JSON)로도 함께 출력하는 것입니다. 이를 위해 Hugo의 커스텀 출력 형식을 정의한 템플릿(layouts/databank/daily-bible/single.dailybiblejson.txt)이 있습니다.

이 템플릿 덕분에 예를 들어 2026년 7월 7일 QT는 다음 주소에서 JSON 데이터로 접근할 수 있게 됩니다.

즉, 서버 없이도 각 날짜의 QT가 하나의 “미니 API 엔드포인트”가 되는 셈입니다. 이것이 정적 사이트에서 데이터를 다루는 전형적인 기법입니다.

4-2. 홈 화면 JavaScript가 오늘 것을 불러온다

이제 첫 페이지(layouts/home.html)에 심어 둔 JavaScript가 이 데이터를 이용합니다. 핵심 흐름만 옮기면 이렇습니다.

동작을 말로 풀면:

  1. 오늘 날짜를 계산한다 (2026-07-07 형태).
  2. localStorage 확인 — 이 방문자가 “오늘 하루 보지 않기”를 눌렀다면 즉시 종료.
  3. 오늘 날짜의 JSON을 fetch — 파일이 없으면(그날 QT가 준비 안 됐으면) 에러가 나고, 그 에러를 조용히 삼켜서 아무 팝업도 뜨지 않는다.
  4. 내용이 있고 아직 draft 상태가 아니면 → 모달을 띄운다.

4-3. “오늘 하루 보지 않기”의 정체

모달을 닫을 때 “오늘 하루 보지 않기” 체크박스를 켜면, 브라우저의 localStorage에 오늘 날짜를 저장합니다.

그러면 위 ②단계에서 “저장된 날짜 == 오늘”이 되어 다시 뜨지 않습니다. 그리고 날짜가 바뀌면 저장된 값(어제 날짜)과 오늘이 달라지므로 다음 날 다시 정상적으로 등장합니다. 서버도, 로그인도, 데이터베이스도 없이 브라우저 저장소 한 줄로 해결한 겁니다.

🔎 참고로 QT 목록 페이지(/databank/daily-bible/)에도 비슷한 원리로 “오늘의 묵상 보기” 버튼이 있습니다. 오늘 날짜 페이지가 실제로 존재할 때만 버튼이 나타나도록, fetch(... , { method: "HEAD" })로 파일 존재 여부를 먼저 확인합니다.


5. 네 톱니바퀴를 한 장으로

이 네 가지가 맞물려서, 관리자가 아무 버튼도 누르지 않는 날에도 사이트는 매일 새로운 IT뉴스를 발행하고, 방문자에게 그날의 말씀을 건넵니다.


마치며

3부의 요점:

  1. IT뉴스는 AI 생성(정해진 archetype 틀) → 밤 11:30 launchd 자동 push → Cloudflare 배포로 이어진다.
  2. 아침 6시 빈 커밋은 예약 글을 공개하기 위한 정적 사이트 특유의 재빌드 트릭이다.
  3. 오늘의 QT 팝업은 각 QT를 JSON 엔드포인트로 출력하고, 홈 화면 JS가 오늘 것만 fetch해 모달로 띄우며, localStorage로 “하루 안 보기”를 처리한다.

마지막 4부에서는 눈에 보이는 껍데기 — 카드 레이아웃, 반응형 디자인, 다크 모드, 그리고 코딩 없이 브라우저에서 설정을 바꾸는 Git 기반 관리자 패널 — 을 다루고, 제작 과정에서 실제로 부딪혔던 대표적인 문제와 해결법도 함께 정리하겠습니다.

Similar Posts

  • |

    사이트 제작기 2부 – 콘텐츠 3구역 대해부

    사이트 제작기 시리즈 · 1부 — 왜 정적 홈페이지인가 / 2부 (이 글) — 콘텐츠 3구역 대해부 / 3부 — 자동화 파이프라인 / 4부 — 커스터마이징과 관리자 패널 1부에서 “우리가 글을 쓰는 곳은 content/ 폴더뿐”이라고 했습니다. 그런데 그 안을 열어 보면 글이 아무렇게나 쌓여 있는 게 아니라, 성격이 뚜렷한 세 개의 구역으로 정돈되어 있습니다. 이번…

  • |

    Local AI 컴퓨터 간단 비교

    Local AI 컴퓨터 간단 비교 최근에 Local로 LLM을 돌리려는 여러 시도들이 있습니다. 흔히 AI PC라고 일컬어지는 컴퓨터들의 유형을 간단히 살펴보며 이해를 돕고자 내용을 정리하였습니다. 제품 기본 옵션 128GB 또는 최대 메모리 기준 일반 용도 로컬 LLM 용도 Mac mini M4 Pro 24GB Unified / 512GB, $1,399. 최대 64GB Unified / 1TB, 약 $2,199~$2,399. macOS 일반…

  • |

    토큰이 뭐길래 — AI가 글을 읽는 단위

    한 줄 요약: AI는 문장을 ‘레고 블록(토큰)’으로 쪼개서 읽는다 — 그리고 요금도 블록 개수로 낸다. AI 뉴스나 요금제 안내를 보다 보면 꼭 등장하는 단어가 있습니다. “토큰당 요금”, “100만 토큰 처리”, “토큰 한도 초과”… 지하철 토큰도 아니고, 게임 코인도 아니고. 대체 토큰이 뭐까요? AI는 글자를 못 읽습니다 의외의 사실 하나. AI는 ‘안녕하세요’라는 글자를 통째로 읽지 못합니다….

  • |

    창세기 49장: 야곱의 열두 아들 예언과 성취

    창세기 49장: 야곱의 열두 아들 예언과 성취 본문: 창세기 49:1–28 배경: 야곱이 임종 직전 애굽에서 열두 아들을 불러 모아 “후일에 당할 일”을 선포한 예언적 축복/경고 서론: 예언의 성격과 구조 창세기 49장의 야곱의 유언적 예언(בְּרָכָה, berakhah)은 단순한 개인 축복이 아니라, 열두 아들로부터 태어날 지파(族) 전체의 역사적 운명에 대한 선지자적 선포이다. 이 예언은 다음과 같은 문학적 특징을…

  • |

    바벨론 #1 – 지명에서 종말론적 상징까지

    성경의 ‘바벨론’ — 지명에서 종말론적 상징까지 1. 어원의 이중성 히브리어 בָּבֶל (Bābel). 아카드어 bāb-ili, 곧 “신(神)의 문”이라는 자칭(自稱)입니다. 그러나 창세기 11:9은 이를 **בָּלַל (bālal, 혼잡하게 하다)**과 연결하는 언어유희로 조롱합니다. 스스로 “하늘의 문”이라 부른 곳을 성경은 “뒤섞임”이라 부릅니다. 바벨론의 자기 이해와 하나님의 평가 사이의 이 간극이 이후 모든 바벨론 신학의 씨앗입니다. 2. 창세기 11 — 원형(Urbild)…

  • |

    고린도교회

    1단계: 역사적/문화적 배경 (Setting the Stage) 고린도교회는 사도 바울이 2차 전도 여행 중 약 1년 6개월간 머물며 개척한 공동체입니다(사도행전 18장). 당시 고린도는 로마 제국 아가야 지방의 수도이자, 겐그레아와 레기온이라는 두 항구를 연결하는 교통과 무역의 중심지였습니다. 막대한 부가 모이는 상업 도시였으나, 동시에 아프로디테 신전을 중심으로 한 신전 창녀 문화 등 도덕적 타락이 극심했습니다. 당대 헬라 사회에서…