소개
지원 서비스 가용성 엔드포인트가 정상적으로 작동하다가 새 릴리스 이후 503 을 반환하기 시작했습니다. 이 실습에서는 일회용 Worker 의 두 버전을 모두 게시하고, 활성 버전을 확인한 다음, 정상 동작이 확인된 릴리스로 복원합니다. 업로드 성공 메시지만 신뢰하지 않고 실제 HTTP 동작과 Cloudflare 배포 메타데이터를 비교합니다.
로컬 Wrangler 개발, 계정 인증 및 배포 방법을 이미 이해하고 있어야 합니다. 새 VM 에서 본인의 학습 계정으로 시작하며, 이전 VM 이나 Worker 는 재사용하지 않습니다. 설정 과정에서 Node.js 22.22.0 과 프로젝트 로컬 Wrangler 4.131.1 을 설치하고, 작은 합성 핸들러 fixture 두 개를 제공합니다. 도메인, 스토리지 서비스 또는 시크릿은 필요하지 않습니다. 모든 배포와 정리 작업은 직접 수행합니다.
버전은 변경할 수 없는 코드/구성 스냅샷입니다. 배포는 어떤 버전으로 트래픽을 보낼지 선택합니다. 롤백은 기존 버전으로 새 배포를 생성하며, 로컬 소스 파일을 다시 작성하거나 바인딩된 리소스의 데이터를 복원하지 않습니다. 자세한 내용은 공식 버전 개요를 참조하세요.
정상 동작이 확인된 릴리스 준비
이 단계에서는 정상 동작이 확인된 엔트리포인트를 준비하고 로컬에서 동작을 확인합니다. 제공된 fixture 를 사용하므로 릴리스 작업에 집중할 수 있습니다. 정상 핸들러는 available=true 를 반환하고, 오류 핸들러는 health 상태는 유지하지만 비즈니스 경로에 503 을 반환합니다.
cd /home/labex/project/release-recovery
cat versions/good.js
diff -u versions/good.js versions/faulty.js
두 파일이 다르므로 diff 명령은 1 로 종료됩니다. 이는 예상된 결과입니다. 변경되는 것은 availability 값과 HTTP 상태뿐입니다. 정상 fixture 를 복사하면 구성에서 지정한 소스 파일이 선택됩니다.
cp versions/good.js src/index.js
Node 의 표준 crypto API 를 사용해 고유한 이름을 생성합니다. 아래의 따옴표 없는 EOF 구분자는 셸 변수를 JSON 에 삽입합니다. 파일에는 주석이 없으므로 표준 JSON 리더로도 확인할 수 있습니다.
WORKER_NAME="labex-release-$(node -p "require('node:crypto').randomBytes(6).toString('hex')")"
cat > wrangler.jsonc <<EOF
{
"name": "$WORKER_NAME",
"main": "src/index.js",
"compatibility_date": "2026-07-30",
"workers_dev": true,
"preview_urls": false,
"version_metadata": {"binding": "RELEASE"}
}
EOF
버전 메타데이터 바인딩은 런타임 버전 ID 와 태그를 제공합니다. 로컬 개발에서는 로컬 메타데이터를 사용하며, 배포된 메타데이터만 클라우드 버전을 식별합니다. 이 바인딩에 대한 문서는 여기에서 확인할 수 있습니다.
&를 사용해 로컬 서버를 백그라운드에서 시작하고 출력을 dev.log 로 리디렉션합니다. 요청을 보내기 전에 Ready 가 표시될 때까지 기다립니다.
npx wrangler dev --ip 0.0.0.0 --port 8080 > dev.log 2>&1 &
cat dev.log
curl -i http://127.0.0.1:8080/health
curl -i http://127.0.0.1:8080/api/availability
두 경로 모두 200 을 반환해야 하며 availability 는 true 여야 합니다. 로컬 버전과 태그 값은 개발용 임시 값일 수 있습니다. 다음 단계에서 개발 작업을 중지하기 전에 검증을 실행합니다.
정상 버전 배포 및 기록
이 단계에서는 정상 동작이 확인된 소스를 학습 계정에 배포하고 실제 버전을 기록합니다. 현재 작업 번호가 다르면 그 번호로 바꾸어 로컬 작업을 중지합니다.
jobs
kill %1
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_tail:read
출력된 디바이스 링크를 브라우저에서 열고 코드를 입력한 다음, 사용할 학습 계정을 인증합니다. 인증 정보는 로그인 흐름에 입력합니다. 계정이 하나만 표시되더라도 표준 계정 출력에서 이름을 읽고 확인합니다.
npx wrangler whoami --json
아래의 YOUR_ACCOUNT_ID 를 해당 계정의 실제 ID 로 바꿉니다. 이 표준 Node 명령은 프로젝트의 명시적 구성 파일을 수정하며, 임시 환경 변수로 계정을 선택하지 않습니다.
node -e 'const fs=require("node:fs");const p="wrangler.jsonc";const c=JSON.parse(fs.readFileSync(p));c.account_id="YOUR_ACCOUNT_ID";fs.writeFileSync(p,JSON.stringify(c,null,2)+"\n");'
cat wrangler.jsonc
태그는 읽기 쉬운 레이블이고, 버전 UUID 는 정확한 식별자입니다. 배포하면 버전이 업로드되고 해당 버전으로 트래픽이 전달됩니다. 메시지는 해당 버전의 용도를 설명합니다.
npx wrangler deploy --tag good --message "Known-good availability"
출력된 workers.dev URL 과 Current Version ID 를 다음 명령에 입력합니다. 아래 값은 예시용 자리 표시자이며, 고정된 공유 리소스가 아닙니다. 계정에 workers.dev 서브도메인이 없다면 Deploy Your First Cloudflare Worker 의 초기 설정을 수행한 후 배포를 다시 실행합니다.
APP_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
printf '%s\n' "YOUR_GOOD_VERSION_ID" > good-version.txt
curl -i "$APP_URL/api/availability"
npx wrangler deployments status
npx wrangler versions list
응답에서 200, available=true, tag=good 및 기록한 버전 UUID 가 표시되어야 합니다. 활성 배포는 해당 버전에 트래픽의 100% 를 할당해야 합니다. Dashboard 에서 이 정확한 Worker 를 열고 Deployments 를 확인하여 CLI 에 표시된 버전 및 활성 배포와 실제 리소스를 연결해 확인합니다. 배포 직후 응답에 이전 상태가 계속 표시되면 5 초간 기다린 후 최대 1 분 동안 읽기 작업을 반복합니다. 전파 지연을 숨기기 위해 코드를 변경하지 마세요. 관찰 결과가 일치한 후 검증을 실행합니다.
오류가 있는 릴리스 확인
이 단계에서는 일회용 Worker 에서 제어된 릴리스 회귀를 재현합니다. liveness 엔드포인트가 정상이라고 해서 비즈니스 경로도 정상이라는 뜻은 아닙니다. 엔트리포인트를 오류 fixture 로 바꾸고, 다른 태그가 지정된 버전을 게시합니다.
cp versions/faulty.js src/index.js
npx wrangler deploy --tag faulty --message "Demonstrate availability regression"
이 배포의 새로운 Current Version ID 를 저장합니다. 정상 버전 ID 를 저장하면 안 됩니다. 두 경로와 현재 배포를 확인합니다.
printf '%s\n' "YOUR_FAULTY_VERSION_ID" > faulty-version.txt
curl -i "$APP_URL/health"
curl -i "$APP_URL/api/availability"
npx wrangler deployments status
npx wrangler versions list
Health 는 계속 200 을 반환합니다. Availability 는 이제 503, available=false 및 tag=faulty 를 반환해야 합니다. 런타임 UUID 는 새 활성 버전과 일치하고, 해당 버전에 트래픽의 100% 가 할당되어야 합니다. 이 단계에서 503 은 의도한 결함이며 검증을 건너뛸 이유가 아닙니다. 전파가 진행 중이면 동일한 제한된 응답 재확인을 적용합니다. 독립적인 확인을 수행하려면 복구 전에 결함이 실제로 관찰되어야 합니다.
Compute → Workers & Pages에서 정확한 Worker 를 열고 Deployments를 선택합니다. Active deployment 아래의 ID 를 Version History에서 faulty 태그가 붙은 행과 비교합니다. 스크린샷에는 축약된 예시 UUID 가 표시되어 있으므로, 명령에는 저장한 전체 UUID 를 사용합니다. 오류 버전이 활성 상태인 동안에도 정상 버전은 기록에 남아 있습니다. 위의 wrangler deployments status를 사용해 구성된 트래픽 100% 할당을 확인합니다. 이 조용한 스크린샷에 표시된 0 값의 활동 수치는 비즈니스 경로가 정상이라는 증거가 아닙니다.

롤백 및 로컬 소스 동기화
이 단계에서는 정확히 정상 동작이 확인된 버전으로 복원합니다. 저장한 ID 를 읽고 트래픽을 변경하기 전에 선택한 정상 버전을 확인합니다. 셸 명령 치환은 파일에서 UUID 를 읽을 뿐이며, 새 버전을 업로드하지 않습니다.
cat good-version.txt faulty-version.txt
npx wrangler versions view "$(cat good-version.txt)"
정상 태그, 대상 Worker 와 계정, UUID 가 올바른지 확인합니다. 롤백하면 이 일회용 Worker 의 트래픽 100% 가 해당 버전으로 전달됩니다. 메시지에는 복구 이유가 기록됩니다. 대상을 확인한 후에만 명령을 실행합니다.
npx wrangler rollback "$(cat good-version.txt)" --message "Restore known-good availability"
Wrangler 가 선택적 메시지를 입력하라고 요청하면 Enter 키를 눌러 Restore known-good availability 를 수락합니다. 표시된 정상 UUID 와 트래픽 100% 대상을 확인한 다음, 일치하는 확인 단계에서 y 키만 누릅니다. 계속하기 전에 롤백 성공 메시지가 표시될 때까지 기다립니다.
npx wrangler deployments status
curl -i "$APP_URL/api/availability"
새 배포는 원래 정상 버전 UUID 를 사용해야 하지만, 원래 배포 ID 와 같을 필요는 없습니다. Availability 는 다시 200 과 true 를 반환해야 합니다. Dashboard 의 Deployments 탭을 새로 고치고 활성 UUID 를 비교합니다. 필요한 경우 동일한 1 분 제한의 응답 재확인을 수행합니다.
이 예에서는 Active deployment가 원래 good 버전과 같은 축약 ID 인 7afe5d31로 돌아갑니다. Version History의 활성 표시도 해당 행으로 이동하고, 오류 버전은 계속 목록에 남아 있습니다. 자신의 ID 를 사용해 이러한 관계를 확인하고 예시 값을 복사하지 마세요. 이 페이지는 선택된 버전을 보여주며, availability 응답은 동작이 복구되었음을 확인합니다.

롤백해도 로컬 소스는 변경되지 않습니다. 이후 일반 배포에서 알려진 결함이 실수로 다시 도입되지 않도록 정상 fixture 를 로컬에 복원합니다. Dry-run 은 로컬 소스를 번들로 만들지만 업로드하지는 않습니다.
cp versions/good.js src/index.js
npx wrangler deploy --dry-run
검증을 실행합니다. 검증은 실제 런타임 UUID 와 태그를 현재 트래픽 100% 배포와 비교하고, 이전 오류 배포가 기록에 남아 있는지도 확인합니다. 로컬에 작성한 성공 파일만으로는 충분하지 않습니다.
롤백은 데이터베이스, 큐 또는 외부 API 에 기록한 내용을 되돌리지 않습니다. 또한 바인딩된 리소스의 변경으로 인해 이전 버전이 호환되지 않을 수 있습니다. 이 실습에는 이러한 리소스가 없습니다. 실제 장애에서는 복구 전에 이러한 경계를 평가해야 합니다. 롤백 문서에서 제한 사항과 유지되는 버전 기간을 설명합니다.
릴리스 테스트 Worker 삭제
이 단계에서는 인증이 유지되는 동안 일회용 Worker 를 삭제합니다. 삭제하기 전에 정확한 이름과 계정을 확인합니다.
cat wrangler.jsonc
npx wrangler delete
이름이 일치하는 프롬프트에서 y 키만 누릅니다. 고정된 Wrangler 는 Worker 를 삭제한 후 레거시 KV 정리 인증 오류를 보고할 수 있습니다. 더 넓은 권한 범위를 부여하거나, 오류가 발생했다는 이유만으로 삭제가 완료되었다고 판단하지 마세요. Dashboard 를 새로 고치고 검증을 실행합니다. 인증된 인벤토리에 이 Worker 가 없음을 확인해야 합니다. 학습 계정, 서브도메인 및 관련 없는 리소스는 유지합니다.
VM 연결 해제
이 단계에서는 삭제가 완료된 후 VM 의 연결을 해제합니다. 로그아웃만으로는 배포된 Worker 가 삭제되지 않습니다.
npx wrangler logout
npx wrangler whoami --json
loggedIn=false 가 표시되어야 합니다. 이제 인증되지 않은 상태이므로 구조화된 명령은 0 이 아닌 종료 코드를 반환할 수 있습니다. 최종 검증을 실행합니다. 브라우저 로그인과 학습 계정은 이후 독립적인 실습에서도 계속 사용할 수 있습니다.
요약
Worker 버전과 활성 배포를 비교하고, liveness 가 정상인데도 비즈니스 경로에서 회귀가 발생하는 상황을 확인한 다음, 선택한 정상 버전으로 복원했습니다. 런타임 메타데이터를 사용해 실제 응답을 트래픽 100% 배포와 연결했습니다. 또한 로컬 소스를 복원하고, 클라우드 정리를 확인하고, VM 의 연결을 해제했습니다.

