-
hanyul released this
2026-10-11 22:39:43 +09:00 5.3.0 대비 변경사항
배포·컨테이너
- 운영
compose.yml이 backend·crawler·web을user: "1000:1000"(이미지의node)로 실행하고 루트 파일시스템 읽기 전용, 모든 capability 제거,no-new-privileges를 적용합니다. 쓸 수 있는 곳은 메모리 tmpfs/tmp(64MiB)와 web.next/cache(128MiB,uid=1000,gid=1000)뿐입니다. 세 앱은 볼륨을 마운트하지 않으므로 기존data/소유권은 바뀌지 않습니다. log-reader는 Docker 소켓을 읽기 위해user: "0:0"으로 고정합니다. - 모든 서비스에 json-file 로그 회전(20MB×5)을 적용하고, PostgreSQL
stop_grace_period: 120s·oom_score_adj: -500, MinIO60s, crawlerinit: true·cpu_shares: 512·oom_score_adj: 500을 추가했습니다. - healthcheck는 node 프로세스 대신 busybox
wget으로127.0.0.1을 묻습니다. nginx는 자기 자신을 거친/api/health/live를 묻고, log-reader는 Docker 소켓/_ping이 실패하면503입니다. - backend·crawler가 선택적으로 앱별 최소 권한 MinIO 계정을 쓸 수 있습니다(
BACKEND_MINIO_ACCESS_KEY·BACKEND_MINIO_SECRET_KEY,CRAWLER_MINIO_ACCESS_KEY·CRAWLER_MINIO_SECRET_KEY). 두 키를 모두 비우면 기존MINIO_ACCESS_KEY·MINIO_SECRET_KEY를 그대로 쓰고, 한쪽만 채우면 그 앱은 키 이름을 담은 설정 오류로 시작하지 않습니다. - Nginx는 썸네일·보호 원본 응답을 NAS 볼륨 임시 파일로 spool하지 않습니다.
ops/deploy-production.sh는 실패하면 migration 때문에 멈춘 crawler의 실제 상태를 안내합니다.ops/publish-images.ps1에-VerifyOnly·-PromoteOnly·게시 뒤latest재검증을 추가했고, 모든 Dockerfile의FROM·# syntax를 digest로 고정했으며ops/update-base-images.ps1로 최신 여부를 조회합니다. backend health의version은 이미지 릴리스 버전을 보고합니다.ops/production-audit.sh는 이미지 label·health·invalid index·migration도 점검합니다.
계정·보안
- 계정 보안 화면에 로그인 session 목록(기기 요약·로그인·마지막 사용 시각)과 개별 종료를 추가했습니다(
GET /api/auth/sessions,DELETE /api/auth/sessions/:sessionId). - cookie로 인증한 요청에서 token 남은 수명이 절반 이하이면 같은 session으로 다시 발급해 만료를 늘립니다. 처음 passkey로 로그인한 뒤 30일을 넘겨 늘리지 않습니다. 배포 전 session은 그대로 유지됩니다.
- 요청 제한을 고정 창에서 sliding window counter로 바꿨습니다. 로그인 전역 제한은 계정 단위로 세고 주소별 상한을 더했습니다. Redis 명령 2초·연결 3초 timeout을 넘으면 fail-closed
503입니다. - 브라우저가 Push 구독을 스스로 교체하면 service worker가 새 구독을 한 번 다시 등록하고 이전 행을 교체합니다.
홈·viewer·화면
- 홈 검색 조건을 URL에 담아 검색어·태그를 조합해 검색하고
수집순정렬을 추가했습니다. 뒤로·앞으로 가기는 history 항목별로 목록과 기준 카드 위치를 복원합니다. 다른 화면의 검색 링크와 예전?search=링크는 저장된 정렬 없이 기본 정렬로 엽니다. 출처 선택은 없앴고 예전 링크·저장값의source는 버립니다. - 첫 실행 빈 서재 안내, 접힌 이어 읽기 header의 바로 이어 읽기, 정렬 방향 화살표, 고급 검색 태그 분류의 번역 표기, 카드 완독 배지와 제목 상세 링크, 완독 작품의
다시 읽기, 운영 화면 첫 수집 안내, 빈 대시보드 안내와 선호 태그 번역 표기를 추가하고 대시보드·차단 관리·북마크 폭을 맞췄습니다. - viewer 한 페이지·두 페이지 모드에 마우스 환경의 이전·다음 가장자리 버튼을 추가했습니다.
- 썸네일 재요청 상한, dialog·보조 화면 지연 로딩, 상세 미리 받기, 움직임 줄이기와 시스템 테마 추종을 개선했습니다.
수집
- 완료된 Hitomi 작품의 원본 metadata(제목·태그·파일 목록 변경)를 30초 간격으로 큰 ID부터 한 바퀴 다시 확인합니다. 설정을 저장한 적이 없으면 켜져 있고, 한 바퀴를 마치면 스스로 꺼지며 운영 화면의
다시 실행으로 새 바퀴를 시작합니다. 수집 중에는 쉬고 수집과 같은 보호 회로를 지킵니다. - E-Hentai에서 관리자 재개 뒤에도 같은 실패가 반복되는 작품을 격리하고 다음 작품으로 진행합니다. 원본 삭제는 detail 404 재확인으로만 확정합니다.
- Hitomi 한국어 색인·최신 ID·gg.js의 보호 응답(403·429·503)을 공용 보호 회로에 기록하고 회로가 열려 있으면 요청하지 않습니다. 중지 신호와 요청 기한, Retry-After 상한(하루)을 적용했습니다.
- 페이지 저장의 완료 재계산·카운터 갱신을 줄이고 이미지 색인 누계를 지문 변경과 같은 transaction에서 올립니다.
중복 검사·DB
- 합본·부분 수록을 찾는 포함 관계 중복 후보를 추가했습니다. 기본 비활성이며 중복 검토 화면의 검사 설정에서 켭니다. 해결은 큰 쪽을 보존합니다.
- 쌍 판정 정책을
phash-pair-v2로 올렸습니다. 짧은 작품은 괄호 블록을 지운 제목 key로도 근거를 인정합니다. 정책 문자열이 바뀌어 다음 중복 검사에서 전체를 다시 비교합니다. - 작품의 probe를 8개 묶음 문장으로 나누고 pHash 블록 index를
INCLUDE (phash)covering index로 바꿨습니다. 공통 페이지 재검사는 문장 단위 trigger로 바뀌었습니다. - 목록 cursor를 row 비교로 바꾸고 읽기 상태 필터를
EXISTS·NOT EXISTS로 바꿨으며, 목록 cache는 개인 차단 revision과 같은 snapshot에서 계산합니다. 태그 자동완성은 일치 순위로 정렬합니다. 운영 로그는 컨테이너별since이후만 증분으로 받습니다.
좁힌 입력 검증
- offset 목록 조회는
page × limit이 100,000을 넘으면400입니다(cursor 조회나 정렬 방향 변경 안내). 목록source는hitomi·e-hentai외 값이400입니다. 이미지 업로드 검색은 최대 5천만 픽셀입니다. 자사 web은 이 범위를 넘지 않습니다.
5.3.0에 있던 공개 API는 제거되지 않았습니다(viewer
이 페이지와 비슷한 작품API는 5.3.0 이후 추가됐다가 게시 전에 제거). 필수 환경 변수·수동 전환·데이터 재설정이 없고, 새 Compose와 5.3.0 이미지, 5.3.0 Compose와 새 이미지의 교차 조합도 동작하므로 minor 5.4.0을 적용합니다. 제품 버전은 Git 태그·OCI label·문서로 관리하며 private package와 lockfile의 기존 버전은 유지합니다.이미지 게시 범위
production 빌드 입력 지문이 다섯 서비스 모두 기존
latestlabel과 달라 byedpi·nginx·backend·crawler·web을 모두 새로 빌드해 5.4.0·latest로 게시합니다. 공통으로 지문 recipe(ops/image-inputs.ps1)가 바뀌었고, byedpi·nginx는 기반 이미지 digest 고정, nginx는 media 응답 spool 금지 설정, backend·crawler·web은 Dockerfile·소스·shared가 바뀌었습니다. npm 의존성과 lockfile은 바뀌지 않았고, 기반 이미지 고정 digest는 게시 준비 시점의 upstream 최신 digest와 같습니다. 모든 자체 이미지에 5.4.0 태그가 생기므로IMAGE_TAG=5.4.0을 지정할 수 있습니다.NAS 업데이트와 주의사항
운영자는 운영 반영에 따라 5.4.0의
compose.yml·ops/deploy-production.sh·sql/init-db.sql·.env.example을 받고sh ops/deploy-production.sh로 반영합니다.- Compose 갱신 필수: 실행 제한(non-root·읽기 전용·tmpfs)·로그 회전·종료 유예·healthcheck·앱별 MinIO 키 전달은
compose.yml이 소유합니다. Watchtower가 이미지만 바꾸면 앱은 이전처럼 root로 동작하므로 새compose.yml로 재배포해야 적용됩니다. 파일을 받은 뒤grep -n '1000:1000\|read_only\|x-logging\|BACKEND_MINIO_ACCESS_KEY\|CRAWLER_MINIO_ACCESS_KEY' compose.yml로 확인합니다. .env.example대조: 새 키는 선택 키 4개(BACKEND_MINIO_ACCESS_KEY·BACKEND_MINIO_SECRET_KEY·CRAWLER_MINIO_ACCESS_KEY·CRAWLER_MINIO_SECRET_KEY)뿐이며 빈 값이 기본입니다. 비워 두면 기존 MinIO 키를 그대로 씁니다. 앱별 계정으로 전환하려면 MinIO 앱별 계정 절차대로 앱마다 두 키를 함께 채웁니다. 한쪽만 채운 채 5.3.0 이하로 rollback하지 않습니다.- DB migration 6개(
AddDuplicateScanGalleryIndexes1792030000000,DuplicateCommonPageStatementTrigger1792030100000,DuplicateFingerprintStatementTrigger1792030200000,InvalidateDuplicateSummaries1792030300000,CoveringImageSearchBlockIndexes1792070000000,DuplicateContainment1792080000000)가 backend 시작 때 자동 적용됩니다. 모두 데이터를 보존하지만 forward-only입니다. index 생성·교체는CONCURRENTLY라 오래 열린 transaction이 있으면 기다리고, covering index 교체는 pHash 블록 index를 다시 만들므로 수집·백필이 적은 시간에 배포합니다. 배포 전 백업을 확인하세요. - 배포 순서: Watchtower식 개별 교체(crawler를 멈추지 않고 backend 먼저 교체) 리허설에서
DuplicateCommonPageStatementTrigger가 이전 crawler 쓰기와 deadlock을 내고 재시도 끝에 수렴했습니다. Watchtower 자동 업데이트와 겹치지 않는 시점에ops/deploy-production.sh로 반영합니다. 이 스크립트는 backend 이미지가 바뀌면 migration 전에 crawler를 멈추고, byedpi → postgres → redis → minio → log-reader → backend → crawler → web → nginx 순서로 교체합니다. - rollback 제한: 5.3.0 이미지로 되돌릴 수는 있지만 보장 범위는 데이터 보존과 crawler 비교 SQL이 오류 없이 도는 것입니다. 이전 crawler·web은 포함 관계 후보를 다루지 못하며 자세한 범위는 운영 반영의 rollback 항목을 따릅니다. 5.2.0 이하 backend로는 5.3.0부터 계속 rollback할 수 없습니다.
- 배포 뒤 자동으로 시작되는 작업: 완료 Hitomi 작품 metadata 재확인이 설정 행이 없으므로 켜진 상태로 시작합니다. 30초에 한 작품씩 확인하므로 운영 규모(2026-10-08 작품 약 6.9만 개)에서는 수집이 없는 시간 기준 한 바퀴에 약 24일이 걸립니다. 원하지 않으면 운영 화면 Hitomi 패널에서 끕니다. 중복 검사는
InvalidateDuplicateSummaries와 정책phash-pair-v2때문에 다음 검사에서 다시 비교하며, 그 전까지 영향받는 pHash 후보의 해결은409입니다. - 로그인 cookie는 그대로 유효하며 다시 로그인할 필요가 없습니다.
NAS 배포·운영 데이터 변경은 이번 게시에서 실행하지 않았습니다.
검증
- 최종 main
0a9ef0e4에서run-unit.ps1 -Workspace all이 shared lint를 포함해 통과했습니다(backend 78 suites·580 tests, crawler 69·876, web 133·1,653). - 같은 main의
run-integration.ps1첫 실행은 새 viewer 브라우저 검증(session-viewer-browser.mjs)의페이지 모드selector strict mode 위반으로 실패해exact: true로 고쳤고(2dd06a15, 테스트만 변경·앱 코드 동일), 병합 main4cd97204에서 전체 통과했습니다. - 개발 stack을
4cd97204로 재빌드해 전 서비스 healthy, 홈·/api/health/live·/api/health/ready200을 확인했습니다. - 알려진 리스크(P2, 수용): 새 설치에서 상태 행이 없을 때 30초 이상 지연된 metadata 재확인 켜기가 한 바퀴 완료 저장과 교차하면 이번 바퀴 확인 수가 초기화되지 않습니다.
- 병합 main
37f4449d(UI/UX 패키지 A~D와 통합 selector 수정)에서 web 단위 133 suites·1,657 tests,run-integration.ps1전체,run-schema.ps1, 로컬 hard reset이 통과했습니다. - 기술 검토 후속 병합 main(
f3d752d1)에서run-unit.ps1 -Workspace all,run-schema.ps1,run-integration.ps1,run-crawler-recovery.ps1(전체·-EHentaiOnly),run-duplicate-benchmark.ps1,run-search-benchmark.ps1,run-operations.ps1 -DeploymentOnly,run-compose-compat.ps1(3조합),run-upgrade.ps1 -BuildNew(deploy-script PASS, watchtowerWATCHTOWER RISK)가 통과했습니다. ops/update-base-images.ps1(레지스트리 조회만)은 고정 digest 11개가 모두 현재 digest와 같다고 확인했습니다.- 각 변경은 병합 전에 읽기 전용 리뷰를 거쳤습니다. 최종 main에서
run-schema.ps1·run-crawler-recovery.ps1·benchmark·run-compose-compat.ps1·run-upgrade.ps1은 다시 실행하지 않았고(위 이전 병합 main 결과), 전체 WebAuthn runner(run-passkey.ps1), 실제 Hitomi·E-Hentai 통신 runner, 운영 DB 재측정, NAS 배포는 NOT RUN입니다.
게시 확인
- 릴리스 소스:
c6c0fbb9a6469f31ca69e41d72ebdd6f8feee8cf(annotated Git 태그5.4.0대상). - backend
5.4.0·latest:sha256:3b7eb7cd03355cfe088bc67a3f207a300d9f4bd344b14344b395537bb4f479ab. linux/amd64 manifest:sha256:2f8a97c87d441478637cb00e5869148149c647139b5fe8815a2ff9aa06945bb7. OCI version5.4.0·revisionc6c0fbb9a6469f31ca69e41d72ebdd6f8feee8cf·입력 지문9270deed8859d573b6f48f9c8020e66e57414ae55b11d585dc6a1d0e36739c52. - crawler
5.4.0·latest:sha256:29a53b4295a79846e3ecf9c258c19c9967837406b106dfb8fcf9714150429f60. linux/amd64 manifest:sha256:de909254beff8955e040b9a14b291e0f406ce5e948588b002a9cb959cf57ed54. 입력 지문8229d5b02b55808e37f790544dd6f0bcee8e9efb81f7805bb435dc55a93d9be5. - web
5.4.0·latest:sha256:dc13bbde279b9ca2098fb8ad097311228356a02ae5de05f8e9afa86ce088cf0d. linux/amd64 manifest:sha256:be819ee26ae0a9bb5e72daf07e9534c70bdb30e0f0e3330ac3ca3a2c16b09e40. 입력 지문3a18af3a80a82dc63245c310ffe8a90cc8fc24879790ece7194050bb22947673. - byedpi
5.4.0·latest:sha256:04cf2838499d67a033a3c3101913563bf983e551fee27b891dab0d2f75a4233a. linux/amd64 manifest:sha256:93ea65f6266dc78f928678edb9940720f62d218a7d93cf8e97f03ab3bdb4f670. 입력 지문eb782ec044138f129f03f3574c429e270562cf0f3b47020518dcd64be9fb3584. - nginx
5.4.0·latest:sha256:fb3a63eb7be971660a5b8e4936d42d9ce6454e726a121383c060789b10583b40. linux/amd64 manifest:sha256:8a09d389b1a8396f2c4620b192694b63537c85b3ca1e31d06806af1461195f19. 입력 지문63f29fb371128296c1c1226981bf745d2593b3e1ef1d57713ac0200e59003c67. ops/publish-images.ps1 -Version 5.4.0 -Publish로 다섯 서비스를 모두 새로 빌드·게시했고(재사용·재시도 없음), 버전 태그 게시 뒤 같은 digest로latest를 승격해 다섯 서비스의5.4.0·latest일치를 최종 검증했습니다(Registry tags verified for 5.4.0.).
Downloads 2
-
Source code (zip)
0
2026-10-11 22:39:43 +09:00 -
Source code (tar.gz)
0
2026-10-11 22:39:43 +09:00
- 운영
-
hanyul released this
2026-10-09 04:08:03 +09:00 5.2.0 대비 변경사항
계정·보안
- 관리자 보안 키(
ADMIN_SECURITY_KEY)로는 관리자에게 활성 passkey가 하나도 없을 때만 passkey를 등록할 수 있습니다. 이미 passkey가 있으면 틀린 키와 구분되지 않는 응답으로 거절합니다. - 정규화 뒤 일반 아이디 규칙(
^[a-z0-9_-]{3,32}$)을 통과하는 형식의 보안 키는 비활성화되고 backend 로그에admin_security_key_disabled오류가 남습니다. 키를 쓰려면 33자 이상의 무작위 값으로 바꿔야 합니다. - passkey를 모두 잃었을 때를 위한 서버 셸 전용 복구 명령
node apps/backend/dist/cli/revoke-admin-passkeys.js를 추가했습니다. 관리자 passkey를 비활성화하고 session을 끊습니다. 복구 절차는 운영 가이드의 관리자 보안 키 절에 있습니다.
개인화
- 비로그인 읽기 기록을 로그인 계정에 병합할 때 한 건씩 저장하던 방식을 일괄 SQL로 바꿨습니다. 결과는 같고, 요청 비용(query weight)은 100건당 1(최대 5)입니다.
- 북마크의 쓰지 않던
category·priority·note컬럼과 관련 조회 옵션(category필터,sortBy=priority)을 제거했습니다. 계정 내보내기에서도 빠집니다. 배포 전에 열려 있던 탭·PWA가 보내는 이 필드는 받은 뒤 무시합니다.
수집·중복 검사
- Hitomi checkpoint는 지원하는 schema 버전(1)만 재개합니다. 버전이 없거나 다르면 원본을 그대로 두고, 새 작업이 덮어쓰지 못하게 하며, 운영 화면에 "재개할 수 없습니다. 폐기한 뒤 새로 수집하세요" 안내와 폐기 버튼을 표시합니다(상태 응답에
canDiscard추가). - 중복 검사의 공통 페이지(50작품 이상이 공유하는 지문) 집계를 바꿨습니다. 먼저 지문 행 수로 후보를 걸러 임계값 미만 지문의 images·galleries 읽기를 줄입니다. 판정 결과와 비교 signature는 그대로입니다. 공통 페이지 임계값·지문 algorithm·색인 대상 category는 shared 상수 하나에서 TypeScript 질의와 trigger SQL을 만듭니다.
crawling_states의 쓰지 않던 카운터를 crawler가 더 이상 기록하지 않습니다. 컬럼은 다음 릴리스에서 제거합니다.
DB·운영
- 다른 unique 제약이나 index와 중복된 index 7개를
DROP INDEX CONCURRENTLY로 제거합니다(DropDuplicateIndexes1791942400000). 중단돼도 다음 기동 때 invalid index를 복구해 이어서 완료합니다. - schema 검사는 entity에 선언된 index가 DB에 없거나 정의가 다르면 실패하고, fresh
mark_duplicate_hash_neighbors정의를 migration 전에 shared 정책과 대조합니다. ops/duplicate-scan-cost.sql은 새 질의를 측정하고,-v compare=1이면 이전 질의도 함께 측정합니다. 사전 필터 통과 분포도 출력합니다.- npm 의존성(Next 16.4.0·TypeORM 1.1.2 등)과 기반 이미지(byedpi alpine 3.24, Playwright 1.64.0)를 최신화했습니다. 감사(audit) 결과는 0건입니다.
새 운영 CLI와 상태 필드가 추가됐고, 제거한 북마크 필드는 자사 web이 저장·표시에 쓰지 않아 기존 client와 호환되므로 minor 5.3.0을 적용합니다. 제품 버전은 Git 태그·OCI label·문서로 관리하며 private package와 lockfile의 기존 버전은 유지합니다.
이미지 게시 범위
production 빌드 입력 지문 대조 결과 backend·crawler·web·byedpi가 바뀌어 네 이미지를 새로 빌드해 5.3.0·latest로 게시했습니다. nginx는 기존 latest digest에 5.3.0 태그만 붙였습니다. 모든 자체 이미지에 5.3.0 태그가 있어
IMAGE_TAG=5.3.0을 지정할 수 있습니다. 다만 아래 migration 때문에 5.3.0 적용 뒤에는 5.2.0 이하 backend로 rollback할 수 없습니다.NAS 업데이트와 주의사항
운영자는 운영 반영에 따라 5.3.0의 Compose와 릴리스 파일(
ops/duplicate-scan-cost.sql포함)을 갱신합니다.- DB migration 2개(
DropUnusedBookmarkColumns1791856000000,DropDuplicateIndexes1791942400000)가 backend 시작 때 자동 적용됩니다. 둘 다 forward-only이므로 적용 뒤 이전 backend 이미지로 되돌릴 수 없습니다. 배포 전 백업을 확인하세요.ops/deploy-production.sh는 backend 이미지가 바뀌면 migration 전에 crawler를 멈춥니다. - index 제거는
CONCURRENTLY로 실행되므로 오래 열린 transaction이 있으면 기다립니다. backend가 오래 시작하지 못하면 운영 가이드의 "migration으로 backend가 시작하지 못할 때" 절을 따르세요. ADMIN_SECURITY_KEY가 아이디처럼 보이는 형식이면 배포 뒤 키가 비활성화됩니다. 서비스는 정상 동작하며, 키를 쓰려면 33자 이상의 무작위 값으로 바꿉니다.- 배포 뒤
ops/duplicate-scan-cost.sql(필요하면-v compare=1)로 공통 페이지 집계 비용을 다시 측정할 수 있습니다.
NAS 배포·운영 데이터 변경은 이번 게시에서 실행하지 않았습니다.
검증
- 병합 main
9619668f에서run-unit.ps1 -Workspace all(backend 74 suites·467 tests, crawler 64·726, web 127·1,500),run-schema.ps1,run-integration.ps1,run-crawler-recovery.ps1,run-duplicate-benchmark.ps1,run-operations.ps1 -DeploymentOnly가 통과했습니다. - 중복 검사 benchmark(합성 55,000작품, warm p95): 공통 페이지가 없는 일반 입력은 15.29→4.05ms로 빨라졌습니다. 모든 작품이 공유하는 지문이 섞인 합성 최악 입력은 278.60→396.48ms로 느려졌고, 운영에서 가장 많이 공유된 지문은 90작품입니다. 사전 필터와 기존 집계의 결과가 같다는 것은 실제 PostgreSQL 경계 fixture로 확인했습니다.
- 새 migration은 schema runner에서 재적용, 행 보존, invalid index 복구, 다른 정의 거부를 확인했습니다. backend·crawler·web을 같은 코드로 재빌드해 개발 stack 기동과 migration 적용을 확인했습니다.
- 각 변경은 병합 전에 읽기 전용 리뷰를 거쳤습니다. 전체 WebAuthn runner(
run-passkey.ps1), 실제 Hitomi·E-Hentai 통신, 운영 DB 재측정, NAS 배포는 NOT RUN입니다.
게시 확인
- 릴리스 소스:
02857e6c455958c3e6a290bd2ce2d44c66855f0d(annotated Git 태그5.3.0대상). - backend
5.3.0·latest:sha256:2fd9e69bc5fab7130d73975dc02cf1f8f04b33ba211c6fcb98e9841791c5ceea. linux/amd64 manifest:sha256:6153e18771572b39283a444570e51140f16ec86bb3bfbeb5e4f388876f19f889. OCI version5.3.0·revision02857e6c…·입력 지문a3b1674ff69b2ae17db0e9aa65faca8f6a299e9139b42c4e6021e314a9e3b00d. - crawler
5.3.0·latest:sha256:904ab880b9950574cbd309a02d6acc0b46d5b5cb4c5792d3213f66721c397673. linux/amd64 manifest:sha256:842cf466ca0f7ffbc1a208387ee1187d3a963e5f2af2f4f9395ba3486f342f6b. 입력 지문1c97e22b914f6f8a895ff938b927a2f1049521f2eb6abb3dc35eb62ef6b0ad1d. - web
5.3.0·latest:sha256:9fb1ccabf564f0a944df88f84f6e9045da0787643b84108bbf8c32716b9881f0. linux/amd64 manifest:sha256:c4fe0ecc1f393f4de014b4f6adfe88ba32e23370655031c82fc7afd4b0d9b2aa. 입력 지문f7837d144137546f627cde58abeb7dd02f50ef6f14c8fd6e968b65d2548ff797. - byedpi
5.3.0·latest:sha256:8ffd2e496e2073e8dd7fa523fc3741eb9290f6973192c3b19d81262662dd9efe. linux/amd64 manifest:sha256:28cbfeead016413c34b0c99898ed79e55bc435d6a3a830514e733bc27ee281df. 입력 지문c6bc597c5528f9f45fb32ec7f46b1111913163b5702d0e91f2329e7c5ea4149f. - nginx
5.3.0·latest(기존 digest 재사용):sha256:0ed33b91538effe5864676f21e16edbbdd33f11251bd180adc97f4eb7a16467d. COMPOSE_PARALLEL_LIMIT=1로 push를 직렬화해 첫 실행에 exit 0으로 완료했습니다. 재시도·no-cache·ForceRebuild·직접 docker push·인증 변경은 없었습니다.
Downloads 2
-
Source code (zip)
0
2026-10-09 04:08:03 +09:00 -
Source code (tar.gz)
0
2026-10-09 04:08:03 +09:00
- 관리자 보안 키(
-
hanyul released this
2026-10-08 12:43:39 +09:00 5.1.0 대비 변경사항
E-Hentai 불완전 원본 응답 대응
- 일부 H@H 노드가 원본 앞부분만 캐시한 채
HTTP 200으로 응답해, 같은 페이지를 다시 받아도 같은 잘린 파일이 와서 수집이 영구 실패로 멈추던 문제를 고쳤습니다. - 이미지 URL의 fileid(SHA-1·크기)와 WebP RIFF 선언 크기로 응답을 검증해, 불일치하면
nl대체 서버에서 한 번 더 받습니다. 그래도 불일치하면 영구 실패가 아니라 일시 실패로 처리합니다.nl재요청도 페이지 요청 예산(6회·3분)에 포함됩니다. - 절단된 WebP는 디코더 실패와 구분하고, 과거에 절단된 채 남은
pending객체는 버리고 다시 받습니다. 정상 경로의 요청 수는 늘지 않습니다.
운영 화면
- 썸네일 생성 패널은
대상 갤러리·완료·미처리만 표시하고 진행률은생성 완료 N%로 바꿨습니다. - 데이터베이스 통계와 요청 지표·의존성의 새로고침 버튼을 제거했습니다. 섹션을 펼칠 때마다 자동으로 조회하며, 조회·갱신 실패 시에는
다시 시도를 제공합니다.
PWA 설치 안내와 알림 유도
- 모바일 PWA 설치 안내를 한 번 닫으면 영구히 다시 뜨지 않던 문제를 고쳤습니다. 닫은 뒤 14일이 지나면 다시 보이고, 설치 이벤트가 오지 않는 브라우저에도 한 줄 바와
방법 보기(브라우저별 홈 화면 추가 방법)를 보입니다. 높이는 절반 이하로 줄였습니다. - 북마크한 작가·그룹의 신규 작품 알림 유도창을 추가했습니다. 로그인, 서버 push 구성, 이 브라우저 미구독, 작가·그룹 북마크 1개 이상일 때 잠시 뒤 조용히 나타나며, 모바일은 하단 바, PC는 우측 하단 카드입니다. 권한 요청은
알림 받기를 누를 때만 하고나중에(30일)·받지 않기(영구)를 고를 수 있습니다. - 하단 안내 바가 목록 끝의 페이지 이동 버튼을 가리지 않도록 본문 하단 여백을 예약합니다.
기존 기능과 데이터를 유지하는 기능 추가가 있어 minor 5.2.0을 적용합니다. API 비호환·DB migration·SQL schema·의존성 변경은 없습니다. 제품 버전은 Git 태그·OCI label·문서로 관리하며 private package와 lockfile의 기존 버전은 유지합니다.
이미지 게시 범위
production 빌드 입력 지문 대조상 crawler·web만 변경돼 두 이미지를 새로 빌드해 5.2.0·latest로 게시했습니다. nginx·backend·byedpi는 기존 latest digest에 5.2.0 태그만 붙였습니다. 모든 자체 이미지에 5.2.0 태그가 있으므로
IMAGE_TAG=5.2.0지정과 일괄 rollback이 가능합니다. log-reader는 backend 이미지를 공유하며 PostgreSQL·Redis·Silo는 자체 이미지 게시 대상이 아닙니다.NAS 업데이트와 주의사항
운영자는 운영 반영에 따라 5.2.0의 Compose와 릴리스 파일을 갱신하고 기본
latest를 사용합니다. DB migration은 없으므로 crawler·web 교체만으로 반영됩니다.- 불완전 응답으로
재개 대기에 멈춘 E-Hentai 작업은 배포 뒤 운영 화면에서체크포인트 재개만 누르면nl대체 서버에서 받아 이어 갑니다. - 알림 유도창은 HTTPS(secure context)에서만 동작합니다.
NAS 배포·운영 데이터 변경은 이번 게시에서 실행하지 않습니다.
검증
- 병합 main
2a5b7548에서run-unit.ps1 -Workspace all(backend 71 suites·440 tests, crawler 63·717, web 127·1,497)과run-crawler-recovery.ps1 -EHentaiOnly(합성 provider, 실제 PostgreSQL·MinIO)가 통과했습니다. - 운영 중단 원인은 개발 stack의 crawler egress 경로로 해당 페이지를 실제로 받아 확정했습니다(배정 노드 1,212,416바이트·운영 hash 일치,
nl서버 13,797,136바이트·fileid SHA-1 일치). 수정 코드의 검증·대체·예산 경로는 합성 fixture와 실제 adapter·저장소 경계 spec으로 고정했습니다. - crawler·web을 같은 코드로 재빌드해 기동을 확인했고, 이미지 검색·운영 UI 격리 브라우저 검증 1440/320px이 통과했습니다. PWA 안내와 알림 유도창은 모바일 390/320px·PC 1440px 라이트·다크와 목록 끝 겹침을 캡처로 확인했습니다.
- 각 브랜치는 병합 전 읽기 전용 리뷰를 거쳤습니다. 실제 E-Hentai 통신 runner, 실제 Android·iOS 기기와 push 구독, NAS 배포는 NOT RUN입니다.
게시 확인
- 릴리스 소스:
508ac2225478c7a64d98fed308e8ee296a0ab185(annotated Git 태그5.2.0대상). - crawler
5.2.0·latestOCI index digest:sha256:d08a1d5be95110f2a8aae2fc77f0e6b08f757fefaad1589bf30595e4e2049107. linux/amd64 manifest:sha256:ce3c0a4eaa59629fdb79dc1b989c962205c310d75b626529fd59a1add471e5a5. OCI version5.2.0·revision508ac222…·입력 지문5ee81b7b01a23d03dcdff4a16cf5a5980b5e1ebbde648a7b59b987a86433d4ae. - web
5.2.0·latest:sha256:590952eaa20c3fa045dabd25826887ec6ef1581d2bf90f19a30e29d4b9d75196. linux/amd64 manifest:sha256:151b6ad32c9c715549d742e21ba3a9c148d4edf3685c29d4fb53bb265c1f6e11. OCI version5.2.0·revision508ac222…·입력 지문28b69ca545d4b8946504c4f118de3a8fbeac7b5a05c7a97708a854c0745a9ceb. - nginx
5.2.0·latest(기존 digest 재사용):sha256:0ed33b91538effe5864676f21e16edbbdd33f11251bd180adc97f4eb7a16467d. OCI version5.1.0유지. - backend
5.2.0·latest(기존 digest 재사용):sha256:5ed675eed4da9c63125080a3e4ebc0fabe43093d137fd198ecf225e35917816c. OCI version5.1.0유지. - byedpi
5.2.0·latest(기존 digest 재사용):sha256:15ac60ab852a92219573aa3e3795f700e9da0692022af47233590e6a78a1a40a. COMPOSE_PARALLEL_LIMIT=1로 push를 직렬화해 첫 실행 exit 0으로 완료했으며 재시도·no-cache·ForceRebuild·직접 docker push·인증 변경은 없었습니다.
Downloads 2
-
Source code (zip)
0
2026-10-08 12:43:39 +09:00 -
Source code (tar.gz)
0
2026-10-08 12:43:39 +09:00
- 일부 H@H 노드가 원본 앞부분만 캐시한 채
-
hanyul released this
2026-10-07 08:50:45 +09:00 5.0.1 대비 변경사항
수집 상태와 운영 화면
- E-Hentai 상태 API에
stage·cursor.total·currentGallery.pageCount·lastSuccessAt을 추가하고, metadata 검사 중에는 검사 중인 갤러리를 현재 갤러리로 유지해-깜박임을 줄였습니다. 재개 시 남던E-Hentai 수집을 재개했습니다.안내는 제거했습니다. - 수집 패널은 Hitomi·E-Hentai 모두
현재 단계와 하단마지막 성공:시각을 같은 자리에 보이고, E-Hentai는목록 위치를N번째/M번째, 이미지 저장 단계의현재 페이지를N / M페이지로 보입니다.대기 갤러리·실패 갤러리수는 표시하지 않으며 운영 관리의 시각 레이블을마지막 성공으로 통일했습니다. - 운영 관리의 새로고침은 공용 버튼(아이콘 +
새로고침, 조회 중 스피너)으로 통일했고, 가비지 컬렉션은 새로고침을 제목 행 우측 상단,마지막 집계를저장 원본아래로 옮겼습니다. 안내문·보조 줄 색과 시각 형식을 맞췄습니다(전수 점검 시각은 초 유지). 중복 검사 작업의최근 검사 기록블록은 제거했습니다. - Hitomi 매일 증분 자동 수집은 20:00(Asia/Seoul)에 실행됩니다.
중복 관리
- 홈 삭제·GC로 소속 작품이 사라져 비교 상대가 없는 중복 그룹(살아 있는 작품 2개 미만, 해결 그룹은 0개)은 검토 목록과
검토 필요집계에서 제외합니다. 그룹 행은 지우지 않습니다.
브라우저 캐시
- HTML 문서와 버전 없는 public 파일(아이콘·manifest 등)은
private, no-cache(200·304)로 응답해 Firefox도 썸네일을 디스크 캐시에 저장합니다. 오류·redirect는no-store를 유지합니다. - 썸네일 304 응답에 ETag·Cache-Control을 포함하고
If-None-Match를 RFC 9110 약한 비교(W/·쉼표 목록·*)로 처리합니다. 보호 원본도 같은 helper를 씁니다. - 설정의
브라우저 캐시 정리설명·완료 토스트에 "브라우저에 따라 이미 열린 탭은 새로 열어야 반영될 수 있다"는 안내를 넣었습니다.
기본 블랙리스트와 태그 번역
- fresh install 기본 전역 블랙리스트를 2026-10-06 운영 내보내기와 동일하게 태그 143개·갤러리 582개로 맞췄습니다(기존 DB 규칙은 바뀌지 않음, migration 없음).
- 누락 태그 628건 중 563건을 번역(공식 한국어 확인 115건)하고 15건은 원문 유지, 50건은 보류했습니다.
oppai loli는거유로리,whos that girl은오늘의 한요일은 여자다로 바꿨습니다. - 기존 사전 10,816개를 감사해 공식 표기 132건·게임 데이터 44건·의미 55건·표기 일관성 264건·통용 표기 23건, 총 518건을 교정했습니다. 교정 전후·근거는
apps/web/src/lib/__fixtures__/tag-translation-review-2026-10-07.json에 있습니다.
기존 기능과 데이터를 유지하는 기능·지원 범위 추가가 중심이라 minor 5.1.0을 적용합니다. API 비호환·DB migration·SQL schema·의존성 변경은 없습니다. 제품 버전은 Git 태그·OCI label·문서로 관리하며 private package와 lockfile의 기존 버전은 유지합니다.
이미지 게시 범위
production 빌드 입력 지문 대조상 nginx·backend·crawler·web이 변경돼 네 이미지를 새로 빌드해 5.1.0·latest로 게시했습니다. byedpi는 기존 latest digest에 5.1.0 태그만 붙였습니다. 모든 자체 이미지에 5.1.0 태그가 있으므로
IMAGE_TAG=5.1.0지정과 일괄 rollback이 가능합니다. log-reader는 backend 이미지를 공유하며 PostgreSQL·Redis·Silo는 자체 이미지 게시 대상이 아닙니다.NAS 업데이트와 주의사항
운영자는 운영 반영에 따라 5.1.0의 Compose와 릴리스 파일을 갱신하고 기본
latest를 사용합니다. DB migration은 없으므로 backend·crawler·web·nginx 교체만으로 반영됩니다.- Hitomi 자동 수집 시각이 22:00에서 20:00으로 바뀝니다. 다음 자동 실행 시각은 운영 화면 Hitomi 패널에서 확인합니다.
- HTML 캐시 정책 완화로 HTML이 개인 브라우저 디스크 캐시에 남을 수 있습니다. 공유 cache 불허(
private)와 매 요청 재검증(no-cache)은 유지됩니다. - 기본 블랙리스트 seed 변경은 새 설치에만 적용됩니다. 운영 DB의 기존 규칙과 비어 있는 중복 그룹은 변경되지 않으며, 빈 그룹은 배포 뒤 목록에서 사라집니다.
- 번역 교정 518건은 화면 표기가 바뀝니다. 되돌릴 항목은 fixture의 교정 목록으로 확인합니다.
NAS 배포·운영 데이터 변경은 이번 게시에서 실행하지 않습니다. 마지막 기록된 NAS 배포는 4.6.0이며 현재 운영 버전 확인을 대신하지 않습니다.
검증
- 병합 main
5c02afa2에서run-unit.ps1 -Workspace all(backend 71 suites·440 tests, crawler 63·691, web 126·1,483),run-operations.ps1 -DeploymentOnly, 기본 블랙리스트 브랜치의run-schema.ps1이 통과했습니다. - 개발 stack을 같은 코드로 재빌드해 HTML·manifest
private, no-cache와 304, 없는 chunkno-store, 썸네일 304의 ETag·약한 목록 검증, 정리 endpoint 204와Clear-Site-Data,jobs/ehentai/status응답 형태, crawler 기동 로그의 20:00 예약을 확인했습니다. - 이미지 검색·운영 UI 격리 브라우저 검증 1440/320px, 운영 UI 320~1920px 라이트·다크 176장 캡처,
run-translation-coverage.ps1(개발 DB 101 tags)이 통과했습니다. 브라우저 캐시는 Chromium·Firefox·WebKit에서 재방문 전송 0바이트와 정리 뒤 재전송을 실측했습니다. - 각 브랜치는 병합 전 읽기 전용 리뷰를 거쳤습니다. 실제 데스크톱 브라우저 재측정, viewer 보호 페이지 캐시 실측, 수집 실행 중 화면 관측, NAS 배포는 NOT RUN입니다.
게시 확인
- 릴리스 소스:
20ec1d9379ca4c4b936aa35c3c179c71d273e0c9(annotated Git 태그5.1.0대상). - byedpi
5.1.0·latest(기존 digest 재사용):sha256:15ac60ab852a92219573aa3e3795f700e9da0692022af47233590e6a78a1a40a. linux/amd64 manifest:sha256:6c30efe40328be54695b17acbc2f82d255ca66b6f0fac5e07c1da7b0df2c1024. 입력 지문이 latest와 같아 새로 빌드하지 않았습니다. - nginx
5.1.0·latestOCI index digest:sha256:0ed33b91538effe5864676f21e16edbbdd33f11251bd180adc97f4eb7a16467d. linux/amd64 manifest:sha256:398179ddd39a7cbe2a0773d68af7a2e1085457995ed04081f58960bc6f2ead79. OCI version5.1.0·revision20ec1d93…·입력 지문a02757a0a50293e8d4bf509b8b317fc46942ae155926bb759a946871643bc7d0. - backend
5.1.0·latest:sha256:5ed675eed4da9c63125080a3e4ebc0fabe43093d137fd198ecf225e35917816c. linux/amd64 manifest:sha256:7fedbfa9ed1500cfce0b3a9b064a72cc441b6d94e06e486b3155ecbfc01bdc63. OCI version5.1.0·revision20ec1d93…·입력 지문3c628833c714d4218f3e49db5588c970b3605612cdbe84c34ddc28013ec2b396. - crawler
5.1.0·latest:sha256:e738b21c0aa1cba32955d907e35a2207a9a100872dc3c669c65c4c4ad041648e. linux/amd64 manifest:sha256:96f7ea6ecb4847818cc1c858f873470340b7391ae0d5cab460058fec670c8c8d. OCI version5.1.0·revision20ec1d93…·입력 지문499554adee2571372c2507ea27781e0e445cd591d06fb01da9137c164fbc3fdd. - web
5.1.0·latest:sha256:80a1b119ba2793ffd9a4e31f10465dce90855e26fcd715e09f708779a879efb3. linux/amd64 manifest:sha256:2ec56af015a301486b4cb24d234268807fbbd811086aef85d1239a6bed598808. OCI version5.1.0·revision20ec1d93…·입력 지문09913fa94996ecb0b3d5815c23d1c305932d5149a11d3ad4b30896f7ca2a7c07. publish-images.ps1 -Version 5.1.0 -Publish첫 실행은 네 이미지 동시 push에서 레지스트리unknown오류로 멈췄고 태그는 하나도 올라가지 않았습니다.COMPOSE_PARALLEL_LIMIT=1로 push를 직렬화한 재실행이 exit 0으로 완료했으며 no-cache·ForceRebuild·직접 docker push·인증 변경은 없었습니다. 공유 개발 stack 9개 컨테이너는 같은 코드로 재빌드돼 유지 중입니다.
Downloads 2
-
Source code (zip)
0
2026-10-07 08:50:45 +09:00 -
Source code (tar.gz)
0
2026-10-07 08:50:45 +09:00
- E-Hentai 상태 API에
-
hanyul released this
2026-10-04 01:28:01 +09:00 5.0.0 대비 변경사항
검색과 운영 UI
- 검색 태그의 inline/wrap 전환을 검색칸 자체의 36rem 폭으로 판단하고 자동 끝 스크롤을 제거하여 태그 앞부분 잘림을 고쳤습니다. 좁은 칸의 긴 한국어 태그를 줄바꿈하고 키보드·터치로 조건 끝까지 접근할 수 있습니다.
- GC 네 분류가 패널 폭을 균등하게 채우며, 원본 무결성은 1·2·3열 반응형 배치와 큰 수치 줄바꿈으로 표시합니다. 저장량은 넓은 화면의 실행 버튼 오른쪽 하단에 정렬합니다. GC·점검·복구 명령과 권한은 유지합니다.
- 갤러리의 링크 복사 아이콘을 Share2로 바꿨습니다. 접근 이름, 복사 URL과 성공·실패 안내는 유지합니다.
PostgreSQL 공유 메모리
- Compose의 postgres에
shm_size: 1gb를 추가하여 POSIX 공유 메모리(/dev/shm) 용량을 1GiB로 설정합니다. PostgreSQL upstream 이미지와 DB schema·migration은 바꾸지 않습니다.
호환되는 UI 수정과 운영 설정 조정으로 patch 5.0.1을 적용합니다. API 비호환·DB migration·SQL·의존성 변경은 없습니다. 제품 버전은 Git 태그·OCI label·문서로 관리하며 private package와 lockfile의 기존 버전은 유지합니다.
이미지 게시 범위
production COPY/ignore·빌드 옵션·Turnstile 인자·linux/amd64 지문 대조상 web만 변경됐습니다.
publish-images.ps1 -ChangedOnly로 web 5.0.1·latest를 게시했습니다. backend·crawler·nginx·byedpi는 기존 latest digest를 유지하고 5.0.1 태그를 추가하지 않습니다. log-reader는 backend 이미지를 공유하며 PostgreSQL·Redis·Silo는 자체 이미지 게시 대상이 아닙니다.NAS 업데이트와 주의사항
운영자는 운영 반영에 따라 5.0.1의 Compose와 릴리스 파일을 갱신하고 기본
latest를 사용합니다. 일부 이미지에만 5.0.1 태그가 있으므로 전체IMAGE_TAG=5.0.1지정과 일괄 rollback은 불가합니다. 서비스별 digest·Compose·현재 DB migration 호환성을 확인합니다.공유 메모리 설정 반영에는 postgres 컨테이너 재생성이 필요하고
restart만으로 적용되지 않습니다. DB 연결이 일시적으로 끊기므로 별도 승인 후 작업이 없는 시간에 적용합니다. web 이미지 교체만으로 공유 메모리 설정은 반영되지 않으며 NAS 배포·운영 데이터 변경은 이번 게시에서 실행하지 않습니다.실제 NAS
/dev/shm확장·문제 병렬 쿼리 재측정·DSM53100 해소, 공유 개발 runtime·운영 배포, 실제 GC/audit/repair·OS clipboard·외부 source는 NOT RUN입니다. 마지막 기록된 NAS 배포는 4.6.0이며 현재 운영 버전 확인을 대신하지 않습니다.검증
-
동일 최종 입력의 web lint/typecheck·검색 선택 1 suite/15 tests, 이미지 검색/운영 UI fixture와 142 geometry를 재사용했습니다. 라이트·다크 320~1920px·575/576/577px 검색 container 경계, 긴 한국어·15조건·키보드/터치, GC 진행·경고·오류/loading·preview 성공/실패를 포함합니다.
-
Share2 최종 production build와 1440/320px × light/dark 4상태에서 실제 Next modal 렌더·overflow·console 및 mock clipboard 성공/실패를 확인한 증거를 재사용했습니다. API/이미지·clipboard는 mock이며 실제 서버 mutation·OS clipboard 검증이 아닙니다.
-
최종 Compose의 operations DeploymentOnly exit0와 quiet config·정규화 공유 메모리 1073741824 bytes를 재사용했습니다. 실제 격리 Nginx/stub upstream·배포/게시 모의 fixture이며 NAS 실행·개발 DB/Redis runtime을 포함하지 않습니다.
-
최종 전체 web/all 재실행은 NOT RUN입니다. 커밋·태그 때문에 통과한 동일 입력 검증을 반복하지 않았으며 실제 production Turnstile 인자의 게시 web build는 별도로 확인했습니다.
-
준비 문서 검증은 추적 Markdown 21개·로컬 링크/anchor 440개 오류 0, dev/prod Compose quiet 두 종류 exit0·Git diff check exit0입니다.
게시 확인
- 릴리스 소스:
1c7e7405f48023cc817ff397d1ec49debbc355ab(annotated Git 태그5.0.1대상). - byedpi 기존
latest:sha256:15ac60ab852a92219573aa3e3795f700e9da0692022af47233590e6a78a1a40a. linux/amd64 manifest:sha256:6c30efe40328be54695b17acbc2f82d255ca66b6f0fac5e07c1da7b0df2c1024. OCI version3.0.5·revision89c34755db3b5b2105a0b3124ff7f86014d9223a·입력 지문2516e0359a2130a7ecda1a0f620667e8a1abea44232437d0d014e38ef6e7efa9유지와5.0.1태그 부재를 확인했습니다. - nginx 기존
latest:sha256:e40f31f88d0af2c48b739d2cd3165cefcfd83e92603510b4b0c22fe3010df7ee. linux/amd64 manifest:sha256:d005f7f82dd66799144c4dbeab522329c13bee4575d6f64a43dbfadb9754173a. OCI version4.8.0·revisionb70e66b9764958941ca663bc2e53e65b5e671573·입력 지문00187339729a4310754408dfbac096f97bd3ebec1c78507e208302afaf549cea유지와5.0.1태그 부재를 확인했습니다. - backend 기존
latest:sha256:85affabef49fe42c77f144d80dbab1ac74351c571130bf7283db28daa90b07d5. linux/amd64 manifest:sha256:90f7b131691538943996b95e7453a2424712a4d97382b2ebf89a4c1fe65c5cb8. OCI version5.0.0·revision18a87ae2ca960824a214dedfc35c7f30c9f6d27d·입력 지문f0c803d38211c5cac15ed538bc5f42c40918f277f02487780d57b36ddb75dc4a유지와5.0.1태그 부재를 확인했습니다. - crawler 기존
latest:sha256:23b843708095fdeb3ce6ae1c1fa55d0d4d5538ae88c57dced1d478e80225937c. linux/amd64 manifest:sha256:e53059a560c0ce51ff24592dcdbbc160c4c164822917ebb499c70ef297708c7c. OCI version5.0.0·revision18a87ae2ca960824a214dedfc35c7f30c9f6d27d·입력 지문6baa627b9554fd7d9b605f0d21feada8198fa1b6e63a2ca788b0a81ac6d7d1a1유지와5.0.1태그 부재를 확인했습니다. - web
5.0.1·latestOCI index digest:sha256:6b529280dca3476046b124f6e2aa7c790ecdc8b5c59c7c7642e70b448ad84a84. linux/amd64 platform manifest:sha256:425a612a818d269ac9961cd102613244f77be41f3415a2bea0521a5f2f08ae8a. OCI version5.0.1·revision1c7e7405f48023cc817ff397d1ec49debbc355ab·입력 지문dfc3e3f9076d1f1e1c97d9b49396d306119b4224716ad30f9ce79118cb6be866일치를 확인했습니다. - 정식 publisher가 자식 프로세스에만
COMPOSE_PARALLEL_LIMIT=1을 적용하여 첫 실행 exit0으로 완료했습니다. 재시도 0회이며 no-cache·ForceRebuild·직접 docker push·인증/전역 설정 변경은 없었습니다. 공유 개발 stack 9개 컨테이너와 5개 local 이미지 identity는 유지합니다.
Downloads 2
-
Source code (zip)
0
2026-10-04 01:28:01 +09:00 -
Source code (tar.gz)
0
2026-10-04 01:28:01 +09:00
-
hanyul released this
2026-10-03 23:01:30 +09:00 4.8.1 대비 변경사항
GC와 원본 보존
- GC를 삭제 대기 이미지(
unreferenced), 블랙리스트 갤러리(blacklisted), 완료 상태 불일치(completion), 불완전한 갤러리(orphaned)의 네 분류로 통일했습니다. 불완전한 갤러리는 통계 전용이며 삭제하거나 회수 용량에 포함하지 않습니다. - 확인된 업스트림 404는
sourceRemovedAt으로 기록하고 기존 원본·완료 시각·개인 기록을 보존합니다. 승인된 metadata 404를 DB에 기록한 뒤 coverage를 확정하며, marker 저장 실패·정지·오류·업스트림 의심 상태에서는 확정을 보류합니다. 재시작 때 확인된 404 coverage를 다시 열지 않고 명시적 재검사와 성공 metadata의 marker 해제를 지원합니다. - 페이지 trim·무결성 repair의 pending 원장을 전체 갤러리 삭제 의도로 추정하지 않도록 고쳤습니다. 명확한 블랙리스트 claim은 원본이 모두 정리된 뒤에도 마지막 갤러리 삭제를 재시도합니다. 원본이 없는 deleted-only legacy tombstone은 모호한 상태로 보호하고 완료 시각과 관계없이 불완전 통계에 포함합니다.
- 404 미완료 갤러리의 개인 기록 쓰기·병합·내보내기와 관리자 페이지 조정을 보호합니다. 완료된 404의 기존 개인 쓰기와 일반 미완료·태그 차단 정책은 유지합니다. 홈 일괄 GC의 즉시 숨김과 내부 쓰기 보호도 유지합니다.
UI/UX와 의존성
- GC 초기 미리보기 설명과 정상 완료의 지속 안내를 제거하고 진행·실패·중단·남은 실패 경고와 실제 미리보기 결과를 유지했습니다.
- 썸네일 안내를 한 줄로 줄이고 저장 원본·썸네일 수와 용량을 실행 버튼 행 오른쪽 하단에 배치했습니다. 좁은 화면에서는 다음 행으로 줄바꿈합니다.
- web의
lucide-react를 1.51.0으로 갱신했습니다.
운영 문서
- Cloudflare WAF·rate limit·Cache Rule·Cache Deception Armor·URL 정규화와 적용 확인·롤백 안내를 정리했습니다. 실제 zone 설정 변경이나 운영 Cloudflare 경유 검증 결과는 아닙니다.
API 비호환과 필수 업데이트 안내
GC stats/result/failures의
deleted필드와 요청includeDeleted가 제거됐으므로 기존 API 사용자는blacklisted·includeBlacklisted로 전환해야 합니다. 이 API 비호환을 근거로 major 5.0.0을 적용합니다. 저장된 구형 실행 결과의 deleted 수·용량·실패는 blacklisted에 합쳐 반환하지만 제거된 요청/API 계약을 복원하지 않습니다. 자동 데이터 보존 migration 자체는 major 결정 이유가 아닙니다. private package/lock 버전은 유지하고 제품 버전은 Git 태그·OCI label로 관리합니다.backend 시작 시
UnifyGarbageGalleryCategories1791770000000migration이 자동 적용됩니다. 기존 deleted-only 행의 원인 시각을 보존하고 ready 원본이 있는 행만 삭제 표시를 해제하며 구형 GC 통계 snapshot을 무효화합니다. gallery·image·개인 행과 완료 시각을 삭제하지 않습니다. forward-only migration으로 down을 지원하지 않고 이미지 rollback만으로 DB를 되돌릴 수 없습니다. 대량 갱신과 이미지 존재 검사에SET LOCAL statement_timeout = 0을 쓰며 운영 규모의 실행·잠금 대기 시간은 미측정입니다.모호한 legacy tombstone의 전체 삭제 또는 복구는 운영자가 원래 의도를 확인하고 별도 승인된 운영 조치로 수행해야 합니다. 남은 원장만으로 완전한 자동 복원이나 이미 소실된 원본 복구를 보장하지 않습니다. DB 전환 정책을 확인합니다.
이미지 게시 범위
publish-images.ps1 -ChangedOnly로 production 빌드 입력이 바뀐 backend·crawler·web을 새로 빌드하고 5.0.0·latest를 게시했습니다. 각 앱 코드와 shared·root lockfile의 COPY 입력이 바뀌었고 web은 production Turnstile 빌드 인자도 지문에 포함합니다. nginx·byedpi는 Dockerfile·COPY/ignore·옵션·플랫폼 입력 지문이 같아 기존 latest digest를 유지하고 5.0.0 태그를 추가하지 않습니다. log-reader는 backend 이미지를 공유하고 PostgreSQL·Redis·Silo는 자체 이미지 게시 대상이 아닙니다.NAS 업데이트
이번 작업은 이미지·Git·Forgejo 게시이며 NAS 배포나 운영 데이터 변경은 실행하지 않습니다. 4.8.1 대비 Compose·환경 키·배포 스크립트는 같지만 fresh SQL과 자동 migration이 바뀌었습니다. 운영자는 운영 반영의 릴리스 파일 준비와 배포 스크립트를 사용합니다. backend 교체 전에 crawler를 멈추는 스크립트 순서를 유지하고 새 backend migration 성공 뒤 새 crawler·web과 backend 이미지를 공유하는 log-reader를 반영합니다. 개별 web 교체만으로 이번 전환을 완료할 수 없습니다.
마지막으로 기록된 NAS 배포는 4.6.0입니다. 이 이력은 현재 운영 버전 확인을 대신하지 않습니다. 이전 버전에서 올라오면 4.8.0 릴리스 안내와 현재 운영 가이드를 함께 확인합니다.
알려진 주의사항
- ChangedOnly로 일부 서비스에만 5.0.0 태그가 있으므로 전체
IMAGE_TAG=5.0.0지정이나 일괄 rollback은 불가합니다. 운영은 기본 latest를 사용하고 rollback은 서비스별 digest·Compose·현재 DB migration 호환성을 확인합니다. - 운영 NAS migration 시간·잠금·부하, 모호 tombstone의 의도 확인/삭제/복구, 실제 Hitomi/E-Hentai 통신, 운영 기기·실제 Cloudflare 화면·개발 공유 화면 반영은 NOT RUN입니다. 기존 운영 검증 미확인 항목을 이번 릴리스로 해소했다고 표시하지 않습니다.
검증
- 최종 gc4
7767270d와 같은 입력의 인수 증거를 재사용했습니다: backend 70 suites/436 tests 및 lint/typecheck, crawler 63/685와 마지막 coverage 선택 1/9 및 lint/typecheck(중복 합산하지 않음), fresh/migration schema, 실제 PostgreSQL·MinIO 원본/개인 행 보존 통합, metadata 14 cases와 3종 fresh-process recovery. - web 전체 초기 실행은 125 suites/962 tests PASS와 1 test spy 실패였고, 보완 후 영향받은 GC 12 tests 및 전체 lint/typecheck PASS로 인수됐습니다. 최종 full web/all 재실행은 NOT RUN이며 단일 all PASS로 표현하지 않습니다.
- 최종 동일 입력 production build·통합 브라우저 1440/320px와 독립 운영 UI 1440/320px PASS를 재사용했습니다. API/source/provider mock과 합성 fixture의 한계를 유지합니다. production Turnstile arg는 통합 fixture와 달라 이번 실제 게시 production build 성공을 별도로 확인했습니다.
- 이번 완료 이력 수정의 문서 21개·로컬 링크/anchor 439개 오류 0, quiet Compose config 두 종류와 Git diff 통과를 확인했습니다. 공유 개발 stack·local 이미지 태그는 변경하지 않습니다.
게시 확인
- 릴리스 소스:
18a87ae2ca960824a214dedfc35c7f30c9f6d27d(annotated Git 태그5.0.0대상). - byedpi 기존
latest:sha256:15ac60ab852a92219573aa3e3795f700e9da0692022af47233590e6a78a1a40a, OCI version3.0.5·revision89c34755db3b5b2105a0b3124ff7f86014d9223a·입력 지문 유지와5.0.0태그 부재를 확인했습니다. - nginx 기존
latest:sha256:e40f31f88d0af2c48b739d2cd3165cefcfd83e92603510b4b0c22fe3010df7ee, OCI version4.8.0·revisionb70e66b9764958941ca663bc2e53e65b5e671573·입력 지문 유지와5.0.0태그 부재를 확인했습니다. - backend
5.0.0·latestOCI index digest:sha256:85affabef49fe42c77f144d80dbab1ac74351c571130bf7283db28daa90b07d5. linux/amd64 platform manifest:sha256:90f7b131691538943996b95e7453a2424712a4d97382b2ebf89a4c1fe65c5cb8. OCI version5.0.0·revision18a87ae2ca960824a214dedfc35c7f30c9f6d27d·입력 지문f0c803d38211c5cac15ed538bc5f42c40918f277f02487780d57b36ddb75dc4a일치를 확인했습니다. - crawler
5.0.0·latestOCI index digest:sha256:23b843708095fdeb3ce6ae1c1fa55d0d4d5538ae88c57dced1d478e80225937c. linux/amd64 platform manifest:sha256:e53059a560c0ce51ff24592dcdbbc160c4c164822917ebb499c70ef297708c7c. OCI version5.0.0·revision18a87ae2ca960824a214dedfc35c7f30c9f6d27d·입력 지문6baa627b9554fd7d9b605f0d21feada8198fa1b6e63a2ca788b0a81ac6d7d1a1일치를 확인했습니다. - web
5.0.0·latestOCI index digest:sha256:ec86a242f7546a471f414b4af6eeda85eee93ca9d83d9c4cf0b211e830d2165e. linux/amd64 platform manifest:sha256:44e6f36f69480d38f44f4e5789552c6f9917b1508576d89778956e41d3c4a803. OCI version5.0.0·revision18a87ae2ca960824a214dedfc35c7f30c9f6d27d·입력 지문2a009cd7567951b500d0b5ff035b3c2d9f62d1d888f71fdc0208e6bd8931cea7일치를 확인했습니다. - 첫 version push는 세 서비스의 registry
unknown오류로 exit 1, latest 미승격 상태에서 중단했습니다. 원격 version 태그 부재와 latest 불변을 확인한 뒤 coordinator 승인으로 자식 프로세스에만COMPOSE_PARALLEL_LIMIT=1을 적용한 controlled retry 한 번이 exit 0으로 성공했습니다. 서버 오류 원인은 미확정이며 동시성이 원인이었다고 단정하지 않습니다. 캐시를 사용했고 no-cache·ForceRebuild·auth/daemon 설정 변경은 없었습니다.
Downloads 2
-
Source code (zip)
0
2026-10-03 23:01:30 +09:00 -
Source code (tar.gz)
0
2026-10-03 23:01:30 +09:00
- GC를 삭제 대기 이미지(
-
hanyul released this
2026-10-03 17:22:15 +09:00 4.8.0 대비 변경사항
UI/UX
- Navigation 줄바꿈 수정 — Windows 클래식 스크롤바와 맑은 고딕에서 관리자 메뉴가 두 줄로 꺾이던 구간을 고쳤습니다. desktop 메뉴 시작을 833px에서 872px로, 계정 이름·로그인/로그아웃 글자 표시 시작을 1024px에서 1040px로 올렸습니다. 872px 미만은 햄버거 메뉴를 사용합니다.
- 같은 속성의 반응형 간격을 px 기준으로 맞춰 Tailwind rem 기준과 출력 순서가 충돌하지 않게 했습니다. 전환 경계의 단위·브라우저 회귀 검증을 추가했습니다.
문서
- README를 해결하는 문제·사용 장면·사전 조건·첫 실행 중심으로 재구성했습니다.
- 공통·영역별 작업 규칙의 적용 범위와 여러 checkout의 공유 개발 stack·runner 주의를 정리했습니다.
- 문서 색인에 독자와 단일 소유 범위를 표시하고 운영·API·아키텍처·DB·중복 검사·테스트 안내의 링크·수치·현재 구현 설명을 바로잡았습니다. 중복 설명은 소유 문서로 연결하고 완료 이력을 최신 게시·마지막 운영 배포·영역별 검증 기준선으로 정리했습니다.
호환되는 UI 수정과 문서 정리이므로 patch 버전입니다. 내부 private 패키지의 manifest·lock 버전은 4.8.0과 같이 유지하고 릴리스 버전은 Git 태그·이미지 OCI label로 관리합니다.
이미지 게시 범위
4.8.0 게시 뒤
latest의 빌드 입력 label과 최종 소스를 대조해 web만 새로 빌드하고4.8.1·latest를 게시했습니다(publish-images.ps1 -ChangedOnly). web은 Navigation 실행 코드가 바뀌었습니다. backend·crawler·nginx·byedpi는 빌드 입력 지문이 같아 기존latestdigest를 유지하며4.8.1태그를 추가하지 않습니다. log-reader는 backend 이미지를 공유하고 PostgreSQL·Redis·Silo는 별도 자체 이미지 게시 대상이 아닙니다.NAS 업데이트
4.8.0 대비
compose.yml·배포 스크립트·환경 키·DB migration 변경은 없습니다. 4.8.0이 이미 반영된 NAS는 web만 갱신하면 됩니다. 아래는 운영자 안내이며 이번 릴리스 작업에서는 NAS 배포를 실행하지 않습니다.cd /volume1/2ex-hentai docker login git.2ex.dev docker compose --env-file .env.production pull web docker compose --env-file .env.production up -d --no-deps web docker compose --env-file .env.production ps web4.8.0보다 이전 버전에서 업데이트하면 먼저 4.8.0 릴리스의 Compose·migration·배포 안내를 확인합니다. 마지막으로 기록된 NAS 배포는 4.6.0이며 4.7.0·4.8.0 운영 반영은 확인되지 않았습니다.
알려진 주의사항
-ChangedOnly로 web에만4.8.1태그가 있으므로 전체 서비스를IMAGE_TAG=4.8.1로 일괄 지정하거나 일괄 rollback할 수 없습니다. 운영은 기본latest를 사용하고 rollback은 서비스별 기존 digest·Compose·migration 호환성을 확인합니다.- NAS 배포·실제 운영 브라우저의 메뉴 전환 확인은 미실행입니다. 기존 릴리스의 운영 검증 미확인 항목은 이번 UI·문서 릴리스로 해소되지 않습니다.
검증
- 코디네이터가 확인한 Navigation
fd4b1b3b의run-unit.ps1 -Workspace web963개, web production build,run-integration.ps1(브라우저 871px 햄버거·872px 한 줄 포함) 통과 결과를 재사용했습니다. 이후 실행 코드가 같아 재실행하지 않았습니다. - 게스트·일반·관리자 × 라이트·다크 × 맑은 고딕/클래식 스크롤바·Noto Sans KR/스크롤바·기본 폰트/무스크롤바의 760~1440px 1px 측정은
fd4b1b3b기준선이며 운영 브라우저 확인을 대신하지 않습니다. - 통합 문서
fada8dff에서 링크 415개·anchor 273개 오류 0, 개발·운영 Compose config와git diff --check통과 결과를 재사용했습니다. 게시 전 깨끗한 checkout·production Compose 설정·실제 Turnstile 빌드 키 존재·서비스별 입력 지문을 확인했습니다.
게시 확인
- 릴리스 소스:
1cedd031b1f07ba0ad2750765927cda97b72e887(주석 태그4.8.1). - web
4.8.1·latest:sha256:a14687e35c7ae1905d915974ce92c8ab9a9ace10cdf90715a922c0e1ace73f59 - web OCI version
4.8.1·revision1cedd031b1f07ba0ad2750765927cda97b72e887·빌드 입력 hashbaa2d560d2ef7cac1ca4043970f058971158c4fb3280cbdf14d28abdf40535eb일치를 확인했습니다. - backend 기존
latest:sha256:8a45d2408182b31b0dd58d642dc04c2ae2bc31ac0ed36195131d22aae265b932 - crawler 기존
latest:sha256:6ee14a74a3992e892a0612881bfd311755827e2649e173768d04fb5e02d02466 - nginx 기존
latest:sha256:e40f31f88d0af2c48b739d2cd3165cefcfd83e92603510b4b0c22fe3010df7ee - byedpi 기존
latest:sha256:15ac60ab852a92219573aa3e3795f700e9da0692022af47233590e6a78a1a40a - 생략한 네 서비스는 기존 OCI version·revision·digest를 유지하며
4.8.1태그를 추가하지 않았습니다.
Downloads 2
-
Source code (zip)
0
2026-10-03 17:22:15 +09:00 -
Source code (tar.gz)
0
2026-10-03 17:22:15 +09:00
-
hanyul released this
2026-10-03 13:36:20 +09:00 4.7.0 대비 변경사항
기능
- Hitomi 수집 기록 무시 재검사 — 명시 범위 수집에 재검사 옵션을 추가했습니다. GC 뒤 이미 닫힌 수집 범위를 다시 검사할 수 있고 기존 coverage와 저장 원장을 보존합니다. 일반 범위·latest에서는 삭제·차단 표시 작품과 이미 닫힌 후보를 요청 없이 처리합니다.
- 태그 제외 검색 — 카드와 상세의 태그 메뉴에
제외하고 검색을 추가했습니다. 홈의 기존 포함·제외 필터를 함께 사용할 수 있습니다. - 묶음 조회 API — 카드 요약(
POST /api/galleries/cards)·작가/그룹 미리보기(POST /api/galleries/creator-previews)·중복 대기 수 전용 조회(GET /api/duplicates/review-groups/counts)를 추가해 북마크·게스트 기록·운영 요약의 반복 요청을 줄였습니다.
UI/UX
- 디자인 토큰과 공용 로딩·빈 화면·오류·권한·진행률 표시를 전 화면에 적용했습니다. 다크 입력 윤곽을 보강하고 좁은 화면의 버튼·메뉴·필터 배치를 정리했습니다.
- 모바일 메뉴의 첫 포커스·바깥 영역 비활성화·닫은 뒤 포커스 복귀, dialog 설명·첫 포커스, 정렬·태그 메뉴의 키보드 조작과 터치 영역을 개선했습니다.
- 운영 화면을 작업별로 묶고 접힌 섹션에도 상태를 표시합니다. 권한을 잃으면 상태 조회를 멈추고 재확인을 안내하며, 조회 실패를 빈 상태·0개로 보이지 않게 했습니다.
- GC 확인 창에 대상·용량·실행 중 작업을 표시하고 확인 중 시작 불가로 바뀌면 이유를 안내합니다. 용량 표시와 로그·블랙리스트 상태를 통일했습니다.
- 홈
이어 읽기는 기본 접힘이며 사용자의 펼치기 선택을 저장합니다. 오프라인 배너·일괄 GC 바·PWA 안내가 모바일 검색창이나 하단 도구를 덮지 않게 했습니다. - 작가·그룹 북마크 삭제 뒤 시간 제한 없는
되돌리기, 이미지 검색 미리보기, 뷰어 상태·페이지 제외 확인과 중복 비교 이전/다음 조작을 개선했습니다.
수집·중복 검사·성능·안정성
- Hitomi galleryinfo 재사용, 받은 바이트의 저장 단계 재시도, E-Hentai overlap detail 재요청·불필요한 checkpoint 쓰기 제거로 외부 요청을 줄였습니다.
- E-Hentai 정상 페이지의 보호 문구 오판정을 막고 차단 만료 시각을 읽습니다. 진전 없는 Hitomi 반복 보호 정지는 자동 재개 간격을 늘립니다.
- DB 단절 때 background 작업의 기록 실패가 backend·crawler를 종료시키지 않게 했습니다. 중복 검사 일시 DB 오류는 시도 횟수를 차감하지 않고, GC 통계 갱신은 재시도하며 저장소 전면 장애의 GC는 연속 5개 실패 뒤 중단합니다.
- crawler DB 연결 획득 대기는 30초, idle-in-transaction은 300초, 문장 상한은 기본 15분입니다. 유휴 이미지 색인의 불필요한 잠금 연결·동일 상태 쓰기를 줄였습니다.
- 개인 차단 검색에 태그 LOWER 표현식 index와 한 번의 규칙 해석을 적용했습니다. DB 통계는 11개 순차 query에서 4개로, GC 통계는 이미지 사전 집계 1회로 줄이고 읽기 진행률 저장도 gallery 확인을 포함한 단일 upsert로 바꿨습니다.
- 북마크·작가 미리보기·dashboard의 창 focus 재조회는 마지막 조회 5분 뒤로 제한하고 고급 태그 검색에 300ms debounce·요청 취소·인기 태그 재사용을 적용했습니다.
- 지문 블록 통계를 추가해 중복 후보·이미지 검색 실행 계획을 개선했습니다. 업로드 캡처의 검은 여백·상태바를 검색 전용으로 trim해 원본과 함께 검색하고, trim 실패 시 원본 검색을 유지합니다. 영구 색인 실패는 반복 대기하지 않고 종료·복구 원인을 표시합니다.
버그 수정
- Hitomi 게시 시각 저장 누락으로 작가·그룹 알림 대상에서 빠지던 문제와 다른 브라우저 구독 때문에 알림 스위치가 틀리거나 해제되지 않던 문제를 고쳤습니다.
- Push는 사용자별로 독립 발송해 한 사용자의 장애가 다른 발송을 막지 않습니다. 410은 즉시, 다른 영구 4xx는 연속 3회 뒤 구독을 비활성화하며 재시도 간격은 1분~1시간입니다.
- 썸네일 유지 생성의 일시 오류 뒤 매시간 생성이 끊기던 문제, 부분 실패한 crawler 상태·미종료 GC를 유휴로 표시하던 문제를 고쳤습니다.
- 공개
/api/health/crawling활동에 이미지 색인·썸네일 생성도 반영하고 Hitomi 매일 예약 수집을 서울 오후 10시로 옮겼습니다.
의존성·정리·문서
- NestJS 12.1.2, TypeORM 1.1.1, React 19.3.0, SimpleWebAuthn 14, Sharp 0.35.5와 개발·브라우저 검증 도구를 갱신했습니다. Nest 구버전 peer 중복 설치를 제거하고 ESM·TypeScript 호환 설정을 맞췄습니다.
- 내부 미사용 경로·export·Redis 플래그·중복 설정·무동작 Nginx cache 지시어를 정리했습니다. DB 설정은 문서의
DATABASE_*, crawler 내부 주소는 현재 계약을 사용합니다. - 화면·API·수집 복구·DB·검증·운영 문서를 현재 구현에 맞췄습니다.
기존 기능·데이터를 유지하는 새 기능과 API가 추가돼 minor 버전입니다. 데이터 재설정이나 필수 수동 데이터 전환은 없습니다. 내부 private 패키지의 manifest 버전은 4.6.0→4.7.0과 같이 유지하고 릴리스 버전은 Git 태그·이미지 OCI label로 관리합니다.
DB migration (backend 시작 시 자동 적용, 데이터 보존)
ImageSearchBlockStatistics1790991300000—image_search_hashes의 4개 지문 블록 표현식 통계와ANALYZE를 추가합니다. transaction 안에서 statement timeout을 해제합니다.AddTagLowerNameIndexes1791769000000—tags의LOWER(name)·LOWER(namespace || ':' || name)index 2개를CREATE INDEX CONCURRENTLY로 생성합니다. 실패한 invalid index는 재시도 때 재생성하고 원래 statement timeout을 복원합니다.
이미지 게시 범위
4.7.0
latest의 빌드 입력 label과 최종 소스를 대조해 nginx·backend·crawler·web만 새로 빌드하고4.8.0·latest를 게시했습니다(publish-images.ps1 -ChangedOnly). nginx는 CSP·설정, backend·crawler·web은 앱·공유 패키지·lockfile·빌드 입력이 바뀌었습니다. byedpi는 지문이 같아 기존latestdigest를 유지하며4.8.0태그를 추가하지 않습니다. log-reader는 backend 이미지를 공유하고 PostgreSQL·Redis·Silo는 별도 자체 이미지 게시 대상이 아닙니다.NAS 업데이트
compose.yml이 바뀌었으므로 먼저 이 태그의 파일을 받습니다. 아래는 운영자 안내이며 이번 릴리스 작업에서는 NAS 배포를 실행하지 않습니다.cd /volume1/2ex-hentai curl -fsSL https://git.2ex.dev/hanyul/2Ex-Hentai/raw/tag/4.8.0/compose.yml -o compose.yml grep -n CRAWLER_DB_STATEMENT_TIMEOUT_MS compose.yml docker login git.2ex.dev sh ops/deploy-production.sh docker compose --env-file .env.production ps- 새
CRAWLER_DB_STATEMENT_TIMEOUT_MS는 기본900000ms(15분),0은 상한 해제입니다. 키가 없어도 Compose 기본값으로 동작합니다. - backend·crawler·web을 함께 반영합니다. 배포 스크립트는 backend 변경 시 crawler를 먼저 멈춰 migration과 옛 crawler 쓰기의 deadlock을 피합니다.
- 대형 태그·지문 테이블의 index 생성·통계 수집은 시간이 걸릴 수 있습니다. NAS 실측 시간은 미확인이며 수집·백필이 적은 시간에 배포하고 migration 완료와 backend healthy를 확인합니다. 이미지 rollback은 migration을 되돌리지 않습니다.
- 이전 오류로 운영 썸네일 백필이
paused상태라면 배포 뒤 운영 화면에서생성 시작을 한 번 누릅니다. - 작가 알림을 쓰면 운영 VAPID 공개·비밀 키가 설정돼 있고 같은 키 쌍인지 확인합니다. 키 값은 로그나 게시 기록에 남기지 않습니다.
- nginx CSP에 Cloudflare Web Analytics의
static.cloudflareinsights.comscript와cloudflareinsights.com연결을 허용했습니다. 운영 Cloudflare를 거친 브라우저에서 CSP 오류를 확인합니다. Inter 폰트 preload 경고도 제거했습니다.
알려진 주의사항
-ChangedOnly로 변경 서비스에만4.8.0태그가 있으므로 전체 서비스를IMAGE_TAG=4.8.0으로 일괄 지정하거나 일괄 rollback할 수 없습니다. 운영은 기본latest를 사용하고 rollback은 서비스별 기존 digest·Compose·migration 호환성을 확인합니다.- 실제 원본 정확도 runner
run-duplicate-accuracy.ps1은 기존 입력 표본 디렉터리가 없어 미실행입니다. 합성 fixture·golden raster·검색 회귀 결과를 운영 원본 정확도로 해석하지 않습니다. - NAS 배포·실제 NAS 부하 및 migration 소요 시간·운영 원본 검색 정확도·실제 Push provider·실제 인증기·운영 Cloudflare 브라우저 확인은 미실행입니다.
검증
- 합친 main
36b77df2에서 코디네이터가 확인한run-unit.ps1 -Workspace all -TimeZoneRegression(backend 436·crawler 670·web 962), crawler recovery 일반·EHentaiOnly, duplicate benchmark·near-miss 결과를 재사용했습니다. 이후 앱 실행 코드 변경은 없고 UI fixture 한 줄(698924a0)과 게시 준비 기록(b70e66b9)만 추가했습니다. - 게시 준비 소스에서 schema, search benchmark(
rel-480-search), integration 전체, operations DeploymentOnly, 이미지 검색·운영 UI(1440/320px), 북마크 UI(1440/450/320px), passkey viewer/admin 검증이 통과했습니다. 실제 저장소 통합과 mock UI·가상 인증기 검증을 구분합니다. - 이미지 검색 UI의 최초 실패는 새 개수 API fixture 누락이었고 실제 backend 응답 형태를 추가한 뒤 해당 격리 UI만 재실행해 통과했습니다.
- 합성 tmpfs 검색 fixture의 개인 차단 100/500개 p95는 39.817/53.119ms(같은 실행 baseline 394.532/137.928ms)였습니다. NAS 성능이 아닙니다.
- 현재 lockfile의 root production/전체·integration API/browser·passkey audit 모두 0건이며 DI 공유 의존성은 단일 버전입니다.
- 실제 E-Hentai는 direct TLS/DPI 실패를 분류하고 선택 ByeDPI로 목록·상세·WebP 이미지·showpage를 확인했습니다(7요청). 전체 외부 이미지 host 가용성을 보증하지 않습니다.
게시 확인
- 릴리스 소스:
b70e66b9764958941ca663bc2e53e65b5e671573(주석 태그4.8.0). - nginx
4.8.0·latest:sha256:e40f31f88d0af2c48b739d2cd3165cefcfd83e92603510b4b0c22fe3010df7ee - backend
4.8.0·latest:sha256:8a45d2408182b31b0dd58d642dc04c2ae2bc31ac0ed36195131d22aae265b932 - crawler
4.8.0·latest:sha256:6ee14a74a3992e892a0612881bfd311755827e2649e173768d04fb5e02d02466 - web
4.8.0·latest:sha256:66fee185ad4b28b250fe29b64d784dd7d3395ae202b56cf0880ce47b2ceae93d - 네 이미지 모두 OCI version
4.8.0·revisionb70e66b9764958941ca663bc2e53e65b5e671573·빌드 입력 hash 일치를 확인했습니다. byedpi는 기존latestdigestsha256:15ac60ab852a92219573aa3e3795f700e9da0692022af47233590e6a78a1a40a유지·4.8.0태그 부재를 확인했습니다.
Downloads 2
-
Source code (zip)
0
2026-10-03 13:36:20 +09:00 -
Source code (tar.gz)
0
2026-10-03 13:36:20 +09:00
-
hanyul released this
2026-10-03 01:39:23 +09:00 4.6.0 대비 변경사항
보안 전수조사(브라우저·backend·crawler·edge)에서 찾은 1순위 항목을 고친 릴리스입니다. XSS·권한 누락·SQL 주입은 발견되지 않았고, 아래는 방어 강화와 DoS·우회 경로 차단입니다.
backend
- 요청 1건으로 backend가 멈추던 문제 수정(High) — 의심 입력 검사 정규식을 선형 패턴으로 바꾸고 검사 길이를 제한했습니다. 요청 한도 검사가 그보다 먼저 실행됩니다.
- 다른 사이트에서 보내는 요청 차단(CSRF) — 데이터를 바꾸는 요청(POST·PUT·PATCH·DELETE)은 사이트 자체 출처일 때만 받습니다(
403 REQUEST_ORIGIN_REJECTED). form 인코딩 본문 parser를 제거했습니다. - IPv6 요청 한도 우회 차단 — 요청 한도·조회 예산·미디어 예산·가입 시도는 IPv6 주소를 /64 단위로 셉니다.
- 관리자 보안 키 — 틀린 시도를 IP당 1시간 10회로 제한하고(일반 가입 시도에도 함께 적용), 길이를 드러내지 않게 비교합니다. 운영에서
JWT_SECRET·COOKIE_SECRET·ADMIN_SECURITY_KEY가 예제 값(CHANGE_ME…)이거나 JWT와 쿠키 비밀값이 같으면 시작하지 않고, 32자 미만은 경고를 남깁니다. - Web Push — 알려진 Push 서비스 주소(HTTPS)만 등록하고 사용자당 구독은 10개까지입니다. 모든 기기 로그아웃은 Push 구독도 지웁니다.
- DB 연결 고갈 방지 — 개인 route가 클래스의 조회 비용을 낮추지 않게 하고, 계정 내보내기·guest 병합에 비용과 사용자별 단일 실행을 적용했습니다.
X-Powered-By제거, 경로 판정 대소문자·경계 정확화.
crawler
- Hitomi
gg.js를 실행하지 않음(High) — 외부 스크립트를 실행하는 대신 형식 parser로 읽습니다. 실제 응답으로 이전 방식과 결과가 같은 것을 확인했습니다. - 내부 API 토큰 — 새 설정
CRAWLER_INTERNAL_TOKEN이 있으면 backend→crawler 호출을 공유 토큰으로 확인합니다. 비어 있으면 검사하지 않고 시작 경고만 남깁니다. crawler CORS를 제거했습니다. - Hitomi redirect는 Hitomi HTTPS 주소만 따라가고(최대 3회), E-Hentai 보호 응답 판별을 선형 검사로 바꿨습니다.
nginx·web
- CSP 강제 정책 승격 —
unsafe-eval, 임의 외부 이미지·WebSocket 출처를 막고object-src 'none'·base-uri·form-action·frame-ancestors를 추가했습니다(Report-Only 제거). /api/요청 본문 상한 2 MiB, 이미지 검색만 11 MiB. 정적 파일은 GET·HEAD만, upstreamX-Accel-*무시,X-Powered-By숨김.- web API 경로 인코딩과 lint 규칙, 홈
?gallery=UUID 검사, 알림 클릭은 같은 사이트 주소로만 이동, 로그아웃 때 Push 구독·조회 cache·홈 복귀 상태 정리. - 의존성 — Next.js 16.3.8, Nest 11.2.7(multer 2.4.0), axios 1.20.0. 운영 의존성
npm audit0건.
운영
deploy-production.sh는 backend 이미지가 바뀌면 migration 전에 crawler를 멈춰 deadlock을 막습니다.compose.yml: backend·crawler에CRAWLER_INTERNAL_TOKEN(기본 빈 값),sql/init-db.sql읽기 전용 mount.
DB migration은 없습니다. 새 설정은 선택이고 기존 데이터·사용 방식이 유지되므로 minor 버전입니다. 사이트 밖 출처에서 관리 작업을 하던 경우에는 그 출처를
CORS_ORIGIN에 추가해야 합니다.이미지 게시 범위
빌드 입력 지문을 4.6.0 시점
latest와 대조해 nginx·backend·crawler·web을 새로 빌드하고4.7.0·latest를 게시했습니다(publish-images.ps1 -ChangedOnly). nginx는 보안 헤더·CSP·본문 상한 설정, backend·crawler·web은 앱 코드·공유 패키지·lockfile이 바뀌었습니다. byedpi는 입력이 같아 기존latestdigest를 유지하며4.7.0태그를 추가하지 않았습니다.NAS 업데이트
compose.yml과 배포 스크립트가 바뀌었으므로 먼저 받습니다.cd /volume1/2ex-hentai curl -fsSL https://git.2ex.dev/hanyul/2Ex-Hentai/raw/tag/4.7.0/compose.yml -o compose.yml curl -fsSL https://git.2ex.dev/hanyul/2Ex-Hentai/raw/tag/4.7.0/ops/deploy-production.sh -o ops/deploy-production.sh grep -n "CRAWLER_INTERNAL_TOKEN" compose.yml docker login git.2ex.dev sh ops/deploy-production.sh docker compose --env-file .env.production ps- 권장: 배포 전
.env.production에CRAWLER_INTERNAL_TOKEN=<openssl rand -hex 32 결과>를 넣습니다. 없어도 동작하지만 crawler가 경고를 남기고 토큰 검사를 하지 않습니다. - 권장:
ADMIN_SECURITY_KEY가 32자 미만이면 무작위 긴 값으로 바꿉니다(이미 등록된 passkey는 계속 사용). - 배포 뒤 운영 사이트에서 브라우저 개발자도구 console에 CSP 오류가 없는지 확인합니다. Cloudflare가 Web Analytics·Rocket Loader 등으로 스크립트를 주입하면 막힐 수 있습니다.
- 이 릴리스는 변경 서비스에만 버전 태그가 있으므로
IMAGE_TAG로 전체 서비스를 일괄 지정할 수 없습니다.
검증
- 게시 소스 main에서
run-unit.ps1 -Workspace all(web 860 포함),run-crawler-recovery.ps1(내부 토큰 거부 포함),run-operations.ps1 -DeploymentOnly,run-integration.ps1(브라우저 회귀 포함) 통과. worker 단계에서run-hitomi-network(실제 Hitomi, gg.js parser) 통과. - 격리 nginx·web Playwright로 주요 화면·Turnstile 로그인·viewer·이미지 검색에서 강제 CSP 위반 0건을 확인했습니다.
- 개발 서버를 이 소스로 재빌드해 healthy, 외부 출처 POST 403, 강제 CSP 헤더를 확인했습니다. 실제 Push 해제·PWA 설치·운영 Cloudflare 스크립트 주입 여부와 NAS 배포는 실행하지 않았습니다.
게시 확인
- 릴리스 소스:
969a854a(주석 태그4.7.0). - nginx
4.7.0·latest:sha256:8abb8e6c23405656d22150cc1cb632d93042efd9191a0877d8d206e2cb8b41da - backend
4.7.0·latest:sha256:bb61f0134cafc8a8b39c05fb81fe79f4b6a396e6d72f01a382390db96dfaa35f - crawler
4.7.0·latest:sha256:f80c46f91309b07ab29f16c4c9497dce8f881880d5e1ecc82e415aa9818fae45 - web
4.7.0·latest:sha256:a76b2dee8f88f96b3523ea83dcd5d1c7730ff55a87ecb6178e524d653d63fbbd - 네 이미지 모두 OCI version
4.7.0·revision969a854a확인. byedpi(15ac60ab)는 기존latest유지·4.7.0태그 부재 확인.
Downloads 2
-
Source code (zip)
0
2026-10-03 01:39:23 +09:00 -
Source code (tar.gz)
0
2026-10-03 01:39:23 +09:00
-
hanyul released this
2026-10-02 20:13:54 +09:00 4.5.0 대비 변경사항
수집(crawler)
- 정지·재개가 더 똑똑해졌습니다 — 색인 404 이상 판정은 같은 batch의 정상 응답이나 최신 gallery 확인으로 통과하면 삭제로 닫아 영구 정지하지 않습니다. 원본 삭제 판정이 연속 상한에 걸리면 자동·예약 재개를 멈추고 관리자 확인을 기다립니다(같은 gallery를 하루 12번 헛재시도하던 문제 해소). permanent 첫 실패는 gallery마다 1회 1시간 뒤 다시 시도하고, 페이지 수 변경은 일시 실패(
source_changed)로 분류합니다. - 차단 신호 보강 — Hitomi 403(30분)·이미지 503(5분)도 공용 보호 회로를 엽니다. 수집 중 삭제·차단된 gallery는 저장 오류로 job을 멈추지 않고 건너뜁니다.
- 체크포인트 폐기 분리 —
jobs/discard를 새로 두고, 유휴 상태의jobs/stop은 체크포인트를 지우지 않습니다. - 처리량·고정비 — E-Hentai detail HTML 중복 요청 제거, 전역 blacklist 잠금 반복 축소, gallery 종료 저장을 한 transaction으로(완료 gallery당 DB 왕복 16→8회), 범위 계획을 checkpoint마다 저장하지 않고 한 번만, 작은 covered 구간 병합, nozomi 후보 우선 처리, 원본 다운로드·decode를 storage lock 밖으로, HTTP 응답 크기 상한.
- 판정·관측 — 한국어 tag 판정을
korean정확 일치로 좁혔고(수집 정책 version 유지), E-Hentai 계측·병렬 실행 중 로그 buffer 보호, 19시 예약 계획 실패를 상태에 기록합니다.
중복 검사·색인·저장소
- 중복 검사 — 전체 검사는 변경된 작품만 다시 탐색하고(정책·algorithm 변경은 자동 감지), 색인 대기 항목은 back-off로 다시 확인합니다(색인이 덜 된 동안 worker가 쉬지 않고 돌던 문제 해소). 비교 signature에서 revision을 빼 불필요한 무효화를 줄이고, 판정 불가 후보를 미리 거르며, 작업 이력은 30일 보관합니다. 검토 목록 정렬과 읽기 전용 정확도 보고(
ops/duplicate-accuracy.sql)를 추가했습니다. - GC — gallery 단위 일괄 삭제(DeleteObjects, 미지원 시 단건 대체)와 비동기 실행(시작 수락 + 상태 조회)으로 바꿨습니다.
- 썸네일 — 축소본이 없으면 원본으로 대체하고 다시 만듭니다. 운영 화면의 썸네일 생성 상태 조회가 전수 집계를 기다리지 않고 즉시 응답합니다(합성 5.4만 gallery 기준 집계 3,020→63ms, 조회 항상 약 5ms).
- 이미지 색인·검색 — 색인 처리 묶음 장벽 제거, 수집 중 자동 감속, 검색 결과를 작품별로 묶고 단색·빈 업로드는 거절합니다. 운영 작업 상태는 현재 오류만 원인 범주(예:
DB 연결 실패(57P01))·시각과 함께 보여 줍니다.
backend·인프라
- 운영 화면 전용이던 crawler 상태 API(
unified-status·jobs/ehentai/status)를 관리자 전용으로, 공개/api/health/ready는{status}만 반환합니다(200/503 의미 유지). - DB pool 획득 timeout, 태그·작가 검색 cache, 잘못된 ID는 400, Push 처리량·timeout, 블랙리스트 재계산 N+1 제거, 개인 차단 조건 개선(100개 page query 66→12ms).
- 배포 중 502 감소: backend SIGTERM 정리(최대 20초), nginx upstream keepalive, backend 교체 중
/api는503 UPSTREAM_UNAVAILABLEJSON. crawler proxy timeout 정합. - 링크 미리보기 embed 조회 2초 제한, 배포 직후 열린 탭의 이전 chunk 로드 실패는 한 번만 새로고침.
- 강화한 CSP를 Report-Only로 추가. HSTS는 Cloudflare 설정 안내.
- 실제 client IP 복원은
NGINX_REAL_IP_FROM(기본 빈 값 = 현재 동작)으로 운영 검증 뒤에만 켤 수 있습니다. 로그인 사용자 썸네일 한도는 계정 단위입니다. Redis 사용률·축출 수를 관리자 상태에 표시합니다.
화면(web)
- 홈 — 상단
이어 읽기줄, 같은 탭에서 viewer를 닫고 돌아오면 목록·스크롤 위치 복원, 다른 탭의 진행률·북마크 반영, guest 완료·미완료 탭이 목록을 끝없이 조회하던 문제 수정(5 page 뒤더 찾아보기), 번역 사전을 공용 chunk에서 분리(viewer gzip 270→97KB). - viewer·상세 — 상세 modal에 읽기 진행과
이어 읽기·처음부터,?page=진입, Webtoon 지나간 page 해제와 원장 크기 기반 높이 예약(먼 page 이동 시 위치 유지), 네트워크 복구 후 이미지 재요청, 모바일 두 손가락 확대, page 맞춤·Webtoon 폭 설정, RTL scrubber 방향, 프리로드 개선, Push 알림 클릭 처리. - 운영 화면 — 원본 전수 점검 시작·이어서·처음부터, 요청 지표·의존성 진단 섹션, 중복 관리 상태 배지와 동시 실행 경고 보강, 격리 gallery의 원본 링크, GC·저장 용량 표시.
새 기능이 추가되고 기존 데이터·사용 방식은 유지되므로 minor 버전입니다. 관리자 전용으로 바꾼 API와 비동기로 바꾼 GC는 함께 배포되는 web만 사용합니다.
DB migration (backend 시작 시 자동 적용, 데이터 보존)
DuplicateIncrementalScan— 중복 검사 이력 보존·대기 back-off 컬럼, 실제 변경에만 반응하는 trigger, 썸네일 원장skipped·failed상태, 부적격 gallery의 미색인 대기 행 정리(파생 대기열, 다시 적격이 되면 trigger가 재등록). transaction 안에서만 statement timeout 해제.AddThumbnailTargetIndex— 썸네일 통계용 부분 index를CREATE INDEX CONCURRENTLY로 생성(쓰기 잠금 없음, timeout 해제 후 복원).
이미지 게시 범위
빌드 입력 지문을 4.5.0 시점
latest와 대조해 nginx·backend·crawler·web을 새로 빌드하고4.6.0·latest를 게시했습니다(publish-images.ps1 -ChangedOnly). nginx는 설정(upstream keepalive·client IP 복원 entrypoint·CSP Report-Only)과 Dockerfile, backend·crawler·web은 앱 코드·공유 패키지가 바뀌었습니다. byedpi는 입력이 같아 기존latestdigest를 유지하며4.6.0태그를 추가하지 않았습니다.NAS 업데이트
compose.yml에 backend·web의init: true·stop_grace_period: 30s와 nginx의NGINX_REAL_IP_FROM(기본 빈 값)이 추가됐습니다. 배포 중 502를 줄이려면 compose를 먼저 받습니다(저장소가 공개라 로그인 없이 받아집니다).cd /volume1/2ex-hentai curl -fsSL https://git.2ex.dev/hanyul/2Ex-Hentai/raw/tag/4.6.0/compose.yml -o compose.yml docker login git.2ex.dev sh ops/deploy-production.sh docker compose --env-file .env.production ps.env.production은 바꾸지 않아도 됩니다.NGINX_REAL_IP_FROM이 없으면 지금과 같이 동작합니다. 켜기 전 검증 절차는 운영 가이드에 있습니다.- backend가 시작하며 위 migration 2개를 적용합니다. index는 잠금 없이 만들어지지만 NAS에서 수 분 걸릴 수 있습니다.
- 운영 화면 이미지 색인에 남아 있던 지난 오류 경고는 배포 뒤 첫 주기에 지워집니다.
- 이 릴리스는 변경 서비스에만 버전 태그가 있으므로
IMAGE_TAG로 전체 서비스를 일괄 지정할 수 없습니다.
검증
- 게시 소스 main에서
run-unit.ps1 -Workspace all(backend 347·crawler 543·web 856),run-schema.ps1,run-integration.ps1전체 통과. 직전 2차 개선 기준(26c75bef)에서run-crawler-recovery.ps1,run-operations.ps1 -DeploymentOnly,run-search-benchmark.ps1통과(benchmark 연속 3회 포함). - 실제 Hitomi·E-Hentai 통신(
run-hitomi-network·run-ehentai-network), 격리 브라우저 화면 캡처와 수치 측정(웹툰 page 위치, 홈 스크롤 복원, 썸네일 통계 시간)으로 화면·전송 변경을 확인했습니다. - 개발 서버를 이 소스로 재빌드해 healthy를 확인했습니다. 실제 기기·Firefox·Safari 확인, NAS 실측(썸네일 통계·index 생성 시간), 실제 client IP 판정 켜기, NAS 배포는 실행하지 않았습니다.
게시 확인
- 릴리스 소스:
0de3cf8ef56a01cb8761798249f597f12ff4fe94(주석 태그4.6.0). - nginx
4.6.0·latest:sha256:d43e596d023703648cb936b2afb48951c9f6db816ba952c952859f2e501ec8ec - backend
4.6.0·latest:sha256:ab055ca11b0f1c7b72edfa39fc31069b05f0eba326d6d497bfb970f73df55604 - crawler
4.6.0·latest:sha256:edd9523595f8b204b64e3e1ac76ec469597f6fc5e1760e960bcc5a387d851afd - web
4.6.0·latest:sha256:f5a25edd4bea602d14370c650d06f7586f1babb3e57d9e72a3f1c72e1ff7b5c2 - 네 이미지 모두 OCI version
4.6.0·revision0de3cf8e확인. byedpi(15ac60ab)는 기존latest유지·4.6.0태그 부재 확인.
Downloads 2
-
Source code (zip)
0
2026-10-02 20:13:54 +09:00 -
Source code (tar.gz)
0
2026-10-02 20:13:54 +09:00
- 정지·재개가 더 똑똑해졌습니다 — 색인 404 이상 판정은 같은 batch의 정상 응답이나 최신 gallery 확인으로 통과하면 삭제로 닫아 영구 정지하지 않습니다. 원본 삭제 판정이 연속 상한에 걸리면 자동·예약 재개를 멈추고 관리자 확인을 기다립니다(같은 gallery를 하루 12번 헛재시도하던 문제 해소). permanent 첫 실패는 gallery마다 1회 1시간 뒤 다시 시도하고, 페이지 수 변경은 일시 실패(