Blue/Green Deploy (frame)
AI 요청 프롬프트
https://docs.axelabs.ai/ops/runbook/deploy 따라 frame [customer] Blue/Green 배포해줘.
진행:
1. 현재 active color 확인 (`docker exec axe-frame-proxy` + network alias) + git log origin/main..HEAD 변경 미리보기
2. 자동 경로 (`axe deploy frame {customer} --apply`) 가능 판단, 안 되면 수동 9 step 분기
3. 페이지의 각 step 실행 + 매 step 결과 받고 다음. 특히 alias swap 직전 사용자 확인 (passive health 60s 통과 검증 후) + 기존 active stop 전 60s grace 대기
4. 함정 발생 시 페이지 본문 따라 우회 (health check 60s timeout / in-flight grace 미준수 / mcp-proxy upstream 미반영)
5. 새 active 첫 요청 검증 (`curl https://axe.axelabs.ai/frame/health` 200) + (선택) /ops/updates Ship Log본인 AI session = Claude Code / Cursor / ChatGPT 데스크탑 / Claude.app / 기타.
페이지 본문 = 사람이 직접 read 도 가능, AI 도 참고. AI 가 본 페이지 fetch 후 위 진행 순서대로 사용자와 step-by-step interactive 풀어나감.
다운타임 0 으로 frame 새 코드 적용.
자동 (권장)
# Dry-run 으로 변경사항 미리 확인
axe deploy frame axe
# 실제 적용
axe deploy frame axe --applyaxe deploy frame {customer} 가 자동으로 처리:
| Step | 작업 |
|---|---|
| 1 | git pull origin main |
| 2 | passive container 의 새 코드로 build (예: green 이 passive 면 green build) |
| 3 | passive container start |
| 4 | 헬스체크 통과 대기 (poll /health/ready, max 60s) |
| 5 | docker network alias frame-mcp 이동 (active → passive) |
| 6 | 새 active 의 첫 요청 정상 처리 검증 |
| 7 | 기존 active (현재 passive) 의 in-flight 요청 60s grace |
| 8 | 기존 active stop |
| 9 | 운영자에게 deploy 완료 알림 |
총 5-7 분 (build 시간 포함). 사용자 측 다운타임: 0.
수동 (응급, axe CLI 사용 불가 시)
1. 현재 active color 확인
docker exec axe-frame-proxy cat /etc/caddy/Caddyfile # mount 위치 (frame-proxy/docker-compose.yml 의 :ro) | grep upstream
# 또는
docker network inspect frame_default | grep -A 2 'frame-mcp"'
# Aliases 에 `frame-mcp` 표시된 컨테이너가 activeactive = blue 가정.
2. green 에 새 코드 build
cd /Users/axe/frame
git pull origin main
set -a && source .env.local && set +a
docker compose build frame-mcp-green
docker compose up -d --force-recreate frame-mcp-green3. green health check
sleep 10
curl -s http://localhost:3711/health/ready
# → {"status":"ok"}4. alias 이동 (blue → green)
# blue 에서 alias 제거
docker network disconnect frame_default frame-mcp-blue
docker network connect frame_default frame-mcp-blue # alias 없이 다시
# green 에 alias 부여
docker network disconnect frame_default frame-mcp-green
docker network connect --alias frame-mcp frame_default frame-mcp-green위 절차는 axe-frame-proxy 의 upstream resolution 이 즉시 갱신. Caddy 가 alias 기반이라 DNS 캐시 없음.
5. axe-frame-proxy 갱신 확인
docker exec axe-frame-proxy cat /etc/caddy/Caddyfile # mount 위치 (frame-proxy/docker-compose.yml 의 :ro) | grep frame-mcp
# upstream 이 frame-mcp:3710 그대로 (alias 가 green 으로 이동)6. blue 의 in-flight 요청 완료 대기 + stop
sleep 60 # in-flight grace
docker stop frame-mcp-blue
# 다음 deploy 시 새 코드로 build 됨 (현재 passive)검증
# 외부 호출 확인
curl -s https://axe.axelabs.ai/frame/health
# → 200 OK + service: frame-mcp
# 새 코드 버전 확인
docker exec frame-mcp-green python -c "import frame; print(frame.__version__)"Rollback (5초)
문제 발견 시 alias 만 되돌리면 끝:
docker network disconnect frame_default frame-mcp-green
docker network connect frame_default frame-mcp-green
docker network connect --alias frame-mcp frame_default frame-mcp-blueblue 가 다시 active. 새 코드는 green 컨테이너에 그대로 (다음 시도 시 fix 후 재배포).
함정
| 함정 | 결과 | 회피 |
|---|---|---|
docker compose up --build 단일 컨테이너로 (블루든 그린이든) | 30-60s 다운타임 | blue+green 동시 운영 필수 |
--force-recreate 없이 env 변경 적용 | 새 env 안 읽음 | 항상 --force-recreate |
| customer macmini 에 docker daemon 죽음 | proxy 도 죽음 | launchctl kickstart 로 docker 재시작 |
| build 실패 (Dockerfile 오류) | passive 컨테이너 stop | git revert + 재시도, blue 는 영향 없음 |
다른 서비스
- blueprint — 단일 컨테이너, 짧은 다운타임 수용 (
docker compose up -d --force-recreate blueprint) - vault (Vaultwarden) — 단일 컨테이너, 다운타임 시 사용자 vault 로그인 불가 (rare op, 야간 작업)
- stream / magnet — 각 customer 측 자체 운영
Last updated on