# chiwaa > chiwaa.kr 은 정적·빌드형 웹사이트 호스팅이다(엑스와이넷 운영, 한국어 지원, 원화·부가세 포함 요금). > 사이트는 `<이름>.chiwaa.com` 주소로 열리고, 터미널의 `chiwaa` CLI 로 바로 배포한다. ## AI 코딩 도구를 위한 배포 방법 사용자가 "치와와(chiwaa)에 배포해 줘 / 올려 줘"라고 하면 프로젝트 폴더에서 다음을 실행한다. ```bash npx chiwaa deploy -y --name <사이트이름> ``` - `-y`: 아무것도 묻지 않고 끝까지 진행한다. AI 도구에서는 항상 붙인다. - `--name`: 영문 소문자·숫자·하이픈 2~30자(예: my-shop). 주소는 `<이름>.chiwaa.com` 이 된다. 규칙에 안 맞으면 거절한다. 사용자 계정에 이미 그 이름의 CLI 사이트가 있으면 그 사이트를 새 내용으로 바꾸고, 다른 사람이 쓰는 이름이면 실패한다 — 새 사이트를 만들 때는 사용자에게 이름을 확인받는다. 처음 한 번만 필요하고, 다음부터는 폴더의 `.chiwaa.json` 을 보고 같은 사이트로 올린다. - `--name` 없이 `-y` 만 쓰면 폴더 이름으로 새 사이트를 만들고, 겹치면 뒤에 4글자를 붙인다. - 깃허브로 배포하는 사이트에는 CLI 로 올릴 수 없다. - 처음 배포하면 폴더에 `AGENTS.md`(와 없으면 `CLAUDE.md`)가 생긴다. AI 도구가 다음 작업 때 스스로 읽는 chiwaa 사용 규칙이다. 지우지 말고, 새로 고치려면 `npx chiwaa agent`. 사이트에는 올라가지 않는다. - 성공하면 마지막 줄에 `https://<이름>.chiwaa.com` 주소가 나온다. 그 주소를 사용자에게 알려 준다. - 실패하면 `✗` 로 시작하는 한국어 안내가 나오고 종료 코드가 1 이다. 안내를 사용자에게 그대로 전한다. ### 로그인 처음이면 로그인이 필요하다. 사용자가 직접 승인해야 한다. ```bash npx chiwaa login ``` 브라우저 주소와 확인 코드가 나온다. 사용자에게 주소를 열고 코드를 확인한 뒤 「승인」을 누르라고 안내하고, 명령이 끝날 때까지 기다린다(최대 10분). 응답을 끝내야 하는 도구라면 명령을 끊어도 된다 — 사용자가 승인한 뒤 `npx chiwaa login`(또는 하려던 명령)을 다시 실행하면 새 코드 없이 같은 승인을 이어받는다. 환경변수 `CHIWAA_TOKEN` 이 있으면 로그인 없이 쓴다. 토큰을 출력하거나 파일·저장소에 적지 않는다. ### 빌드 - `package.json` 에 `build` 스크립트가 있으면 CLI 가 `npm install`(node_modules 가 없을 때) → `npm run build` 를 하고 결과 폴더를 올린다. - 결과 폴더: Vite·Vue·Astro·Angular·Parcel → `dist`, Create React App → `build`, Next.js → `out`. 다르면 `--dir <폴더>`. - Next.js 는 `next.config` 에 `output: 'export'` 가 있어야 한다(정적 내보내기만 된다). - 깃허브 연결 사이트의 빌드 Node 판은 `.nvmrc` → `.node-version` → `engines.node` 순서로 정한다(18·20·22·24, 없으면 22). CLI 는 내 컴퓨터의 Node 로 빌드한다. - 빌드가 없는 HTML 사이트는 폴더를 그대로 올린다. `.env*`, `.git`, `node_modules` 는 올리지 않는다. **그 밖의 파일은 모두 공개되므로** 메모·시험 스크립트·원본 자료는 사이트 폴더 밖에 두거나 사이트 파일만 든 하위 폴더(예: `site/`)에서 deploy 한다. - 빌드 시 쓰는 공개 설정값(VITE_ 등)은 사용자 컴퓨터의 `.env` 에서 읽힌다. ### 글 저장이 필요할 때 (문의·방명록·댓글·신청서 등) — 사이트 DB 서버 코드 없이 chiwaa 사이트 DB 를 쓴다. 사이트 폴더(.chiwaa.json 이 있는 곳, 즉 한 번 deploy 한 뒤)에서: ```bash npx chiwaa db on # DB 켜기(켠 뒤 1분쯤 지나야 사이트에서 동작) npx chiwaa db create guestbook --read public --write public # 누구나 쓰고 누구나 보는 표 npx chiwaa db create inquiries --read owner --write public # 방문자가 보내고 주인만 보는 표(문의) ``` - 표 이름: 영문 소문자로 시작, 영문 소문자·숫자·밑줄 40자까지. 사이트마다 20개까지. - `create` 가 사이트에 붙일 HTML 코드를 출력한다. 핵심: - `` 를 넣는다. - `
` 은 제출하면 자동 저장된다(입력 칸 name 이 저장되는 칸 이름). 스팸 방지용 숨김 칸 `` 을 넣는다. 스크립트로 직접 `add` 할 때도 그 숨김 칸 값을 `_hp` 로 같이 보낸다(값이 있으면 저장하지 않고 성공한 척한다). - 스크립트로: `chiwaa.table("표이름").add({...})`, `chiwaa.table("표이름").list({ limit: 20 })` → 글 배열(각 글에 id, created_at 포함). - 방문자가 쓴 글을 화면에 넣을 때는 반드시 `textContent` 로 넣는다(innerHTML 금지). - **게시판**(한국 사이트에서 가장 많이 쓰는 형태): 글 표(예: posts, 읽기·쓰기 public)와 댓글 표(예: comments, 칸에 post_id)를 만든다. - 목록: `chiwaa.table("posts").list({ limit: 20 })` (최신순), 다음 쪽은 `{ before: 마지막 글 id }`. - 상세: `chiwaa.table("posts").get(id)` — 주소에 `?id=12` 를 붙여 한 페이지에서 처리하면 된다. - 글쓰기 때 `_pw`(비밀번호, 4~64자)를 같이 보내면 글쓴이가 `update(id, {칸들}, 비밀번호)` 로 고치고 `remove(id, 비밀번호)` 로 지운다. update 는 **보낸 칸만** 바뀐다(제목만 보내도 사진·다른 칸은 그대로, 칸을 비우려면 "" 를 보낸다). 비밀번호는 저장된 글 내용에 들어가지 않는다. 각 글의 `_editable` 이 true 면 비밀번호가 걸린 글이다. - 댓글: `chiwaa.table("comments").add({ post_id: id, 이름, 내용, _pw })`, 목록은 `list({ where: { post_id: id }, order: "old" })`. - 같은 사람(IP)이 한 사이트에서 1분 안에 비밀번호를 5번 틀리면, 그 1분이 끝날 때까지 그 사이트의 수정·삭제가 막힌다(맞는 비밀번호도). 맞게 고치는 것은 횟수에 들지 않는다. - 비밀번호 없이 쓴 글은 주인만 chiwaa.kr 사이트 화면의 「DB」에서 지울 수 있다. 그래서 **시험 글은 꼭 `_pw` 를 넣어 쓰고 끝나면 그 비밀번호로 지운다.** - 칸 이름은 한글·영문 모두 된다(글자·숫자·밑줄·띄어쓰기·하이픈, 64자까지). 밑줄(_)로 시작하는 칸은 저장되지 않는다(_pw·_hp 전용). - 글의 `id` 는 표마다 1부터가 아니라 사이트 전체에서 이어지는 번호다. 게시판 「번호」 칸에 그대로 쓰지 말고 목록 순서로 매기거나 날짜를 보여 준다. - 게시판·방명록 화면을 만들 때 지킬 것(검증에서 자주 나온 실수): - 비밀번호는 항상 `` 로 받는다. `prompt()` 로 받지 않는다(화면에 그대로 보인다). 쓰고 나면 입력칸을 비운다. - 오류가 나도 이미 보인 목록·버튼을 지우지 말고, 그 아래에 한국어 안내와 「다시 시도」·「목록으로」를 보여 준다. chiwaa.js 오류는 `e.message` 가 한국어 안내다. - 「더 보기」는 불러오는 동안 버튼을 잠가 같은 글이 두 번 붙지 않게 한다. - 보내기 전에 `trim()` 한 값이 비었는지 검사한다(`required` 는 띄어쓰기만 넣어도 통과한다). - 제목·이름처럼 긴 글자가 들어갈 곳에 `overflow-wrap: anywhere` 를 줘서 휴대폰 화면 밖으로 밀려나지 않게 한다. - 문의·신청서처럼 이름·연락처가 들어가는 표는 반드시 `--read owner` 로 만들고, 사이트에서 읽히지 않는다고 public 으로 바꾸지 않는다(개인정보가 공개된다). - 읽기 권한이 owner 인 표는 사이트에서 읽을 수 없다. 주인은 `npx chiwaa db rows <표>` 나 chiwaa.kr 화면(내 사이트 → 그 사이트 「자세히」 → 「DB」 → 표 이름 줄의 「데이터 보기」)에서 본다. 사용자에게 이 경로를 그대로 알려 준다. - 같은 방문자(IP)는 한 사이트에 1분에 10번까지 저장할 수 있다. - 상태 보기 `npx chiwaa db`, 권한 바꾸기 `npx chiwaa db rules <표> --read public`. - DB 끄기·표 지우기·글 지우기는 CLI 에 없다(데이터가 지워지므로). 사용자에게 chiwaa.kr 사이트 화면의 「DB」에서 하라고 안내한다. 시험 주문처럼 주인 전용 표에 남은 시험 데이터도 그 화면에서 지운다. - 카카오 로그인·결제는 브라우저 코드만으로 만들지 않는다. 아래 「서버 함수」의 검증된 견본을 쓴다. ### 사진 올리기 (게시판 사진 첨부·후기 사진·상품 사진) 사진은 사이트 DB 와 함께 쓴다(먼저 `npx chiwaa db on`). ```bash npx chiwaa files on # 방문자 사진 올리기 켜기(게시판 사진 첨부용, 1분쯤 뒤 동작) npx chiwaa files put 상품1.jpg # 주인이 올리기 → 주소가 나온다(상품·메뉴 사진 등) npx chiwaa files # 목록·용량 ``` - 가장 쉬운 방법: `` 안에 `` 를 넣는다. 제출하면 사진을 먼저 올리고 그 주소(`/_chiwaa/files/`)를 글의 `사진` 칸에 넣어 저장한다(여러 장이면 줄바꿈으로 이어짐). - 스크립트로: `const p = await chiwaa.files.upload(file)` → `{ id, url, thumb, width, height }`. 그다음 글에 `url` 을 넣어 저장한다: `chiwaa.table("posts").add({ 제목, 내용, 사진: p.url, _pw })`. - 보여 줄 때: `img.src = item.사진` — 목록에는 작은 그림 `url + "-s"`(긴 변 400px)를 쓴다. **값이 `/_chiwaa/files/` 로 시작하는 22자 id 일 때만** 그림으로 넣는다(방문자가 다른 주소를 넣었을 수 있다). `innerHTML` 로 넣지 않는다. - 올린 사진은 긴 변 2000px 로 줄고 위치(GPS) 정보가 지워지며, 브라우저에 맞춰 AVIF·WebP 로 나간다. 받는 형식: JPG·PNG·WebP·GIF(첫 장면만)·HEIC(아이폰). PDF·문서·동영상은 받지 않는다. - **방문자가 올린 사진은 글에 넣어야 남는다.** 24시간 안에 어느 글에도 안 쓰이면 지워지고, 글을 지우거나(비밀번호 삭제 포함) 글에서 사진 주소를 빼면 그 사진도 지워진다. 주인(`files put`·화면)과 서버 함수가 올린 사진은 자동으로 지우지 않는다. - 한도(사이트마다): 무료 1GB·한 장 10MB·방문자 하루 500장, 프로 10GB·20MB·5,000장, 비즈니스 50GB·20MB·50,000장. 같은 방문자(IP)는 1분에 5장. 용량을 넘기면 올리기만 멈춘다(추가 요금 없음). - 서버 함수에서: `const { url } = await env.FILES.put(file)`(Blob·File·ArrayBuffer, 예: `(await request.formData()).get("photo")`), 지우기 `env.FILES.remove(id)`. - 사진 지우기는 CLI 에 없다. 사용자에게 chiwaa.kr 사이트 화면 「DB」 → 「사진」에서 하라고 안내한다. ### 내 도메인 (예: haesol.co.kr) 도메인은 x-y.net(엑스와이넷, chiwaa 운영사)에서 사고 바로 붙인다. 사이트 폴더에서: ```bash npx chiwaa domains search haesol # 살 수 있는 도메인과 1년 요금 npx chiwaa domains buy haesol.co.kr # x-y.net 신청·결제 화면을 브라우저로 연다 npx chiwaa domains # 상태 · 내 x-y.net 도메인 목록 npx chiwaa domains add haesol.co.kr # 이 사이트에 붙이기(도메인과 www 둘 다) npx chiwaa domains check # 몇 분 뒤 연결 확인 ``` - **결제는 사람이 x-y.net 결제창에서 직접 한다. AI 는 결제를 대신하거나 결제 정보를 다루지 않는다.** buy 를 실행한 뒤 사용자에게 "열린 화면에서 결제해 주세요"라고 안내하고, 결제가 끝났다고 하면 add 를 한다. - 처음 한 번은 x-y.net 계정 연결이 필요하다. `npx chiwaa domains` 가 연결 주소를 알려 주면 사용자에게 브라우저에서 열어 로그인·동의하라고 안내한다. - **다른 곳(가비아·카페24·후이즈·Cloudflare 등)에서 산 도메인**(유료 요금제)도 직원 없이 붙는다: 1. `npx chiwaa domains add example.co.kr` → 넣을 레코드 3개가 나온다(A `@` → chiwaa IP, CNAME `www` → <사이트>.chiwaa.com, TXT `_chiwaa` → chiwaa-verify=확인코드). 2. 사용자가 도메인을 산 곳의 「DNS 관리」(가비아: My가비아 → 도메인 → DNS 관리 / 카페24: 도메인 관리 → DNS 관리 / Cloudflare: DNS → Records) 에서 넣는다. AI 는 화면에서 어느 칸에 무엇을 넣는지 하나씩 안내한다. 3. `npx chiwaa domains check` — 안 되면 무엇이 지금 어떻게 보이는지 알려 준다. 그걸 보고 고친다. - 자주 막히는 곳: 호스트 칸에는 `_chiwaa` 만 적는다(뒤에 도메인을 붙이면 `_chiwaa.example.co.kr.example.co.kr` 이 된다). `@` 를 못 쓰는 곳은 호스트를 비운다. 원래 있던 A 레코드(주차 페이지 등)는 지운다. Cloudflare 는 주황 구름(프록시)을 끄고 「DNS only」로. 반영까지 몇 분~몇 시간 걸릴 수 있다. - 하위 주소(shop.example.co.kr)도 붙일 수 있다. 이때 호스트 칸에는 `shop`·`www.shop`·`_chiwaa.shop` 처럼 add 가 보여 주는 이름을 그대로 넣는다. - 확인 코드(TXT)로 도메인 주인이 맞는지 본다. 확인 전에는 사이트에 붙지 않는다. https 인증서는 붙은 뒤 첫 접속 때 자동으로 받는다. - 무료 요금제는 x-y.net 도메인만 된다. - 연결 끊기 `npx chiwaa domains remove -y` (도메인은 x-y.net 계정에 그대로 남는다). ### 주소·404·사진 (자동) - React·Vue 라우터 같은 앱(SPA)은 따로 설정하지 않아도 된다. `/about` 처럼 파일이 없는 주소는 `index.html` 을 준다(새로고침·공유해도 열림). 단 사이트에 `404.html` 이 있으면 SPA 로 보지 않고 없는 주소에 그 404 페이지를 준다. - `.html` 은 생략해도 된다: `/board` → `board.html`, `/docs` → `docs/index.html`. - 리다이렉트: 사이트 맨 위에 `_redirects` 파일(Netlify 형식)을 두면 배포 때 적용된다. 한 줄에 `보낼주소 받을주소 [상태]`. 예) `/old /new 301`, `/blog/* /news/:splat 301`, `/item/:id /goods/:id 302`, `/go https://example.com`, `/app/* /index.html 200`(주소는 두고 그 파일을 보여 줌, 사이트 안 주소만). 상태는 301·302·303·307·308·200 만. 규칙은 100개까지. `vercel.json`·`netlify.toml` 은 읽지 않으니 `_redirects` 로 옮긴다. `_redirects` 파일 자체는 공개되지 않는다. - jpg·png 사진은 올릴 때 자동으로 WebP 로 바뀌고 잠시 뒤 AVIF 도 만들어진다. 주소는 원래 그대로(`photo.jpg`)이고, 브라우저에 맞춰 AVIF·WebP·원본 중 하나가 간다. 가로 2000px 보다 크면 2000px 로 줄어들며, 촬영 위치(GPS) 같은 정보는 지워진다. 사진을 미리 줄일 필요는 없지만, 화면에 맞는 크기로 `width`·`height` 를 지정하면 더 빠르다. ### 서버 함수 (카카오 로그인·결제 승인·외부 API 처럼 비밀 키가 필요한 일) 사이트 폴더 맨 위 `api/` 에 파일을 두면 `https://<사이트>/api/<파일이름>` 으로 서버에서 실행된다(빌드 프로젝트도 맨 위 `api/`). ```js // api/pay-confirm.js — 반드시 export default (Request, env) => Response export default async function (request, env) { const { paymentKey, orderId, amount } = await request.json(); const r = await fetch("https://api.tosspayments.com/v1/payments/confirm", { method: "POST", headers: { Authorization: "Basic " + btoa(env.TOSS_SECRET_KEY + ":"), "Content-Type": "application/json" }, body: JSON.stringify({ paymentKey, orderId, amount }), }); return Response.json(await r.json(), { status: r.status }); } ``` - 비밀 키는 코드에 적지 말고 `echo 값 | npx chiwaa env set TOSS_SECRET_KEY` 로 넣는다(TTY 면 직접 입력). 코드에서는 `env.TOSS_SECRET_KEY`. 목록 `npx chiwaa env`, 지우기 `npx chiwaa env rm 이름`. 1분 안에 반영된다. 비밀값을 출력·로그·응답에 넣지 않는다. - 실행 환경: Deno 기반 Web 표준(`fetch`·`Request`·`Response`·`crypto`). `npm:패키지` 가져오기 가능. 파일 읽기·쓰기 안 됨. `_` 로 시작하는 파일은 주소가 생기지 않는 공용 코드(`import ... from "./_lib.js"`). - 한도(사이트마다): 무료 월 50만 회·요청당 CPU 50ms·10초, 프로 500만 회·200ms·30초, 비즈니스 2,000만 회·1초·30초. 넘으면 추가 요금 없이 429(그달 말까지). CPU 를 오래 쓰는 일(이미지 변환 등)은 하지 않는다 — 바깥 API 를 기다리는 시간은 CPU 에 안 들어간다. - 사진: `env.FILES.put(사진)` → `{ id, url, thumb, ... }`, `env.FILES.remove(id)` (위 「사진 올리기」). - 사이트 DB: DB 를 켠 사이트(`npx chiwaa db on`)는 서버 함수에서 `env.DB.table("orders")` 로 쓴다 — `.add({...})`, `.get(id)`, `.list({ limit, where: { 칸: 값 } })`, `.update(id, { status: "paid" })`(보낸 칸만 바뀜), `.remove(id)`. **주인 권한**이라 `--read owner`·`--write owner` 표도 읽고 쓴다 → 결제 상태처럼 방문자가 바꾸면 안 되는 값은 쓰기 권한 owner 표에 두고 서버 함수에서만 바꾼다. DB 가 꺼져 있으면 `env.DB` 는 null. - 기록: `console.log`·`console.error` 와 오류는 `npx chiwaa logs`(--lines 100)와 chiwaa.kr 사이트 화면에 남는다(1분쯤 늦을 수 있음). 요청 하나에 20줄·한 줄 500자까지. 비밀값·개인정보는 찍지 않는다. - 서버 함수는 chiwaa 내부 서버로 접속할 수 없다(사이트 DB 는 env.DB 로만). - 결제 승인처럼 금액이 걸린 일은 서버 함수에서 금액을 다시 확인한다(브라우저가 보낸 금액을 믿지 않는다). - **검증된 견본(그대로 가져다 고쳐 쓴다)**: - 토스페이먼츠 결제: https://chiwaa.kr/samples/toss/order-create.js (서버가 주문·금액을 정함) · https://chiwaa.kr/samples/toss/pay-confirm.js (주문 금액과 대조 → 승인 → orders 표에 paid). 표: `npx chiwaa db create orders --read owner --write owner`, 비밀값 `TOSS_SECRET_KEY`. 화면: https://chiwaa.kr/samples/toss/checkout.html (결제위젯 v2, 클라이언트 키는 화면에 둬도 됨) · success.html (pay-confirm 호출 — 이걸 불러야 결제가 끝난다) · fail.html. 사이트 맨 위에 그대로 두면 주소가 맞는다. orders 처럼 쓰기 「나만」 표는 브라우저 폼·chiwaa.table().add 로 쓰지 않는다(403). 권한을 「누구나」로 바꾸지 말고 서버 함수에서 env.DB 로 쓴다. - 카카오 로그인: https://chiwaa.kr/samples/kakao/kakao-login.js · kakao-callback.js · _session.js(서명 쿠키) · me.js(로그인 확인). 비밀값 `KAKAO_REST_KEY`, `SESSION_SECRET`(긴 무작위 문자), 필요하면 `KAKAO_CLIENT_SECRET`. 카카오 개발자 센터 Redirect URI 는 `https://<사이트>/api/kakao-callback`. 회원 표(선택): `npx chiwaa db create members --read owner --write owner`. - 오래 안 쓰면: 무료 회원이 6개월 로그인하지 않아 사이트가 멈추면 서버 함수·비밀값도 함께 꺼진다. 90일 넘게 실행이 없으면 `npx chiwaa env` 가 비밀값 정리를 권한다. ### 미리보기·잠금·사용량 - 미리보기: `npx chiwaa deploy -y --preview` → `이름--preview.chiwaa.com` 에 따로 올라간다(운영 주소는 그대로). 사용자가 확인하고 괜찮다고 하면 `--preview` 없이 다시 deploy. 미리보기는 검색엔진에 나오지 않지만 **DB 는 실제 사이트 것을 같이 쓴다**(시험 글 주의). - 깃허브 연결 사이트: 운영 브랜치(보통 main)가 아닌 브랜치에 push 하면 `이름--브랜치.chiwaa.com` 에 미리보기가 자동으로 올라가고, 커밋 상태(PR 의 chiwaa 「Details」)에 그 주소가 걸린다. 브랜치 이름의 `/`·`_` 등은 `-` 로 바뀐다(예: `feature/new-hero` → `이름--feature-new-hero`). 사이트당 10개, 브랜치를 지우면 미리보기도 지워진다. DB·서버 함수·비밀값은 운영과 같이 쓴다. - 비밀번호 잠금(공개 전 나만 보기): `echo 비밀번호 | npx chiwaa lock` (TTY 면 직접 입력), 풀기 `npx chiwaa unlock`. 브라우저가 아이디 `chiwaa` 와 그 비밀번호를 묻는다. 미리보기·붙인 도메인도 같이 잠긴다. 비밀번호를 명령 줄 인자로 적지 않는다. - `npx chiwaa usage` — 요금제·이번 달 사이트별 전송량·저장 한도. `npx chiwaa open` — 관리 화면을 브라우저로 연다(`--site` 는 사이트). ### 방문자 통계 `npx chiwaa stats` (최근 7일, `--days 30`) — 오늘 방문자·페이지 보기, 날짜별 방문자, 많이 본 페이지, 들어온 곳(네이버·구글·인스타그램 등), 휴대폰 비율. 10분마다 갱신되고, 사람이 본 화면만 센다(검색 로봇·프로그램·해킹 탐색 주소 제외). 방문자 IP 는 저장하지 않는다. chiwaa.kr 사이트 화면의 「방문자」에서도 본다. 따로 분석 스크립트(구글 애널리틱스 등)를 넣지 않아도 된다. ### 올릴 수 없는 것(악용 방지) - 앱 설치·실행 파일(.apk .exe .msi .bat .jar .dmg .ipa 등)과 `.env*` 는 올릴 때 빠진다(배포는 계속되고 「뺀 파일」로 알림). 앱은 플레이스토어·앱스토어 링크로 안내한다. - 사이트 이름에 은행·플랫폼·공공기관 이름(kakao, naver, toss, 은행·카드사·택배사, hometax, police 등)이 들어가면 만들 수 없다. 서비스·프로젝트 이름으로 짓는다. - 피싱·사칭 화면, 카드번호·주민번호를 직접 받는 폼은 자동 감시에 걸려 직원이 확인한다(약관 제11·12조). 결제는 결제사 화면(토스 위젯)으로, 로그인은 카카오 견본으로 만든다. ### 컨테이너 (서버 앱 그대로) 깃허브 push 와 `npx chiwaa deploy` 모두 서버 코드를 그대로 돌린다. CLI 는 서버 앱이면 결과물 대신 소스를 보내고(`node_modules`·`.git`·`.next`·`.env*`·`.gitignore` 의 단순한 줄은 빼고) 빌드 서버가 빌드한다(보통 1~3분). 고르는 기준: - Next.js 에 API 라우트·middleware·서버 액션·SSR 이 있으면 `output: 'standalone'` 을 빌드 동안만 덧씌워 컨테이너로 실행(설정 파일은 고치지 않아도 된다). - 정적 빌드 도구가 아닌 Node 앱(Express·Fastify·Nest 등)은 `package.json` 의 `start`(있으면 `build` 먼저)로 실행. - 정적 결과가 없고 맨 위에 `Dockerfile` 이 있으면 그대로 빌드. 파이썬 등은 Dockerfile 을 만든다. - 앱은 환경변수 `PORT`(3000)에서 듣게 한다(`0.0.0.0`). 사이트 「설정값」이 빌드·실행 환경변수로 들어간다. 디스크는 배포마다 새로 시작하니 저장은 사이트 DB·사진 저장·외부 DB 로. - 요금제: 무료 1개·256MB, 프로 3개·512MB, 비즈니스 10개·1GB(항상 켬). 무료·프로는 30분 요청이 없으면 잠들고 다음 요청에서 약 3초에 깨어난다. 브랜치 미리보기도 컨테이너로 따로 뜬다(개수에 안 셈). - 사이트 DB(주인 권한): DB 를 켠 사이트의 컨테이너에는 `CHIWAA_DB_URL`·`CHIWAA_DB_SITE`·`CHIWAA_DB_TOKEN` 환경변수가 있다. `fetch(process.env.CHIWAA_DB_URL + "orders", { method: "POST", headers: { "Content-Type": "application/json", "X-Chiwaa-Fn-Site": process.env.CHIWAA_DB_SITE, "X-Chiwaa-Fn-Token": process.env.CHIWAA_DB_TOKEN }, body: JSON.stringify({...}) })` — GET `표?limit=20`·`표/번호`, PATCH `표/번호`(보낸 칸만), DELETE `표/번호`. 읽기 「나만」 표도 읽힌다. `npx chiwaa db on` 뒤 한 번 다시 배포해야 들어간다. 토큰은 출력·응답에 넣지 않는다. - 관리형 Postgres 16: `npx chiwaa pg create`(또는 사이트 화면) → 다시 deploy 하면 컨테이너에 `CHIWAA_PG_URL`, 설정값에 없으면 `DATABASE_URL` 로도 들어간다. 사이트 전용 DB·계정, 컨테이너에서만 접속(내 컴퓨터에서 직접 접속은 안 됨 — 마이그레이션은 앱 시작 명령에 `prisma migrate deploy && node server.js` 처럼), 쿼리 30초 한도, 용량(무료 256MB·프로 2GB·비즈니스 10GB) 넘으면 읽기 전용, 매일 백업. 상태 `npx chiwaa pg`, 비밀번호 새로 `npx chiwaa pg password`(그 뒤 다시 deploy). - Supabase: `supabase-js`(https)는 그대로. Postgres 직접 접속(Prisma·Drizzle·pg)은 **Connection pooler 주소**(`aws-0-<리전>.pooler.supabase.com`, 5432/6543)를 쓴다. `db..supabase.co` 는 IPv6 전용이라 컨테이너에서 닿지 않는다. - 컨테이너에서 자기 사이트·다른 chiwaa 사이트 주소(https)는 부를 수 있다. 우리 내부망·메일(25)은 막혀 있다. - 실패하면 `npx chiwaa logs`(컨테이너 앱 기록, `-f` 이어서 보기)로 원인을 본다. 개수 한도를 넘으면 어느 사이트가 쓰는지 알려 준다. ### 지원하지 않는 것 PHP·MySQL(엑스와이넷 웹호스팅 안내). ### Vercel 의 Next.js 앱 옮기기 - **그대로 올리기**: 깃허브 저장소를 연결하거나 앱 폴더에서 `npx chiwaa deploy`. 서버 기능이 있으면 컨테이너, 없으면 정적 내보내기로 자동 처리한다. `vercel.json` 리다이렉트는 `_redirects` 로 옮기고, 환경변수는 사이트 「설정값」에 넣는다. - **정적 사이트로 바꾸고 싶을 때(컨테이너 개수를 아끼려면)**: `next.config` 에 `output: 'export'`, `images: { unoptimized: true }` 를 넣고, API 라우트·서버 액션은 맨 위 `api/이름.js` 서버 함수로 옮겨 `fetch('/api/이름')` 으로 부른다. 비밀 키는 `npx chiwaa env set`. `middleware.ts` 는 지운다. `[id]` 동적 주소는 `generateStaticParams` 또는 `?id=` 쿼리로. - 앱이 하위 폴더(예: `landing/`)에 있으면 깃허브 연결은 자동으로 찾고(앱이 하나일 때), CLI 는 그 폴더에서 실행한다. ## 그 밖의 명령 - `npx chiwaa list` — 내 사이트 목록 - `npx chiwaa versions` — 남아 있는 버전(사이트 폴더에서) - `npx chiwaa rollback [버전]` — 한 단계 전 또는 지정 버전으로 되돌리기 - `npx chiwaa whoami` — 로그인한 계정·요금제 ## 요금 - 무료: 사이트 3개, 사이트마다 월 전송량 100GB, 상업용 가능(chiwaa 표시 붙음) - 프로: 월 9,900원(1년 99,000원), 사이트 무제한, 사이트마다 월 1TB - 비즈니스: 월 19,900원(1년 199,000원), 사이트 무제한, 사이트마다 월 3TB - 금액은 부가세 포함. 전송량을 넘겨도 추가 요금은 없고 그달 말까지 느려진다. - 출시 이벤트: 2026년 12월 31일까지 가입·로그인하면 프로를 무료로 쓴다. 자세히: https://chiwaa.kr/pricing ## 링크 - 서비스: https://chiwaa.kr - 요금: https://chiwaa.kr/pricing - 도움말: https://chiwaa.kr/help