시작

로컬 시험 서버 실행

로컬 머신에 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 Engine28 이상
Docker Compose2.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 status

api·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 down

scripts/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 oldDocker 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로 멈추므로 새 세션을 연다

다음 단계

  • SDK 설치: SDK로 이 서버에 붙고 첫 세션을 만든다
  • 셀프 호스팅: 여러 사람이 쓰는 서버를 운영한다

이 페이지