-
hanyul released this
2026-10-15 08:23:55 +09:00 LINKS 1.0.8
이 hotfix 릴리스는 이전 릴리스 1.0.7(
3f6c504352) 위에 PostgreSQL 최초 기동 healthcheck 수정만 얹었습니다. 최종 소스는9f4ada7c6c, 루트 패키지는 1.0.8, ARCA pin은 exact 0.1.18로 그대로입니다. 1.0.7에서 첫sh backup.sh가[6/8] Restoring into a fresh database and empty volumes에서FATAL: database "links" does not exist로 실패할 수 있던 race를 고쳤습니다. schema는 바뀌지 않았습니다. DB 초기화와 migration이 필요 없습니다. backup 형식도 그대로입니다.업그레이드 주의: 1.0.7 → 1.0.8은
sh update.sh만 실행하고, 설치 뒤sh backup.sh로 backup을 한 번 만들어 둡니다- 대상·원인·수정: 공식 PostgreSQL image는 빈 data 디렉터리의 최초 기동에서 socket만 여는 임시 서버로
POSTGRES_DB를 만든 뒤 최종 서버로 다시 시작합니다. 기존 healthcheck(socketpg_isready)는 DB가 만들어지기 전의 임시 서버에서 이미 통과하므로compose up --wait가 너무 일찍 돌아왔습니다. 그래서backup.sh의 복구 검증(별도 projectlinks-backup-verify의 빈verify-postgres)이 느린 디스크에서 DB 생성 전에 접속해[6/8]에서 실패할 수 있었습니다(BACKUP_EXIT=2, pin 해제,report.json없음). 이제 rootcompose.yaml의postgres와ops/backup-verify.compose.yaml의verify-postgreshealthcheck가 TCP127.0.0.1pg_isready(임시 서버는 TCP를 열지 않음)와 대상 DB의 실제 쿼리(psql … select 1)를 함께 요구합니다. 같은 수정이 운영postgres의 최초 기동(reset.sh뒤migration의service_healthy대기)에도 적용됩니다. healthcheck 설정이 바뀌므로 갱신 때postgrescontainer가 한 번 다시 만들어집니다(data는 그대로). 격리 gate에서 이전 container 종료부터 새 container healthy까지 약 5.3초(새 container 시작 → healthy 약 5.1초) 동안 PostgreSQL을 쓸 수 없었습니다. 실제 NAS의 중단 시간은 측정하지 않았습니다. - 갱신 방법: 배포 디렉터리에서
sh update.sh만 실행합니다. schema는 바뀌지 않았고(infra/schema·infra/migrations·.env.example이 1.0.7과 같고 migration은 0개)reset.sh를 실행하지 않습니다. 배포 파일 중compose.yaml과ops/backup-verify.compose.yaml이 바뀌며update.sh가 둘 다 받아 설치합니다. 1.0.8 설치 뒤 coordinator를 멈추고sh backup.sh로 backup을 한 번 만들어 둡니다(운영 가이드 '운영 backup 명령'). 다음 1.0.9는 schema migration(게스트 공유 링크)을 포함하므로 그 전의 pre-update backup이 필요합니다. 1.0.7에서 실패한 backup 디렉터리(report.json없음)는 복구에 쓰지 않습니다. - 결과(R54 P3 수정과 NAS 조건 gate): 리뷰 R54의 P3(회귀 runner가
00같은 인자로 검증 0회에도 PASS를 출력하던 문제)를 고쳤습니다.tests/run-postgres-init-race.sh가 반복 횟수와 지연을 선행 0 없는 양의 정수로만 받고0·00·01·숫자 아님은 Docker 변경 전에 exit 2로 거부합니다. 릴리스 전에 격리docker:24.0.2-dind(공식 Docker Compose v2.20.1, stager 1026:100, library 최상위0:0 000+ 1026 ACL)에서 1.0.7 배포에 합성 VX Ace(rgss-wasm, ARCA 0.1.18)·MZ(web-static) ready build와 로그인 사용자의 세이브를 만든 뒤, 복구 검증verify-postgres의 최초 기동에 15초+15초 init 지연을 넣었습니다. 1.0.7backup.sh는 운영과 같이[6/8]에서database "links" does not exist로 실패했고(RED), 설치된 1.0.7update.sh로 1.0.8에 갱신한 뒤 같은 지연에서backup.sh가 8단계와 fresh restore drill을 모두 통과했습니다(아래 검증). Synology build(v2.20.1-6047-g6817716)와 실제 NAS 재현은 확인 전입니다.
NAS 절차(1.0.7에서):
cd /volume1/docker/links sh update.sh docker compose --env-file .env.production --profile runtime stop runtime-package-coordinator sh backup.sh docker compose --env-file .env.production --profile runtime up -d --no-build runtime-package-coordinatorupdate.sh가 성공하면 단계 표시 6줄 뒤에Updated to 1.0.8 (catalog 6f8cb1a5d406), runtime.package ready.가 출력됩니다.backup.sh는[1/8]부터[8/8]까지 출력한 뒤Backup <id> PASS. Copy the whole directory off-host and keep it at least 30 days.로 끝나고, 실패하면 원인 한 줄을 출력하고 nonzero로 끝납니다. 복구 검증 단계([6/8])는 이제 새 PostgreSQL의 최초 init이 끝날 때까지 기다리므로 1.0.7보다 길어질 수 있습니다. backup 디렉터리 전체를 off-host로 복사해 둡니다.원본 game library는 읽기 전용으로 유지합니다. 이번 게시 작업에서 개발·운영 DB 초기화나 NAS 배포는 실행하지 않았습니다.
수정 내용
compose.yamlpostgres,ops/backup-verify.compose.yamlverify-postgres: healthcheck를pg_isready -q -h 127.0.0.1 -p 5432 -U … -d …와PGPASSWORD=… psql -h 127.0.0.1 … -v ON_ERROR_STOP=1 -qAt -c "select 1"로 바꿨습니다. 비밀번호는 container 환경 변수 참조($${POSTGRES_PASSWORD})로만 쓰며 렌더링된 설정에 값이 들어가지 않습니다. interval·timeout·retries·start_period, image pin, read_only·user·tmpfs·network는 그대로입니다.tests/run-postgres-init-race.sh(신규 gate)와tests/postgres-init-race/(test 전용 entrypoint·override): 같은 PostgreSQL image의 entrypoint를 그대로 쓰면서 DB 생성 전과 임시 서버 종료 전에 지연을 넣어 두 service를 빈 volume으로 기동하고,up --wait가 돌아온 즉시 TCP·socket 쿼리·init 완료를 요구합니다. 1.0.7 healthcheck는 FAIL(RED), 수정 뒤 PASS입니다. 반복 횟수·지연 인자 검증(R54 P3)을 함께 고쳤습니다.- 바꾸지 않은 것:
backup.sh(ops/backup-registry.sh)와 restore 수락 규칙, backup 형식, schema·migration, application 코드, ARCA pin.
문서
- 운영 가이드 '운영 backup 명령': 1.0.7 이하
[6/8]실패의 증상·원인·조치와 수정 배포 파일 - 완료 기준선(운영 backup 행·검증), tests README(runner 색인
run-postgres-init-race.sh와 인자 규칙, test 전용 override, 변경별 검증 선택)
알려진 제한(후속 과제)
- 실제 NAS에서 1.0.7
[6/8]실패의 재현과 1.0.8의backup.sh·복구, 갱신 때 PostgreSQL 재생성의 실제 중단 시간은 NOT RUN입니다. 배포 뒤 운영자가 위 절차로 backup을 만들고report.json의executionStatus·restore·evidence를 확인합니다. - 1.0.9 예고: 관리자 공유 링크 게스트 재생(schema migration 포함), ARCA 0.1.19(모바일 고 DPR 배율), 게스트 catalog 차단. migration이 있으므로 1.0.9 갱신 전에 이 릴리스의 backup이 있어야 합니다.
- 1.0.7과 같은 제한: 실제 Cloudflare 경유 artifact header, VX Ace 실제 browser acceptance, Synology 실제 환경의 갱신, PowerShell coordinator 전체 실행은 NOT RUN입니다.
update.sh는 network가 빠진 container를 스스로 감지하지 않습니다.
검증과 남은 범위
- PASS: 소스 gate(1.0.7 base, 리뷰 R54 '병합 가능')
run-postgres-init-race.sh 10(init 15초+15초 지연): 10회 모두 두 service가 healthy가 된 즉시 사용 가능(20/20, healthy 33–37초). 1.0.7 healthcheck의 RED(healthy 3–6초 뒤database "<name>" does not exist)는 수정 과제(T54)의 기록을 재사용했습니다.- R54 P3: 수정 전
00은 검증 0회로 PASS와"rounds":00을 출력했습니다(정적 확인). 수정 뒤 반복 횟수00·01·0·abc·007·1x와 지연00·015·0·abc가 Docker 변경 없이 exit 2,1·10은 정상 실행. run-ops-backup.sh: Player lock 충돌 fail closed, 8단계, fresh restore drill, rgss-wasm build 복구, save history, evidence 3.run-backup-restore.shphase-0 drill: 11개 항목 모두 PASS(rgss-wasm active generation과 web-static 포함).- static(Prettier·ESLint·typecheck·docs-static), 문서 검사,
git diff --check, reset 기록기 30·deploy 기록기 93 synthetic case, Compose config 3조합 Watchtower label(20·20·32)과 restore drill 렌더링(2). - schema gate:
infra/schema·infra/migrations변경 없음이라 NOT RUN.
- PASS: 릴리스 gate(Compose v2.20.1, NAS 조건)
- 환경: 격리
docker:24.0.2-dind, host Compose는 공식 v2.20.1 linux-x86_64 binary(release의 게시 checksum과 일치). 합성 CA의 HTTPS release 서버가 Gitea를, 합성 TLS registry가git.2ex.dev를 대신했고, registry에는 실제 1.0.7 image와 이 릴리스의 1.0.8 image를 넣었습니다. 배포 파일은 1.0.7 tag와 이 릴리스 커밋의 Git blob입니다. - 1.0.7 설치 →
reset.sh→update.sh: 12개 service, network 불일치 0, 모두 Watchtower 제외, readiness PASS. 합성 VX Ace(rgss-wasm, ARCA 0.1.18) ready, MZ ready, 로그인 사용자 세이브 201·북마크 1. - 복구 검증
verify-postgres에만 test 전용 init 지연(15초+15초)을 Docker PATH shim으로 넣었습니다(배포 파일은 release와 byte 동일). 1.0.7backup.sh: drill postgres가 3초 만에 healthy →[6/8]database "links" does not exist, exit 2, pin 해제, report 없음(RED, 운영 증상과 동일). - 1.0.8 게시 뒤 설치된 1.0.7
update.sh: exit 0(65초),Pending migrations줄 0,Updated to 1.0.8 (…), runtime.package ready., 7개 파일이 1.0.8과 같고.tmp0.postgrescontainer 재생성(ID 변경, 새 healthcheck 적용, 새 container 시작 → healthy 5.1초). 12개 service, network 불일치 0, unhealthy 0, 12/12 Watchtower 제외, readiness PASS, catalog·Player 1.0.8. schemacurrent(migration 0), row count 불변, 같은 사용자의 세이브 ETag·bytes·Player save 파일 목록 동일, VX Ace 0.1.18 buildready·active 유지, MZready. - coordinator 정지 → 같은 지연에서
sh backup.sh(1.0.8): exit 0(46초). drill postgres는 두 지연과 init 완료까지 31초 기다린 뒤 healthy,[1/8]–[8/8],Backup <id> PASS,report.jsonexecutionStatusPASS, restore drill schemacurrent·migration 0,runtimeBuilds2(rgss-wasm + web-static), runtime snapshot 78 files, save 1 namespace·2 files, evidence 2 build, active pin 0, verify project 잔여 0. - coordinator 재기동(7초 뒤 새 ready 줄) → 재-update: exit 0(34초), 배포 파일 불변,
postgres재생성 없음, 12 service 불일치 0, readiness PASS. - PostgreSQL 재생성 시간(같은 배포에서 1.0.7 → 1.0.8 healthcheck 설정 전환을 live event로 측정): 이전 container 종료 → 새 container 시작 0.22초, 시작 → healthy 5.07초, 합계 약 5.3초.
- 환경: 격리
- PASS: 최종 1.0.8 소스. 릴리스 커밋 두 개(root version, 완료 기준선의 version 문구) 뒤 문서 검사, static,
git diff --check를 다시 통과했습니다. - 게시 이미지: 같은 최종 소스에서 build했고 gate도 이 image로 실행했습니다. image 안에서 root version 1.0.8, ARCA pin·설치본 0.1.18, migration 0개를 확인했습니다.
- NOT RUN: 실제 NAS 재현·backup·복구와 1.0.7 → 1.0.8 갱신, 브라우저 matrix(변경은 PostgreSQL healthcheck뿐), live provider.
배포 이미지와 파일
- Git annotated tag는 1.0.8이고 최종 소스는
9f4ada7c6c입니다(branchrelease-1.0.8, 1.0.7 base). - 단일 linux/amd64 이미지:
git.2ex.dev/hanyul/links:1.0.8=git.2ex.dev/hanyul/links:latest - 원격 digest:
sha256:6f8cb1a5d406231f9851efd176ed3b5bc8cf41a993f542c8e6278ce6a3fa133a - release asset은 없습니다.
update.sh가 tag1.0.8의 7개 배포 파일을 HTTPS로 받습니다. 대응은update.sh=ops/deploy-registry.sh,reset.sh=ops/reset-registry.sh,backup.sh=ops/backup-registry.sh이고, 나머지는compose.yaml·infra/docker/Caddyfile·ops/backup-verify.compose.yaml·ops/runtime-package-coordinator.sh입니다. - 1.0.7 대비 바뀐 배포 파일은
compose.yaml과ops/backup-verify.compose.yaml(healthcheck)뿐입니다.
Downloads 2
-
Source code (zip)
0
2026-10-15 08:23:55 +09:00 -
Source code (tar.gz)
0
2026-10-15 08:23:55 +09:00
- 대상·원인·수정: 공식 PostgreSQL image는 빈 data 디렉터리의 최초 기동에서 socket만 여는 임시 서버로