TASK-002 배포 부트스트랩: 지속 가능한 SaaS를 위한 기초 공사

바이브 코딩으로 제품을 빠르게 만드는 것만으로는 실제 SaaS를 운영하기 어렵습니다. vibePulse TASK-002에서는 develop은 dev로, main은 prod로 배포되는 무중단 배포 기반을 만들고, GHCR·Infisical·rootless Podman·Caddy Blue/Green 구조를 통해 지속 가능한 개발 환경을 구축했습니다.

Share
TASK-002 배포 부트스트랩: 지속 가능한 SaaS를 위한 기초 공사
vibePulse TASK-002 무중단 배포 부트스트랩

바이브 코딩으로 제품을 만들다 보면 눈에 보이는 기능을 빨리 붙이는 데 집중하기 쉽습니다.
화면이 생기고, 버튼이 눌리고, 사용자가 바로 만질 수 있는 기능이 추가되면 확실히 제품을 만들고 있다는 느낌이 납니다.

하지만 실제 SaaS를 출시하고 운영하려면 그보다 먼저 준비해야 할 일이 있습니다.
만들어진 제품이 안정적으로 배포되고, 문제가 생겼을 때 다시 복구할 수 있고, dev와 prod가 분리된 상태로 계속 개선될 수 있는 기반입니다.

대부분의 빌드 과정에서는 이 부분이 잘 드러나지 않습니다.
기능 출시, 화면 개선, 사용자 반응은 이야기하기 쉽지만, 배포 환경을 정리하고 서버 구조를 나누고 시크릿을 분리하는 작업은 상대적으로 덜 보입니다.

저는 ● goodtek에서 vibePulse를 만들면서 단순히 “만드는 과정”만 공유하지 않으려고 했습니다.
실제 SaaS를 출시하고 운영하는 과정까지 Build in Public으로 기록하려고 했습니다.

그래서 무작정 기능부터 쌓지 않고, 먼저 기초 공사부터 진행했습니다.
이번 TASK-002는 그중에서도 꽤 큰 비중을 차지하는 작업이었습니다.

develop에 푸시하면 dev 환경으로 배포되고, main에 머지하면 production 환경으로 배포되는 구조.
그리고 배포 중에도 서비스를 멈추지 않도록 Blue/Green 방식으로 트래픽을 전환할 수 있는 구조를 만들었습니다.

아마도 여기까지가 vibePulse가 앞으로 지속 가능하게 개발되기 위한 큰 기초 공사 중 하나였다고 생각합니다.

제품을 만드는 속도보다 먼저 본 것

처음에는 저도 기능을 더 빨리 만들고 싶었습니다.
로드맵에는 만들어야 할 타스크가 있고, 제품은 아직 더 채워야 할 것이 많았습니다.

하지만 조금만 생각해보면 기능을 빠르게 만드는 것과 제품을 안정적으로 운영하는 것은 다른 문제였습니다.

기능은 만들 수 있습니다.
AI와 Cursor를 활용하면 예전보다 훨씬 빠르게 화면도 만들고 API도 붙일 수 있습니다.
문제는 그다음입니다.

만든 것을 어디에 배포할 것인지,
배포할 때 기존 서비스는 멈추지 않는지,
dev에서 검증한 것과 prod에 올라간 것이 구분되는지,
시크릿이 코드에 섞이지 않는지,
서버에서 컨테이너가 죽었을 때 다시 확인할 기준이 있는지.

이 질문들이 해결되지 않으면 기능 개발이 빨라질수록 운영 리스크도 같이 커집니다.

그래서 이번 TASK-002의 목표는 기능이 아니라 지속 가능한 배포 기반이었습니다.

바이브 코딩으로 빠르게 만드는 시대일수록, 운영 가능한 구조를 먼저 깔아두는 일이 더 중요하다고 판단했습니다.

이번 작업의 기준은 이렇게 잡았습니다.

기준

선택한 방향

이유

브랜치 전략

develop → dev, main → prod

개발과 운영 환경을 명확히 분리하기 위해

이미지 저장소

GHCR

GitHub Actions와 연결하기 쉽고 레포 흐름과 맞기 때문에

시크릿 관리

Infisical

민감 정보를 코드와 GitHub Actions 설정에서 분리하기 위해

서버 런타임

rootless Podman

Docker 없이도 컨테이너 운영이 가능하도록

트래픽 전환

Caddy Blue/Green

배포 중단 없이 upstream을 바꾸기 위해

성공 기준

/health 200

Walking Skeleton 단계에서 가장 명확한 검증 기준이기 때문에

이 표만 보면 단순한 인프라 선택처럼 보일 수 있습니다.
하지만 실제로는 앞으로 vibePulse를 어떤 방식으로 운영할지 정하는 기준이었습니다.

Walking Skeleton CD라는 목표

TASK-002에서 만들고 싶었던 것은 거창한 배포 플랫폼이 아니었습니다.
처음부터 완성형 인프라를 만들 생각도 없었습니다.

목표는 Walking Skeleton CD였습니다.

앱의 모든 기능이 완성되지 않아도, 최소한의 뼈대가 실제 서버까지 연결되는 상태.
코드를 수정하고, 브랜치에 푸시하고, 이미지가 빌드되고, 서버에 배포되고, 공개 URL에서 health check가 통과하는 상태.

이 흐름이 먼저 필요했습니다.

vibePulse TASK-002
  ├─ develop push
  │   └─ dev 환경 자동 배포
  │
  ├─ main merge
  │   └─ prod 환경 자동 배포
  │
  ├─ GHCR image
  │   ├─ dev tag
  │   └─ prod tag
  │
  ├─ server runtime
  │   └─ rootless Podman
  │
  └─ traffic switch
      └─ Caddy Blue/Green

이 구조가 생기면 그다음부터는 제품 개발 흐름이 훨씬 단순해집니다.

develop에서 작업하고 dev에서 확인합니다.
릴리즈할 준비가 되면 main으로 머지합니다.
main에 들어간 코드는 prod로 배포됩니다.

물론 실제 운영에서는 더 많은 검증 단계가 필요해질 수 있습니다.
테스트도 더 늘어날 것이고, 마이그레이션 전략도 더 정교해져야 할 것입니다.
하지만 지금 단계에서 중요한 것은 기능을 계속 쌓아도 무너지지 않는 기본 배포 경로를 만드는 것이었습니다.

develop에서 dev, main에서 prod로 이어지는 CD 흐름

dev와 prod를 분리한 이유

개인 프로젝트나 초기 SaaS에서는 dev와 prod를 대충 섞어 쓰기 쉽습니다.
특히 혼자 만들고 있으면 “일단 서버 하나에 올리고 나중에 정리하자”는 선택이 편하게 느껴집니다.

하지만 저는 이번에는 그렇게 하지 않기로 했습니다.

vibePulse는 단순한 토이 프로젝트가 아니라, 실제 출시와 운영까지 가져갈 SaaS로 보고 있기 때문입니다.
그러면 처음부터 dev와 prod의 역할을 나눠야 했습니다.

환경

역할

배포 트리거

확인 기준

dev

실험과 검증

develop push

dev URL health check

prod

실제 운영

main merge

prod URL health check

dev는 실험할 수 있어야 합니다.
prod는 조심해서 다뤄야 합니다.

이 둘이 섞이면 문제가 생겼을 때 원인을 파악하기 어려워집니다.
방금 만든 코드가 문제인지, 환경 변수가 다른지, 서버 설정이 꼬였는지, 기존 데이터와 충돌한 것인지 구분하기 어려워집니다.

그래서 이번 작업에서는 브랜치와 환경을 명확히 연결했습니다.

develop은 dev로, main은 prod로.

이 단순한 규칙이 이후 작업에서 계속 기준점이 될 것이라고 봤습니다.

시크릿은 코드 밖에 있어야 했습니다

배포 자동화를 만들면서 가장 먼저 정리한 것은 시크릿이었습니다.

GitHub Actions는 서버에 접속해야 합니다.
서버는 GHCR에서 이미지를 받아야 합니다.
앱은 DB와 Redis에 연결해야 합니다.
환경마다 공개 URL도 다릅니다.

이 값들은 전부 민감하거나 환경에 따라 달라지는 값입니다.
그래서 코드에 넣으면 안 됩니다.

이번에는 GitHub Repository Secret에는 Infisical에 접근하기 위한 최소한의 정보만 두고, 실제 배포에 필요한 값은 Infisical에서 환경별로 읽도록 구성했습니다.

GitHub Actions
  └─ Infisical 접근 정보만 보유
      └─ Infisical
          ├─ dev 환경 값
          │   ├─ dev URL
          │   ├─ dev 서버 접속 정보
          │   ├─ DB / Redis URL
          │   └─ GHCR pull token
          │
          └─ prod 환경 값
              ├─ prod URL
              ├─ prod 서버 접속 정보
              ├─ DB / Redis URL
              └─ GHCR pull token

여기서 한 번 실수가 있었습니다.

dev 배포는 통과했는데 prod 배포에서 GHCR token이 없다는 오류가 났습니다.
처음에는 배포 스크립트 문제라고 생각했습니다.
같은 스크립트인데 왜 prod에서만 실패하는지 확인했습니다.

결론은 단순했습니다.
prod 환경의 Infisical 값에 GHCR pull token이 없었습니다.

dev에 있는 값이 prod에도 자동으로 있는 것은 아니었습니다.
환경이 분리되어 있다는 것은 값도 분리되어 있다는 뜻이었습니다.

이 부분에서 배운 점은 명확했습니다.

배포 자동화에서 중요한 것은 명령어를 잘 쓰는 것이 아니라, 어떤 환경이 어떤 값을 반드시 가져야 하는지 정확히 정리하는 일이었습니다.

이후에는 dev와 prod 각각에 필요한 키를 다시 확인했습니다.
특히 GHCR 사용자, pull token, 서버 접속 정보, health check URL처럼 배포에 직접 영향을 주는 값은 환경별로 빠짐없이 있어야 했습니다.

Docker가 없는 서버에서 배포하기

이번 서버 환경은 Docker 기준이 아니었습니다.
rootless Podman을 사용했습니다.

이 부분이 생각보다 중요했습니다.

대부분의 배포 예제는 Docker를 기준으로 설명됩니다.
명령어도 Docker 중심이고, compose도 Docker 기준으로 생각하기 쉽습니다.
하지만 실제 서버가 Docker를 쓰지 않는다면 배포 스크립트도 거기에 맞춰야 합니다.

처음에는 자연스럽게 Docker 명령어를 떠올렸습니다.
그런데 서버에서는 Docker가 없었습니다.

이때 방향을 바꿨습니다.
서버에 Docker를 새로 설치하는 대신, 이미 운영 기준으로 선택한 rootless Podman에 맞게 배포 스크립트를 조정했습니다.

핵심 아이디어는 짧게 정리하면 이렇습니다.

runtime="${CONTAINER_RUNTIME:-podman}"

echo "container runtime: $runtime"

"$runtime" login ghcr.io
"$runtime" pull "$image"

"$runtime" compose \
  -f compose.prod.yaml \
  up -d --pull never

중요한 부분은 마지막 줄이었습니다.

이미지를 먼저 직접 pull하고, compose에서는 다시 pull하지 않게 했습니다.

이렇게 바꾼 이유가 있었습니다.
Podman login은 성공했지만, compose plugin에서 인증이 이어지지 않아 이미지 pull이 unauthorized로 실패하는 상황이 있었습니다.

처음에는 “로그인했는데 왜 pull이 안 되지?”라고 생각했습니다.
하지만 문제는 로그인 자체가 아니라, compose plugin이 인증 정보를 사용하는 방식에 있었습니다.

그래서 배포 흐름을 다음처럼 바꿨습니다.

  • 런타임으로 GHCR 로그인
  • 런타임으로 이미지 직접 pull
  • compose 실행 시 pull 생략
  • 이미 받은 이미지로 컨테이너 교체

이 방식으로 불필요한 실패 지점을 줄일 수 있었습니다.

Blue/Green을 넣은 이유

배포는 단순히 새 컨테이너를 띄우는 일이 아닙니다.
새 버전이 정상인지 확인하고, 문제가 없을 때 트래픽을 넘기는 일까지 포함됩니다.

그래서 TASK-002에서는 Blue/Green 방식을 넣었습니다.

blue 슬롯과 green 슬롯을 나누고, 현재 서비스 중인 슬롯이 아닌 반대 슬롯에 새 버전을 올립니다.
그다음 health check가 통과하면 Caddy가 바라보는 upstream을 새 슬롯으로 바꿉니다.

vibePulse app slots
  ├─ blue
  │   ├─ web
  │   ├─ api
  │   └─ worker
  │
  ├─ green
  │   ├─ web
  │   ├─ api
  │   └─ worker
  │
  └─ shared data layer
      ├─ postgres
      └─ redis

이번에는 슬롯별 포트도 명확히 나눴습니다.

구성

blue

green

web

3110

3210

api

3111

3211

worker

3112

3212

데이터 계층도 기존 서버의 다른 서비스와 충돌하지 않도록 분리했습니다.

구성

포트

Postgres

5433

Redis

6380

이 포트 분리가 중요했습니다.
prod 서버에는 이미 다른 서비스가 있을 수 있고, 기본 Postgres 포트가 사용 중일 수 있습니다.
그래서 vibePulse는 독립적인 포트 범위를 사용하도록 잡았습니다.

무중단 배포의 핵심은 새 버전을 띄우는 속도가 아니라, 검증된 버전으로 안전하게 트래픽을 넘기는 기준이었습니다.

Blue/Green 슬롯과 Caddy upstream 전환 구조

Caddy는 마지막 스위치였습니다

Caddy는 이번 구조에서 마지막 트래픽 스위치 역할을 했습니다.

앱 컨테이너가 blue에 떠 있든 green에 떠 있든, 사용자는 공개 URL로 접근합니다.
Caddy는 현재 활성 슬롯의 web과 api를 바라보면 됩니다.

처음에는 Caddy 설정도 단순할 거라고 생각했습니다.
하지만 실제로는 배포 스크립트가 Caddy snippet을 교체할 수 있는 구조가 필요했습니다.

그래서 메인 Caddyfile에서 사이트별 설정 경로를 import하도록 만들었습니다.

/etc/caddy
  ├─ Caddyfile
  │   └─ import /etc/caddy/sites/*
  │
  └─ sites
      └─ vibepulse.caddy

여기서 한 번 더 막혔습니다.

배포 스크립트가 Caddy snippet을 쓰려고 하는데 디렉터리가 없어서 실패했습니다.
또 어떤 경우에는 snippet은 만들어졌지만 메인 Caddyfile이 해당 경로를 import하지 않아 Caddy가 설정을 읽지 않았습니다.

겉으로 보면 TLS 문제처럼 보였지만, 실제 원인은 더 기본적인 곳에 있었습니다.

Caddy가 사이트 설정 파일을 읽고 있지 않았습니다.

이후에는 다음 기준을 배포 스크립트와 서버 설정에 반영했습니다.

  • /etc/caddy/sites 디렉터리가 없으면 생성
  • 메인 Caddyfile에서 sites 경로 import
  • snippet 생성 후 Caddy validate
  • validate 통과 후 reload
  • active slot과 upstream 포트 일치 확인

이 과정을 넣고 나니 Caddy는 단순한 reverse proxy가 아니라, Blue/Green 전환을 마무리하는 안정적인 스위치가 됐습니다.

데이터 계층에서 만난 권한 문제

앱 컨테이너보다 먼저 Postgres와 Redis를 올렸습니다.
여기서도 예상보다 시간이 걸린 부분이 있었습니다.

Postgres 데이터 디렉터리 권한 문제였습니다.

처음에는 권한 문제니까 소유자를 바꾸면 되겠다고 생각했습니다.
하지만 rootless Podman 환경에서는 그렇게 단순하지 않았습니다.

rootless 컨테이너는 호스트의 권한과 컨테이너 내부 UID 매핑이 맞아야 합니다.
무작정 호스트에서 소유자를 바꾸는 방식은 실패하거나, 유지보수하기 어려운 방향이 될 수 있었습니다.

결국 방향을 바꿨습니다.

호스트 권한을 억지로 맞추는 대신, Podman rootless 환경에 맞는 볼륨 마운트와 PGDATA 경로를 사용하는 방식으로 정리했습니다.

이 부분에서 다시 느꼈습니다.

AI가 코드를 빠르게 만들어줄 수는 있지만, 서버의 실제 권한 모델과 운영 환경은 직접 부딪혀봐야 이해됩니다.
문서와 예제만 보고는 놓치기 쉬운 부분이었습니다.

실패 목록이 곧 운영 문서가 됐습니다

이번 TASK-002에서 가장 유용했던 산출물 중 하나는 실패 목록이었습니다.
성공한 명령어보다 실패한 이유를 정리해둔 것이 나중에 더 도움이 됩니다.

증상

원인

수정한 방향

인증 방식 오류

Infisical auth method 값 불일치

실제 사용하는 인증 방식으로 수정

GHCR 사용자 값 누락

환경 변수 누락

기본 owner 값과 필수 키 정리

Docker 명령어 없음

서버에 Docker 미설치

Podman 기준으로 배포 스크립트 변경

이미지 pull 권한 오류

compose plugin 인증 전달 문제

직접 pull 후 compose는 pull 생략

Caddy snippet 생성 실패

sites 디렉터리 없음

디렉터리 생성 로직 추가

TLS 관련 오류

Caddy import 누락

메인 Caddyfile에 import 추가

prod token 누락

prod 환경 시크릿 누락

prod Infisical 값 추가

Postgres 권한 문제

rootless 볼륨 권한 불일치

볼륨 마운트와 PGDATA 경로 조정

이 표를 만들면서 작업이 더 명확해졌습니다.

처음에는 각각의 문제가 따로 떨어진 오류처럼 보였습니다.
하지만 정리해보니 대부분은 같은 흐름이었습니다.

환경이 명확하지 않거나, 런타임 기준이 맞지 않거나, 서버의 실제 구조가 배포 스크립트에 반영되지 않은 문제였습니다.

그래서 이번 작업은 단순히 오류를 고친 것이 아니라, 운영 기준을 코드와 문서에 반영하는 과정이었습니다.

최종 검증은 단순하게 잡았습니다

TASK-002의 최종 성공 기준은 일부러 단순하게 잡았습니다.

dev와 prod의 공개 URL에서 /health가 정상 응답하는 것.
그리고 서버에서 현재 active slot과 컨테이너 상태를 확인할 수 있는 것.

검증 기준은 이렇게 정리했습니다.

final check
  ├─ dev public URL
  │   └─ /health 200
  │
  ├─ prod public URL
  │   └─ /health 200
  │
  ├─ dev server
  │   ├─ active slot 확인
  │   └─ vibepulse containers 확인
  │
  └─ prod server
      ├─ active slot 확인
      └─ vibepulse containers 확인

여기서 중요한 것은 “대충 뜬 것 같다”가 아니었습니다.
브라우저에서 한 번 열어보는 정도로 끝내지 않았습니다.

다음 항목을 확인했습니다.

  • dev URL health check
  • prod URL health check
  • 서버 내부 web health check
  • 서버 내부 api health check
  • active slot 파일
  • web / api / worker 컨테이너
  • Postgres / Redis healthy 상태
  • Caddy validate
  • Caddy reload

이렇게 확인하고 나서야 TASK-002를 닫을 수 있었습니다.

결과적으로 dev와 prod 모두 /health가 정상 응답했습니다.
develop과 main의 CD 흐름도 각각 연결됐습니다.
서버는 Docker 없이 rootless Podman으로 운영할 수 있게 됐고, Caddy는 Blue/Green 슬롯을 전환할 수 있게 됐습니다.

이번 작업에서 남긴 파일들

TASK-002가 끝나면서 레포에는 앞으로 계속 사용할 배포 관련 파일들이 남았습니다.

vibepulse
  ├─ .github
  │   └─ workflows
  │       └─ cd.yml
  │
  ├─ scripts
  │   └─ deploy.sh
  │
  ├─ compose.prod.yaml
  ├─ compose.data.yaml
  │
  ├─ data
  │   └─ data.env.example
  │
  ├─ deploy
  │   └─ caddy
  │       └─ vibepulse.caddy.tmpl
  │
  └─ docs
      └─ tasks
          └─ TASK-002 관련 문서

이 파일들은 단순한 설정 파일이 아닙니다.
앞으로 vibePulse를 개발하고 배포할 때 계속 밟게 될 길입니다.

특히 deploy.sh는 이번 작업의 중심이었습니다.
현재 슬롯을 확인하고, 반대 슬롯에 새 버전을 올리고, health check를 통과하면 Caddy upstream을 바꾸는 흐름을 담당했습니다.

배포 스크립트 하나에 너무 많은 책임이 들어가지 않도록 조심해야 하지만, 지금 단계에서는 이 정도 구성이 적절하다고 봤습니다.
너무 이른 시점에 복잡한 배포 플랫폼을 붙이는 것보다, 현재 운영 기준이 명확히 드러나는 스크립트가 더 낫다고 판단했습니다.

TASK-002를 닫기 전에 정리한 체크리스트

이번 작업을 마무리하면서 다음 기준을 체크했습니다.

  • develop push 시 dev CD가 실행되는가
  • main merge 시 prod CD가 실행되는가
  • GHCR 이미지가 dev/prod 태그로 빌드되는가
  • Infisical에서 환경별 값을 읽는가
  • dev와 prod의 시크릿이 분리되어 있는가
  • 서버에서 rootless Podman으로 앱이 실행되는가
  • Postgres와 Redis가 별도 포트로 실행되는가
  • Blue/Green 슬롯 전환이 가능한가
  • Caddy가 active slot을 바라보는가
  • dev와 prod 모두 /health가 정상 응답하는가

이 체크리스트를 통과하고 나서야 “이제 로드맵에 있는 타스크를 계속 개발해도 되겠다”는 생각이 들었습니다.

배운 점

이번 작업에서 가장 크게 느낀 것은, SaaS는 기능만으로 운영되지 않는다는 점이었습니다.

기능은 제품의 앞면입니다.
배포, 시크릿, 서버, 런타임, health check, 로그, 복구 기준은 제품의 뒷면입니다.

사용자는 보통 뒷면을 보지 않습니다.
하지만 뒷면이 약하면 앞면도 오래 버티기 어렵습니다.

특히 AI와 바이브 코딩으로 개발 속도가 빨라질수록, 운영 기반의 중요성은 더 커진다고 느꼈습니다.
코드를 빨리 만들 수 있다는 것은 좋은 일입니다.
하지만 그 코드가 어디에 올라가고, 어떻게 검증되고, 문제가 생기면 어떻게 되돌릴지 정하지 않으면 속도는 곧 불안정함이 될 수 있습니다.

이번 TASK-002는 그 속도를 감당하기 위한 기반을 만든 작업이었습니다.

무작정 만드는 대신, 계속 만들 수 있는 구조를 먼저 만들었습니다.

이제 진짜 제품 개발로 들어갑니다

TASK-002를 마치고 나니 vibePulse의 길이 조금 더 선명해졌습니다.

이제 develop에 작업을 쌓고 dev에서 확인할 수 있습니다.
main으로 머지하면 prod에 반영할 수 있습니다.
배포는 수동 작업이 아니라 반복 가능한 흐름이 됐습니다.

물론 아직 갈 길은 많습니다.
앞으로 기능 개발을 하면서 또 다른 문제가 나올 것입니다.
DB 마이그레이션, 장애 대응, 모니터링, 로그, 백업, 사용자 피드백, 과금 구조까지 계속 다뤄야 할 것들이 남아 있습니다.

하지만 이번 기초 공사가 없었다면 그다음 작업들은 계속 불안한 상태로 쌓였을 것입니다.

● goodtek은 vibePulse를 포함해 AI 자동화와 SaaS를 실제로 만들고 운영하는 과정을 계속 공개할 예정입니다.
잘된 부분만 정리하지 않고, 막힌 부분과 돌아간 이유도 함께 남기려고 합니다.

Build in Public은 완성된 결과를 자랑하는 방식이 아니라, 만들어가는 과정을 함께 볼 수 있게 열어두는 방식이라고 생각합니다.

이 여정에 관심 있는 분들은 언제든 함께 지켜봐 주시면 좋겠습니다.
비슷한 제품을 만들고 있거나, AI로 SaaS를 만들고 있거나, 혼자 제품을 운영해보고 싶은 분들도 환영합니다.

저도 계속 만들면서 배우고, 배운 것을 다시 기록하겠습니다.

Read more

AI와 함께 코딩할 때 먼저 배운 것: 만든 것과 만들려던 것을 구분하기

AI와 함께 코딩할 때 먼저 배운 것: 만든 것과 만들려던 것을 구분하기

AI와 함께 코딩하면 계획, 프롬프트, 문서, 실제 코드가 쉽게 섞입니다. 이번 TASK-013에서는 공개 상태 페이지를 만들려 했지만, 실제로 ship된 것은 실시간 대시보드, 알림 테스트 상태 추적, 디자인 정합 작업이었습니다. 이번 글에서는 TASK 이름보다 머지된 코드를 기준으로 사실을 검증한 과정과, Realtime 아키텍처·비동기 상태 모델·공통 계약 관리 등 AI와 함께 개발할 때 놓치기 쉬운 기준들을 정리합니다. Build in Public 관점에서 ‘만들려던 것’과 ‘실제로 만든 것’을 구분하는 방법을 공유합니다.

By ● goodtek
감지 → 판단 → 알림: vibePulse의 심장을 만든 6개의 TASK

감지 → 판단 → 알림: vibePulse의 심장을 만든 6개의 TASK

goodtek이 만들고 있는 vibePulse는 "내가 만든 웹/API가 지금 살아 있는가"를 확인하고, 죽으면 즉시 알려주는 초간단 생존 확인 SaaS입니다. 이번 글은 그 핵심 파이프라인 — 모니터를 만들고(TASK-006), 주기적으로 찌르고(007), 장애를 판단하고(008), 신호가 끊기면 알아채고(009), 알림을 큐에 태워(010), 슬랙·카카오톡으로 보내기까지(011) — 를 한 호흡에 만든 기록입니다.

By ● goodtek