로컬 시험 서버 실행
로컬 머신에 Werft 서버를 띄우고 API key를 받는다
Werft 서버는 API 서버, scheduler, reconciler, 세션마다 뜨는 worker 컨테이너, PostgreSQL, S3(SeaweedFS), 예시 저장소를 내주는 읽기 전용 Git 서버, egress proxy로 이뤄진다. 이 페이지는 이 전부를 Docker Compose로 한 머신에 띄운다. 모델은 key 없이 도는 fake 모델을 쓰므로 Anthropic 계정이 없어도 된다.
다 띄우면 서버 주소는 http://127.0.0.1:3000이다. SDK와 curl 예제는 이 주소와 여기서 받는 API key로 서버에 붙는다.
준비물
| 항목 | 버전 |
|---|---|
| Docker Engine | 28 이상 |
| Docker Compose | 2.24.6 이상 |
| curl, jq, uuidgen, git | 아무 버전 |
스택은 127.0.0.1에만 포트를 연다. 3000(API·웹 콘솔), 5432(PostgreSQL), 4566(S3), 4567(LocalStack Secrets Manager), 3001(읽기 전용 Git 서버)이 비어 있어야 한다.
docker version --format 'Docker Engine {{.Server.Version}}'
docker compose version
for p in 3000 5432 4566 4567 3001; do
lsof -nP -iTCP:$p -sTCP:LISTEN >/dev/null 2>&1 && echo "사용 중: $p"
done사용 중: 줄이 없으면 된다.
받기
git clone https://github.com/JeongJaeSoon/werft.git
cd werft띄우기
scripts/local.sh up --fake-model처음에는 이미지를 이 checkout에서 빌드하므로 몇 분에서 10분쯤 걸린다. 준비가 끝나면 마지막 줄에 다음이 나온다.
{"status":"ready","checks":{"database":"ok","schema":"ok","config":"ok"}}--fake-model을 붙이면 모델 호출을 compose 안의 fake Messages API가 받는다. worker 안에서는 진짜 Claude Code가 돌고, fake는 메시지에 적힌 대본대로 답한다(첫 세션 만들기). 옵션 없이 scripts/local.sh up으로 띄우면 실제 Claude를 부르고 비용이 든다. 모델 key는 콘솔의 설정 > 에이전트 연결 > 모델 연결 > 연결 추가에서 넣는 것이 기본이고, 셸의 ANTHROPIC_API_KEY로 주는 것은 대안이다. key 없이 띄우면 fake로 바뀌지 않고 모델 연결이 없는 상태로 뜬다.
상태 보기
scripts/local.sh statusapi·scheduler·reconciler가 running이고 끝에 /readyz 응답이 있으면 된다. worker 컨테이너는 상주하지 않는다. scheduler가 세션마다 띄우고 지운다.
API key 받기
API=http://127.0.0.1:3000
KEY=$(scripts/local.sh key quickstart \
--scopes sessions:read,sessions:write,sessions:approve,sessions:control,sessions:recover)
echo "${KEY:0:4}…"key_id …
csp_…key_id는 stderr로 나오는 key의 id다. key 자체는 stdout에 한 번만 나온다. 다시 볼 수 없으니 변수에만 둔다. quickstart는 key의 owner 이름이고, 이 key로 만든 세션은 이 owner의 것이다. scope는 API key에 있다.
SDK에는 baseUrl로 서버 주소(API)를, apiKey로 이 key를 넘긴다(SDK 설치). WERFT_API_KEY="$KEY"처럼 환경 변수로 넘겨도 된다. HTTP API 예제는 API와 KEY를 같은 터미널에서 이어 쓴다.
내리기
scripts/local.sh downscripts/local.sh down은 스택과 모든 데이터(세션, checkpoint, API key)를 지운다. 처음부터 다시 하려면 scripts/local.sh reset --fake-model이다.
데이터를 보존하고 worker 컨테이너·네트워크도 정리하려면 scripts/local.sh down --keep-volumes를 쓴다. 다시 scripts/local.sh up --fake-model로 띄우면 PostgreSQL·S3 named volume의 데이터가 남는다. S3 객체와 암호화 키는 local-s3-data에 함께 저장되므로 Docker/OrbStack 재시작 뒤에도 checkpoint를 읽을 수 있다.
이전 LocalStack 설치에서 전환할 때는 pull 전에 옛 checkout에서 백업하고, pull 뒤 사용한 적 없는 새 프로젝트에 복원한다. 이미 유실된 checkpoint는 복원할 수 없으므로 복구 가능한 백업을 찾거나 유실 참조를 명시적으로 해제해야 한다. 전환·백업 안내를 따른다.
막혔을 때
| 증상 | 조치 |
|---|---|
Docker Engine … is too old | Docker Engine을 28 이상으로 올린다 |
127.0.0.1 port(s) … already in use | 위 lsof 루프로 그 포트를 쓰는 프로세스를 찾는다 |
up이 no ANTHROPIC_API_KEY … no model connection을 출력하고 세션이 연결 없음(connection_missing)으로 거절된다 | 옵션 없는 up은 실제 Claude를 쓰고 key 없이도 뜬다. 설정 > 에이전트 연결 > 모델 연결 > 연결 추가에서 key를 넣는다. 모델 계정 없이 하려면 --fake-model을 붙인다 |
| Docker를 재시작한 뒤 API가 뜨지 않는다 | S3 volume과 암호화 키를 확인하고 로그를 읽는다. 이전 LocalStack의 객체 유실이면 전환·백업 안내의 복구 결정을 따른다 |
pull 뒤 up이 has neither an image nor a build context specified나 port is already allocated로 끝난다 | Git 서버의 서비스 이름이 fake-git으로 바뀌었다. 포트 override 파일의 키를 고치고 scripts/local.sh down --keep-volumes 뒤 다시 up한다. 옛 세션은 CATALOG_MISMATCH로 멈추므로 새 세션을 연다 |