ACN
dAppOffice
문서 목차 (8 / 16)

08. 설치 · 실행 · 배포

요구 사항

  • Node.js 20+ (개발 환경 24.x), npm
  • Python 3.12+
  • 모바일 기기 + TokenPocket 또는 MetaMask 앱 (PC와 같은 네트워크)

로컬 실행

백엔드

cd backend
python -m venv .venv
.venv\Scripts\activate            # macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
copy .env.example .env            # macOS/Linux: cp
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

--host 0.0.0.0로 띄워야 휴대폰에서 접근할 수 있다. .envCORS_ORIGINShttp://<PC-IP>:3000을 추가한다.

인덱서(선택): python -m app.indexer

프론트엔드

cd frontend
npm install
copy .env.example .env.local
# .env.local: NEXT_PUBLIC_API_URL=http://<PC-IP>:8000
npm run dev -- -H 0.0.0.0

휴대폰 지갑 앱 dApp 브라우저에서 http://<PC-IP>:3000 접속.

PC에서 UI만 확인

Chrome DevTools → Device toolbar(모바일 UA + 터치 에뮬레이션). 지갑이 없으므로 딥링크 화면까지만 보인다. 실제 서명 테스트는 반드시 기기에서 한다.

백엔드 배포 — Render (Blueprint)

저장소 루트의 render.yaml이 FastAPI 백엔드를 정의한다(서비스명 acn202610-api, 루트 디렉터리 backend, Python 3.12, 헬스체크 /health).

  1. https://dashboard.render.comNew → Blueprint → GitHub 저장소 kimduckbo/acn 선택(비공개 저장소이므로 Render GitHub 앱에 접근 권한 부여) → Apply.
  2. 배포가 끝나면 https://acn202610-api.onrender.com/health{"status":"ok"}를, /api/indexer가 동기화 상태를 반환하는지 확인.
  3. Render가 다른 호스트명을 배정했다면 netlify.tomlNEXT_PUBLIC_API_URL을 그 값으로 바꿔 푸시(또는 Netlify UI 환경 변수로 덮어쓰기).
  4. Render 서비스의 CORS_ORIGINS에 프론트 오리진(https://acn202610.netlify.app)이 들어 있는지 확인(Blueprint 기본값에 포함).

무료 플랜 특성:

  • 15분 동안 요청이 없으면 인스턴스가 잠들고, 첫 요청에 30~60초가 걸린다. dApp의 내역 조회는 404/오류 시 재시도하므로 잠시 후 표시된다.
  • 영구 디스크가 없어 SQLite 캐시는 재배포·재시작 시 초기화된다. 인덱서가 INDEXER_BACKFILL_BLOCKS(100000 블록, 약 21시간치)만큼 되감아 체인에서 다시 채운다. 영구 보존이 필요하면 유료 인스턴스 + disk 블록(render.yaml 주석 참고)을 켜고 DATABASE_PATH를 마운트 경로로 바꾼다.
  • 백그라운드 워커가 유료이므로 RUN_INDEXER_IN_APP=true로 인덱서를 API 프로세스 안에서 데몬 스레드로 돌린다. 웹 인스턴스는 1개만 유지한다(여러 개면 인덱서가 중복 실행됨).

프로덕션 배포(권장 구성)

구성 요소방법
프론트엔드npm run build 후 Node 서버(npm start) 또는 Vercel. 반드시 HTTPS (지갑 앱 다수가 http dApp 차단)
백엔드uvicorn app.main:app --host 127.0.0.1 --port 8000 --workers 2 를 systemd로 관리, Nginx/Caddy 리버스 프록시 + TLS
인덱서별도 systemd 서비스로 python -m app.indexer, 자동 재시작
DBbackend/data/ 를 디스크에 두고 주기 백업(.backup)
RPCbsc-dataseed.binance.orgeth_getLogs를 거부하므로 인덱서에 쓸 수 없다. 기본값은 bsc-rpc.publicnode.com이며, 운영은 NodeReal/QuickNode/Ankr 등 전용 RPC 권장

환경 변수 체크리스트

  • NEXT_PUBLIC_API_URL = 백엔드 공개 HTTPS URL
  • CORS_ORIGINS = 프론트 공개 HTTPS 오리진
  • NEXT_PUBLIC_TOKEN_ADDRESS == TOKEN_ADDRESS
  • NEXT_PUBLIC_CHAIN_ID == CHAIN_ID
  • (선택) NEXT_PUBLIC_WC_PROJECT_ID
  • 저장소 루트의 .env 류 파일이 커밋되지 않았는지 확인(.gitignore 적용)

검증 명령

cd frontend && npm run lint && npm run build
cd backend && .venv\Scripts\python -c "import app.main, app.indexer"
curl http://localhost:8000/health
curl http://localhost:8000/api/token