노드 시작
'노드'는 zqagent가 실행되는 머신입니다. 이 기기에 작업 디렉터리, 모델 구성, 세션 데이터를 가지며 이 기기에서만 사용할 수도 있고, 사용자 센터에 연결해 원격에서 관리·조회할 수도 있습니다.
이 페이지에서는 노드의 시작, 상주, 연결 방법을 설명합니다.
세 가지 실행 형태
| 형태 | 시작 방법 | 적합한 용도 |
|---|---|---|
| 대화형 CLI | zqagent | 이 기기에서 대화하며 작업. 가장 일반적 |
| 상주 서비스 노드 | zqagent serve | 서버나 상시 켜진 머신에서 원격 관리용으로 실행 |
| 데스크톱 앱 | 데스크톱 앱 설치 | GUI가 필요할 때. 상주 서비스와 같은 자동 시작 노드 공유 |
데스크톱 앱과 상주 서비스 노드는 같은 노드 서비스(같은 데이터 디렉터리와 포트)이며 조작 화면만 다릅니다. 데스크톱 앱을 설치한 뒤 install.sh를 실행해도 두 번째 노드가 생기지 않습니다. 대화형 CLI는 현재 디렉터리의 독립 데이터를 사용합니다. 세 가지는 필요에 따라 조합할 수 있습니다.
대화형 CLI
zqagent대화형 화면에 들어가 자연어로 작업을 입력합니다. 모델은 /connect로 설정합니다 (빠른 시작 참고). 전체 명령은 CLI 사용을 참고하세요.
대화형 CLI는 '이 기기에서 사용 가능한' 노드이지만 포트를 열지 않아 원격 관리할 수 없습니다. 원격 관리가 필요하면 아래
zqagent serve를 사용하세요.
상주 노드 시작
zqagent serve는 화면 없이 서비스를 시작하고 HTTP 포트를 열어 백그라운드에서 실행합니다.
zqagent serve시작 후 로그에 대기 주소, 데이터 디렉터리, 노드 ID, 데모 테넌트 정보가 출력됩니다 (첫 시작 시 데모 테넌트 demo를 자동 생성하고 그 apiKey를 무작위 생성해 시작 로그에 출력합니다. 이 기기 디버깅에 바로 쓸 수 있습니다).
인수
| 인수 | 설명 | 기본값 |
|---|---|---|
--port <n> | 대기 포트. 사용 중이면 다음 빈 포트로 자동 변경(실제 포트는 데이터 디렉터리 server-port, 로그에도 표시) | 8787(또는 환경 변수 PORT) |
--host <addr> | 대기 주소. 0.0.0.0이면 외부 접근 허용 | 127.0.0.1(또는 HOST) |
--data-dir <dir> | 데이터 디렉터리(프로젝트, 세션, 원장, 자격 증명) | ./.zqagent_data(또는 DATA_DIR) |
--hub <url> | 사용자 센터 주소. --enroll-code와 함께 시작 시 연결 | — |
--enroll-code <code> | 일회용 연결 코드 | — |
--label <name> | 노드 표시 이름 | 호스트 이름 |
기본은
127.0.0.1만 대기, 즉 이 기기에서만 접근 가능하며 가장 안전합니다. LAN/공인 접근이 꼭 필요할 때만--host 0.0.0.0을 설정하고 방화벽과 접근 제어에 주의하세요.
백그라운드 상주
포그라운드 실행은 터미널을 닫으면 종료됩니다. 장기 운영에서는 시스템 서비스로 설치하세요(자동 시작 + 크래시 시 자동 복구).
Windows: systemd / launchd가 없습니다. '작업 스케줄러'에서 '로그온 시 실행' 작업을 만들고 프로그램에 zqagent.exe 절대 경로, 인수에 serve --port 8787 --data-dir "%APPDATA%\zqagent"를 넣습니다. zqagent.exe serve ... 바로 가기를 시작 프로그램 폴더(Win+R → shell:startup)에 넣어도 됩니다. 중지/재시작은 작업 스케줄러나 작업 관리자에서 합니다.
권장: 명령 하나(최신 단일 파일 자동 다운로드, 서비스 설치, 자동 업데이트 활성화. 단일 파일 설치 참고):
curl -fsSL https://agent.cd-zq.com/install.sh | sudo sh설치 후:
sudo sh -s -- status # 실행 상태
sudo sh -s -- logs # 로그 추적
sudo sh -s -- restart # 재시작
sudo sh -s -- rollback # 직전 자동 업데이트 이전으로 롤백
sudo sh -s -- uninstall # 중지 및 제거(sudo sh -s -- <하위 명령>과 curl ... | sudo sh -s -- <하위 명령>은 동일합니다. 스크립트를 내려받았다면 sudo sh install.sh status도 가능.)
리포지토리 소스에서 설치(개발 머신 / npm 설치 시). macOS는 launchd, Linux는 systemd:
# 리포지토리의 deploy/service 디렉터리에서 실행
bash install.sh install # 설치 및 시작(자동 시작)
bash install.sh status # 실행 상태
bash install.sh logs # 로그 추적
bash install.sh restart # 재시작
bash install.sh uninstall # 중지 및 제거기본 데이터 디렉터리: macOS ~/Library/Application Support/zqagent, Linux ~/.zqagent_data. 로그: macOS ~/Library/Logs/zqagent/node.log, Linux ~/.zqagent_data/node.log. (Linux 초기 버전은 /var/lib/zqagent. 기존 설치 인스턴스는 스크립트가 원래 unit의 경로를 이어받으며 마이그레이션하지 않습니다.) PORT / HOST / DATA_DIR / LOG / SERVICE_NAME으로 덮어쓸 수 있습니다. 예:
sudo PORT=9000 DATA_DIR=/data/zqagent bash install.sh install서비스는 '절대 경로 node + CLI 진입점'으로 시작하며 nvm/volta의 PATH에 의존하지 않습니다. Linux의 추가 환경 변수(LLM key, HUB_URL, SECRET_KEY 등)는 /etc/zqagent.env에 쓸 수 있습니다. 중지는 SIGTERM으로 하며 serve는 원장을 저장한 뒤 종료합니다(유예 기본 3초, ZQAGENT_SHUTDOWN_GRACE_MS로 조정).
스크립트는 현재 CLI가
serve를 지원하는지 검증합니다. 오래된 버전(0.1.33 등)에는 이 하위 명령이 없어 먼저npm i -g @zqagent/core@latest하지 않으면 프로세스가 조용히 대화형 세션으로 들어갑니다.
systemd unit 직접 작성(스크립트를 쓰지 않을 때)
# /etc/systemd/system/zqagent.service
[Unit]
Description=zqagent node
After=network-online.target
[Service]
# <사용자명>을 실제로 노드를 실행할 사용자로 바꾸세요. 데이터는 그 사용자의 홈에 두면 권한이 자연스럽게 귀속됩니다
User=<사용자명>
ExecStart=/usr/local/bin/zqagent serve --port 8787 --data-dir %h/.zqagent_data
Restart=always
RestartSec=3
KillSignal=SIGTERM
TimeoutStopSec=15
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now zqagent
journalctl -u zqagent -f # 로그 보기pm2(대안)
명령 전체를 하나의 문자열에 넣지 마세요(bash -c 스크립트로 취급되어 인수가 사라지고 대화형 세션으로 돌아갑니다):
pm2 start "$(command -v zqagent)" --name zqagent -- serve --port 8787 --data-dir "$HOME/.zqagent_data"
pm2 save && pm2 startup # 자동 시작nohup(임시 디버깅)
nohup zqagent serve --port 8787 --data-dir "$HOME/.zqagent_data" \
> "$HOME/.zqagent_data/node.log" 2>&1 &자동 업데이트
단일 파일(SEA)로 설치하고 시스템 서비스가 관리하면 노드가 스스로 버전을 유지합니다. 새 머신에서는 단일 파일 설치의 한 명령을 권장합니다. 바이너리와 서비스를 함께 준비합니다:
- 시작 5분 후 한 번 확인하고 이후 6시간마다(±15% 지터)
- 새 버전이 있으면 조용히 다운로드하고 SHA-256을 검증한 뒤
--version으로 자체 점검 - 연속 60초 유휴(실행 중도, 승인/답변 대기도 없는 세션이 없음)를 기다린 뒤 자신을 교체하고 종료
- systemd / launchd가 새 버전을 띄우고 콘솔 버전도 자동 갱신
실패해도 노드 동작에는 영향이 없습니다. 다운로드/검증 실패는 로그만 남기고, 같은 버전에서 3회 연속 실패하면 건너뜁니다.
전제 조건
자동 업데이트는 다음 세 조건이 모두 충족될 때만 동작합니다(하나라도 없으면 무효):
- 단일 파일 형태(SEA 산출물로 시작.
node dist/cli/index.js가 아님) - systemd / launchd가 관리(
install.sh로 설치) - 검증 공개 키
ZQAGENT_UPDATE_PUBKEY설정
npm으로 설치한 노드는 자동 교체되지 않습니다.
npm i -g @zqagent/core@latest로 업그레이드하세요.
macOS: 관리 판정은 Linux와 같습니다. 서비스 프로세스 안에서는 그대로 동작합니다. 터미널에서 수동 실행하는
zqagent update --status/--check/--now도 launchd 작업(pid / program)과 plist의EnvironmentVariables에서 관리 상태, 공개 키, 채널을 자동 인식하므로 환경 변수를source할 필요가 없습니다. 제거는sudo sh -s -- uninstall.
Windows: systemd / launchd가 없어 단일 파일 노드는 자동 업데이트되지 않습니다(
zqagent update --status는 '서비스 관리 미관리(포그라운드/nohup)'로 표시). 업그레이드는serve프로세스를 중지하고 새로 받은 exe로 덮어쓴 뒤 다시 시작하세요.zqagent update --now는 미관리 환경에서 거부됩니다.
설치 스크립트는 기본으로 공개 키를 받아오므로 한 명령으로 설치 + 자동 업데이트 활성화가 완료됩니다:
curl -fsSL https://agent.cd-zq.com/install.sh | sudo sh대역 외에 보관한 공개 키로 자동 획득을 덮어쓰려면 --pubkey "..."를 붙입니다(명시한 공개 키가 우선하며 네트워크 획득으로 덮어쓰지 않음).
스위치와 구성
| 환경 변수 | 기본값 | 설명 |
|---|---|---|
ZQAGENT_AUTO_UPDATE | 1 | 0이면 자동 업데이트 완전 비활성 |
ZQAGENT_UPDATE_PUBKEY | 설치 시 자동 기록 | 검증 공개 키(PEM 또는 base64 SPKI DER). 없으면 자동 설치 안 함 |
ZQAGENT_UPDATE_CHANNEL | stable | 목록 채널(stable / beta) |
ZQAGENT_UPDATE_URL | https://agent.cd-zq.com/downloads/zqagent/<channel>.json | 목록 주소. 내부망에서 덮어쓸 수 있음 |
ZQAGENT_UPDATE_INTERVAL_MS | 21600000(6h) | 확인 간격 |
ZQAGENT_UPDATE_MIN_UPTIME_MS | 600000(10min) | 시작 후 얼마 동안 업데이트하지 않을지 |
ZQAGENT_UPDATE_IDLE_MS | 60000 | 연속 유휴 몇 ms 후 설치할지 |
ZQAGENT_UPDATE_INSECURE | — | 1이면 http 목록 허용(내부 자체 테스트 전용) |
업데이트 확인
zqagent update --check # 새 버전이 있는지만 확인(다운로드 없이 즉시)
zqagent update --status # 현재 버전, 채널, 마지막 확인, 보류/실패 이유출력 예:
현재 버전 v0.2.1
실행 형태 단일 파일(SEA)
서비스 관리 systemd
업데이트 채널 stable
목록 주소 https://agent.cd-zq.com/downloads/zqagent/stable.json
자동 업데이트 사용--check는 '최신 버전입니다(vX)' 또는 '새 버전 vY 발견(현재 vX)'을 출력합니다.
수동 개입
zqagent update --now # 즉시 다운로드 및 설치(유휴 대기 건너뜀, 서비스 재시작 필요)
zqagent update --rollback # 직전 업데이트 이전 버전으로 복귀서비스 측 롤백(자동 재시작):
sudo sh -s -- rollback # 단일 파일 설치(스크립트를 내려받았다면 sudo sh install.sh rollback)
sudo bash install.sh rollback # 리포지토리 내 설치롤백 후에는 해당 버전을 건너뜁니다. 자동 업데이트가 곧바로 다시 설치하지 않고 더 새로운 버전이 나올 때까지 기다립니다. 강제로 설치하려면 zqagent update --now를 사용합니다.
배포 측
명령 하나로 완료됩니다: SEA 단일 파일 빌드 → 목록 생성 및 서명 → 다운로드 디렉터리로 동기화. npm을 거치지 않으며 노드 측에도 Node가 필요 없습니다(바이너리에 런타임 내장).
# 최초: 서명 키 쌍 생성(개인 키는 배포 머신 또는 CI secret에만, 공개 키는 노드에 배포)
node packages/core/scripts/gen_update_keys.mjs --out .update-keys
# 매 릴리스(인수는 모두 기본값 있음: 버전은 packages/core/package.json, 개인 키는 .update-keys/update-private.pem)
bash scripts/release_node.sh자주 쓰는 인수:
| 인수 | 기본값 | 설명 |
|---|---|---|
--version X | packages/core/package.json의 버전 | 순수 버전 번호. 스크립트가 둘의 일치를 검증 |
--key FILE | .update-keys/update-private.pem | Ed25519 개인 키. 목록 서명에 사용 |
--pubkey-file FILE | 개인 키와 같은 디렉터리의 update-public.b64 | 노드 검증 공개 키. 배포 전 개인 키와의 쌍을 검증하고 다운로드 디렉터리로 동기화 |
--host USER@HOST | 비어 있음 = 로컬 배포 | 배포 머신이 사이트 서버면 불필요 |
--dest DIR | /var/www/zqagent-downloads/zqagent | nginx /downloads/가 실제로 가리키는 디렉터리 |
--notes TEXT | 本次更新内容: 例行更新 | 목록에 기록되어 클라이언트 로그에서 확인 가능 |
--skip-build | — | packages/core/release/cli의 기존 산출물 재사용 |
--dry-run | — | 실행할 명령만 출력 |
세 가지 전형적인 사용법:
# 1) 배포 머신이 사이트 서버: 로컬 다운로드 디렉터리에 직접 기록
bash scripts/release_node.sh --skip-build
# 2) 다른 머신에서 배포: ssh + rsync로 사이트 서버에 전송
bash scripts/release_node.sh --host deploy@your-server --skip-build
# 3) 먼저 무엇을 할지 확인
bash scripts/release_node.sh --dry-run크로스 플랫폼 산출물은 해당 시스템/아키텍처에서만 빌드할 수 있습니다. 전 플랫폼 배포는 CI 매트릭스에서 각각 빌드한 뒤 --skip-build --host ...로 모아 배포하세요.
배포 후 디렉터리 구조:
/downloads/zqagent/
├── install.sh # 한 줄 설치 스크립트
├── install-node.sh # 구주소 호환 복사본(내용은 install.sh와 동일)
├── update-public.b64 # 검증 공개 키(설치 시 --pubkey로 전달)
├── stable.json # 업데이트 목록(노드가 읽음)
├── stable.json.sig # 목록 서명
├── stable.txt # 일반 텍스트 목록(설치 스크립트용)
└── v0.2.2/
└── zqagent-<platform>-<arch>노드는 서명 검증을 통과한 뒤에만 바이너리를 다운로드하고 목록의 SHA-256으로 한 번 더 검증합니다. 배포 후 자체 확인:
curl -s https://agent.cd-zq.com/downloads/zqagent/stable.txt
curl -s https://agent.cd-zq.com/downloads/zqagent/stable.json | head -20전체 배포와 롤백 절차는 리포지토리의 docs/release-runbook.md에 있습니다.
사용자 센터 연결(선택)
연결 후 사용자 센터에서 노드 온라인 상태, 프로젝트, 이벤트를 확인할 수 있습니다. 두 방법 중 하나를 선택합니다:
- Hub 계정(권장): 사용자 센터에 가입한 이메일/휴대폰 번호 + 비밀번호를 그대로 사용
- 일회용 연결 코드: 사용자 센터 로그인 → 노드 관리 생성 → 연결 코드 생성(15분 유효)
실행 중인 노드: 핫 연결(재시작 불필요)
# 계정 방식: 이메일 또는 휴대폰 번호 + 비밀번호
zqagent link --hub https://hub.cd-zq.com --username you@example.com --password '<비밀번호>'
zqagent link --hub https://hub.cd-zq.com --username 13800000000 --password '<비밀번호>'
# 휴대폰 번호 + SMS 인증 코드
zqagent link --hub https://hub.cd-zq.com --username 13800000000 --sms-code <인증 코드>
# 또는 일회용 연결 코드
zqagent link --hub https://hub.cd-zq.com --code <연결 코드>Windows 단일 파일:
zqagent.exe link --hub https://hub.cd-zq.com --username you@example.com --password <비밀번호>
zqagent.exe link --hub https://hub.cd-zq.com --code <연결 코드>인증 정보 인수를 붙이지 않으면 zqagent link는 대화형 마법사로 들어가 Hub 주소, 로그인 방식, 계정과 비밀번호를 차례로 묻습니다 (비밀번호는 숨겨 입력). 비밀번호는 환경 변수 ZQAGENT_HUB_PASSWORD로도 제공할 수 있어 명령 기록에 남지 않습니다.
Windows의 기본 데이터 디렉터리는 %APPDATA%\zqagent이며, link는 데스크톱 버전이 등록한 runtime\service.json에서 자동 발견합니다. 수동으로 작업 스케줄러를 설정했고 데이터 디렉터리가 기본 위치가 아닐 때만 --data-dir을 보충하면 됩니다.
link는 먼저 이 기기에서 실행 중인 serve로의 핫 연결을 시도합니다. Linux는 /proc, macOS는 ps, Windows는 PowerShell의 Win32_Process로 프로세스 명령줄을 역조회하므로 serve가 사용자 지정 --data-dir / --port를 써도 발견할 수 있습니다. PowerShell을 쓸 수 없으면 'fleet.json을 쓰고 다음 시작 시 반영'으로 돌아갑니다.
여러 인스턴스가 발견되면 link는 systemd / launchd가 관리하는 서비스를 우선하고(자동 시작으로 재시작 후에도 유지), 다음으로 명령줄에서 임시 실행한 serve를 선택합니다. 현재 디렉터리의 .zqagent_data는 마지막 대비책으로, 임시 인스턴스가 자격 증명을 가로채 '명령은 성공했는데 관리 서비스는 계속 오프라인'이 되는 것을 막습니다.
노드 이름
연결 시 --label을 지정하지 않은 노드는 기본으로 호스트 이름을 표시 이름으로 씁니다. Hub에서는 nodeId가 아니라 머신 이름이 보입니다. 나중에 두 곳에서 변경할 수 있으며 같은 레코드를 수정합니다:
- Hub 사용자 센터 → 노드 관리 → 노드 '이름 변경'
- 노드 머신에서 실행(이 기기에 서비스가 있으면 핫 반영, 재시작 불필요):
zqagent rename ten004-devHub에 연결된 적이 있으면 이 명령은 노드 자신의 자격 증명으로 Hub 레코드를 동기화하고 콘솔을 새로고침하면 반영됩니다. 미연결이면 이 기기 구성만 기록하고 다음 serve 시작 시 반영됩니다.
서비스가 현재 실행 중이 아니어도 link는 plist / systemd unit을 분석해 등록된 데이터 디렉터리를 찾아 그곳에 자격 증명을 기록합니다 (다음 서비스 시작 시 자동 연결). 따라서 데스크톱 버전이든 install.sh로 설치한 노드든 사용자가 수동으로 --data-dir을 넘길 필요가 없습니다.
일반적으로 --data-dir을 직접 쓸 필요가 없습니다: 위 명령이 이 기기의 노드를 자동 발견합니다. '이 기기의 노드 서비스를 찾지 못했습니다'가 표시될 때만 보충하고, 현재 사용자가 쓸 수 있는 디렉터리(각 플랫폼 설치 스크립트의 기본값)를 사용하세요:
| 플랫폼 | 기본 데이터 디렉터리 |
|---|---|
| macOS | $HOME/Library/Application Support/zqagent |
| Linux | ~/.zqagent_data(현재 사용자 소유. 초기 버전은 /var/lib/zqagent) |
| Windows | %APPDATA%\zqagent |
오래된 튜토리얼의
--data-dir /var/lib/zqagent를 그대로 쓰지 마세요. 새 설치는 기본으로~/.zqagent_data에 있으며, 시스템 디렉터리를 수동 지정하면 오히려EACCES: permission denied를 만납니다. 이 인수는 생략하세요.
시작 시 연결
serve에 Hub 주소와 계정(또는 연결 코드)을 넘깁니다:
# 계정 방식(systemd / 컨테이너 등 비대화 환경에 적합)
zqagent serve --hub https://hub.cd-zq.com --username you@example.com --password '<비밀번호>'
# 연결 코드 방식
zqagent serve --hub https://hub.cd-zq.com --enroll-code <연결 코드>환경 변수로도 지정할 수 있습니다(컨테이너 / 스크립트용):
HUB_URL=https://hub.cd-zq.com ZQAGENT_HUB_USERNAME=you@example.com \
ZQAGENT_HUB_PASSWORD='<비밀번호>' zqagent serve
HUB_URL=https://hub.cd-zq.com HUB_ENROLL_CODE=<연결 코드> zqagent serve대화형 CLI 내 연결
zqagent 화면에서 직접:
/link # 계정 연결 마법사 시작
/link <연결 코드> [Hub 주소]Docker
docker run -d -p 8787:8787 -v zqagent-data:/data \
-e HUB_URL=https://hub.cd-zq.com -e HUB_ENROLL_CODE=<연결 코드> \
ghcr.io/<owner>/zqagent-server자격 증명과 네트워크
- 연결 성공 후 자격 증명은
{DATA_DIR}/fleet.json에 기록되며 이후 재시작에는 계정도 연결 코드도 불필요 - 노드는 게이트웨이로 아웃바운드 연결(
wss://, 보통 443)만 하면 되며 공인 인바운드도 포트 개방도 불필요 - 재바인딩/해제: 사용자 센터 노드 상세 페이지에서 조작하거나
fleet.json을 삭제한 뒤 다시 연결
데이터 디렉터리
노드의 모든 장기 데이터는 {DATA_DIR}(기본 ./.zqagent_data, 프로젝트를 따름)에 있습니다:
| 경로 | 내용 |
|---|---|
{DATA_DIR}/admin.json | 관리자 키 |
{DATA_DIR}/fleet.json | 연결 자격 증명(0600) |
{DATA_DIR}/usage/ | 사용량 원장, 요약, 가격표 |
| 세션과 프로젝트 | 각 프로젝트가 작업 디렉터리별로 저장 |
모델 API Key는 사용자 구성 디렉터리(macOS / Linux
~/.config/zqagent/, Windows%APPDATA%\zqagent\)에 별도로 암호화 저장되며 데이터 디렉터리와 분리됩니다.
노드 온라인 확인
노드가 오프라인이면: serve 프로세스가 살아 있는지, 머신이 게이트웨이 주소(FLEET_GATEWAY_URL)로 아웃바운드 접속할 수 있는지 확인하세요.
