스텔라이브 비공식 팬 아카이브.
- 스택: React 19 + Vite + TypeScript, 정적 JSON (백엔드 없음)
- 실행: Docker Compose (multi-stage build → nginx)
docker compose up -d --build
# → http://127.0.0.1:18083/클론 직후엔 방송 데이터(public/data/)가 비어 있지만,
sync 컨테이너가 시작할 때 전체 동기화를 한 번 돌리므로 몇 분 안에 채워진다.
sync는 저장소에 데이터를 쓰기 때문에 기본 UID/GID 1000으로 실행된다.
호스트 계정의 UID가 1000이 아니라면 NYO_UID=$(id -u) NYO_GID=$(id -g) docker compose up -d --build처럼 넘겨준다.
로컬에 Node 없이 개발 서버를 띄우려면:
docker run --rm -it -u "$(id -u):$(id -g)" -v "$PWD":/app -w /app \
-p 5173:5173 node:22-alpine sh -c "npm install && npm run dev -- --host"
# → http://localhost:5173/compose를 거치지 않고 개발 서버만 쓸 경우 방송 데이터가 비어 있는데,
python3 scripts/sync_vods.py를 한 번 돌리면 채워집니당. (파이썬 표준 라이브러리만 사용)
python3 scripts/sync_vods.py # 치지직 API에서 VOD 동기화
python3 scripts/check_live.py # 방송 중 여부 확인 → live.json
python3 scripts/cache_thumbs.py # 썸네일/아바타 로컬 캐시 (+WebP 변환)src/data/members.json— 멤버 (수동 관리: 이름 · 퍼스널 컬러 · 기수 · 치지직 채널)public/data/games.json— 게임 카탈로그 (치지직 게임 카테고리에서 자동 생성,storeUrl등 수동 보강 필드는 재동기화 시 보존. 런타임 fetch라 재배포 불필요)src/data/vod_thumbs.json— VOD 썸네일 URL 맵 (자동 생성, cache_thumbs 전용, git 제외)public/data/vods.json— 전체 VOD 기록 (자동 생성, 런타임 fetch)public/data/live.json— 방송 중인 멤버 (자동 생성, 프론트가 60초마다 폴링)public/data/는 sync가 계속 갱신하는 생성물이라 git에서 제외public/thumbs/— 캐시된 이미지 (자동 생성: 게임 포스터 · 아바타 · 멤버별 VOD 썸네일. 치지직 핫링크 대신 WebP로 변환해 직접 서빙)
19금 영상 썸네일은 비로그인 API가 안 주므로, 성인 인증된 네이버 계정의 세션 쿠키를 .env에 넣으면 가져올거예요 (.env.example 참고, 없어도 동작)
docker compose up -d를 하면 sync 컨테이너가 같이 올라가 주기적으로 갱신합니당 (scripts/sync_loop.sh):
- 시작 시
sync_vods.py전체 동기화 1회 — fresh clone도 몇 분? 안에 데이터가 채워지고 - 2분마다
check_live.py→ live.json (+ 방송 중인 게임이 카탈로그에 없으면 games.json에 즉석 등록 — 새 게임이 방송 시작 ~2분 안에 사이트에 나타냄) - 방송 종료·재시작 감지 시 그 멤버만 부분 동기화 —
sync_vods.py <멤버id>(종료 후 ~5분 안에 다시보기 반영) - 3시간마다
sync_vods.py백스톱 → vods.json, games.json
public/data/(vods · games · live)는 웹 컨테이너에 볼륨 마운트 + 프론트가 런타임에 fetch하므로 갱신 즉시 반영됩니다.
재배포 안해도 게임 리스트에 추가되게 만들었어요.
sync가 멈추면 live.json의 updatedAt이 오래되고, 프론트는 5분 이상 지난 데이터를 무시하므로 LIVE 배지가 조용히 사라질겁니다 (테스트는 못해봤어요...ㅎㅎ)
로그 확인: docker logs -f nyo-sync
스텔라이브와 무관한 비공식 팬 프로젝트입니다. 게임 및 방송 관련 권리는 각 권리자에게 있습니다.
멤버 상세 페이지·카드·멤버 목록은 팬 개발자가 PR로 직접 꾸밀 수 있다. 폴더 구조가 곧 적용 범위:
src/members/
<기수>/<멤버id>/page|card/<깃허브id>/<이름>.tsx ← 멤버 개인
<기수>/page|card|grid/<깃허브id>/<이름>.tsx ← 기수 전원 (합동 곡 기념 등)
page|card|grid/<깃허브id>/<이름>.tsx ← 전체 멤버
- 같은 표면에 변형이 여러 개면 방문마다 랜덤으로 하나 — 우선순위 엄슴, 그룹 변형도 개인 변형과 같은 확률
- 크레딧은 깃허브 id 폴더명에서 자동으로 잡히고, 머지되면 사이트의
/designs(팬메이드 디자인)에?variant=미리보기 링크와 함께 노출됩니다 - 핵심 규칙:
- 외부 네트워크 요청 금지
- 오디오 자동재생 금지
- 모바일(≤860px) 가로 넘침은 주의 정도만...ㅎㅎ
- 스텔라이브 2차 창작 가이드라인 준수해주세요!!!!
- 상세 가이드(티어 설명 ·
when조건 · 미리보기 방법)와 코드 노트:CONTRIBUTING.md - PR에는 데스크톱·모바일 스크린샷을 첨부해 주세요
코드 말고도 팬게임 목록(src/data/fangames.json) 항목 추가 PR도 환영합니다
필드 설명은 CONTRIBUTING.md 참고해부세욥.
- 코드: MIT — 기여(PR)된 코드도 동일하게 MIT로 배포됩니다.
- 폰트: Pretendard (SIL OFL 1.1)
- 데이터·이미지: 게임 및 방송 관련 권리는 각 권리자에게 있습니다. 본 프로젝트는 스텔라이브와 무관한 비공식·비영리 팬 프로젝트이며, 스텔라이브 2차 창작 가이드라인을 따릅니다.