SSD Nodes Learn 🎉 VPS $5.50/월부터
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-08-21

HarnessRouter 셀프 호스팅 및 Docker 배포 가이드

Codex, Claude Code, Hermes를 하나의 API로 통합하는 HarnessRouter 설치 방법을 설명합니다. Docker 배포 명령어, 루프백 바인딩 설정, 반드시 변경해야 할 기본 로그인 정보 및 TLS 보안 접속 과정을 상세히 안내합니다.

HarnessRouter가 해결하는 문제

HarnessRouter Community Edition을 직접 호스팅하면 여러 에이전트 하니스(agent harness) 앞단에 하나의 API를 배치하여 직접 소유한 서버에서 운영할 수 있습니다. 에이전트 하니스는 모델을 루프 형태로 구동하는 명령줄 프로그램입니다. 세션을 유지하고, 파일을 수정하며, 명령을 실행하고, 작업 요청자에게 진행 상황을 스트리밍합니다. Codex, Claude Code, Hermes는 모두 이 역할을 수행하지만, 각각 고유한 설치 방식, 자격 증명 형식, 세션 정의를 가지고 있습니다. HarnessRouter는 이 모든 것을 하나의 컨테이너 안에서 실행하며, 단일 HTTP 엔드포인트, 단일 로그인, 단일 비밀 저장소를 앞단에 제공합니다.

이것이 전체 개념이며, 그에 따른 비용 또한 명확히 인지해야 합니다. 여러 개의 움직이는 부품을 하나로 통합하기 위해 서버에 컨테이너, 로그인, 볼륨, 업그레이드 경로를 추가하는 것입니다. 현재 정확히 하나의 하니스만 사용 중이라면, 하니스를 직접 설치하는 것보다 이 설정이 더 비효율적일 수 있습니다. 해당 트레이드오프는 이 문서의 마지막 섹션에서 다루고 있으니 배포 전에 반드시 읽어보시기 바랍니다.

아래의 모든 내용은 2026년 8월 19일에 풀(pull)한 이미지 태그 0.5.5을 기준으로 검증되었습니다. 프로젝트는 거의 매일 새로운 태그를 게시하므로, 한 달 뒤 이 페이지를 신뢰하기보다는 실제로 실행 중인 태그를 확인하십시오. 명령어는 github.com/HarnessRouter/harnessrouter의 프로젝트 README에서 가져왔습니다.

Unified Harness Protocol의 실체

HarnessRouter는 unifiedharnessprotocol.org에 게시된 Unified Harness Protocol(UHP)을 구현합니다. UHP는 제품이 하니스(harness)에서 작업을 시작하고, 실행 중인 작업을 추적하며, 세션과 파일을 관리하고, 실패를 보고하는 방식을 정의합니다. 이 사양은 날짜별로 버전이 관리됩니다. 2026년 8월 19일 기준으로 적용되는 버전은 2026-08-11이며, 해당 사이트에서는 이를 "구축하기에 충분히 안정적이고, 안전하게 변경할 수 있도록 버전이 관리되는" 초안 표준으로 명시하고 있습니다.

여기서 "개방형 표준(open standard)"이라는 문구를 주의 깊게 읽어야 합니다. 사양서, 참조 구현체, 그리고 적합성 여부를 판단하는 52개 항목의 검증 제품군 모두를 동일한 기업이 작성했습니다. 이는 이 정도로 초기 단계인 프로토콜에서는 일반적인 현상이며, Apache-2.0 라이선스가 적용되므로 언제든 코드의 일부를 포크할 수 있습니다. 또한, UHP가 아직 다중 공급업체 표준이 아님을 의미하기도 합니다. 이를 유용하고 변화하는 신흥 프로토콜로 간주하십시오. 귀하의 코드가 재작성 없이도 언제든 사용을 중단할 수 있도록 설계하는 것이 좋습니다.

시작하기 전에 필요한 것

Docker와 약 4 GB의 여유 디스크 공간이 필요합니다. 또한 이미 비용을 지불하고 있는 모델 제공업체의 API 키가 있어야 합니다. 이미지 크기는 약 700 MB이며, 나머지 디스크 공간은 에이전트 CLI와 에이전트가 작업 내용을 기록할 워크스페이스를 위해 사용됩니다. 이미지 내부에는 번들로 제공되는 모델이나 체험용 키가 포함되어 있지 않으므로, 제공업체를 연결하기 전까지는 작업이 실패합니다. HarnessRouter 자체는 Apache-2.0 라이선스를 따릅니다. 에이전트 CLI는 해당 라이선스에 포함되지 않으며, 이 때문에 이미지에 포함되어 배포되지 않고 첫 실행 시점에 다운로드됩니다.

docker run 한 번으로 HarnessRouter 직접 호스팅하기

docker pull harnessrouter/harnessrouter
docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  harnessrouter/harnessrouter

그런 다음 컨테이너가 시작되는 과정을 지켜봅니다. 첫 시작은 느리며, 로그를 통해 그 이유를 확인할 수 있습니다.

docker logs -f harnessrouter

작동 중에 다음과 같은 줄이 표시됩니다.

installing Claude Code (Anthropic's terms apply)…
installing Codex (Apache-2.0)…
installing Hermes (check its upstream license before use)…

ready on :3000가 나올 때까지 기다립니다. 해당 설치는 볼륨당 한 번만 수행되므로, 이후의 시작은 몇 초밖에 걸리지 않으며 설치 관련 로그도 출력되지 않습니다.

이 다운로드 과정에서 두 가지 사실을 알 수 있으며, 두 가지 모두 VPS 환경에서 중요합니다. 첫째, 최초 부팅 시에는 외부 네트워크 연결이 필요합니다. 이미지가 모든 것을 포함하고 있지 않으므로, 송신 필터(egress filter)가 있거나 외부 경로가 없는 서버에서는 이 단계에서 멈추며 ready on :3000 메시지가 출력되지 않습니다. 이 경우 docker pull 단계가 아닌 첫 시작 단계에서 실패하게 되는데, 이는 원인을 파악하기 혼란스러운 지점입니다. 둘째, 타사 소프트웨어를 해당 업체의 약관에 따라 설치하게 됩니다. Claude Code는 Anthropic의 약관을 따르고 Hermes는 각 업스트림의 약관을 따르므로, 상업적 용도로 사용하기 전에 두 약관을 모두 확인하십시오.

-v harnessrouter:/data는 명명된 Docker 볼륨을 생성합니다. SQLite 데이터베이스, 저장된 파일, 비밀 저장소, 에이전트 작업 공간 등 모든 영구 데이터는 /data에 저장됩니다. 이 볼륨을 삭제하면 제공자 키와 모든 대화 기록을 포함하여 인스턴스 전체가 삭제됩니다. SQLite 데이터베이스는 기록 중에 복사하면 파일이 열리지 않을 수 있으므로, 컨테이너를 중지한 상태에서 백업하십시오. 이러한 '중지 후 복사' 원칙은 서버의 모든 상태 유지 컨테이너에 적용됩니다. 다만 PhotoPrism 및 Immich와 같이 서비스별로 세부 사항이 다를 수 있으므로 각 서비스에 맞는 백업 명령을 확인해야 합니다.

docker stop harnessrouter
docker run --rm -v harnessrouter:/data -v "$PWD":/backup alpine \
  tar czf /backup/harnessrouter-data.tgz -C / data
docker start harnessrouter

Compose 변형 및 수정해야 할 행

이 저장소는 compose 파일을 제공합니다. 이 파일은 "3000:3000"를 게시하는데, 이는 호스트의 모든 인터페이스에 노출됨을 의미합니다. 공개 서버에서 실행하기 전에 해당 행을 수정하십시오.

services:
  harnessrouter:
    image: harnessrouter/harnessrouter:0.5.5
    ports:
      - "127.0.0.1:3000:3000"
    env_file:
      - .env
    volumes:
      - harnessrouter-data:/data
    restart: unless-stopped

volumes:
  harnessrouter-data:

업스트림과 다른 점은 두 가지입니다. 바인딩 주소와 latest 대신 고정된 버전 태그를 사용한다는 점입니다. 2026년 8월 9일부터 18일 사이에 16개의 버전 태그가 릴리스되었으므로 버전을 고정하는 것은 중요합니다. 예고 없이 변경되는 에이전트 런타임은 디버깅하기 어렵기 때문입니다. 그 후 환경 파일을 복사하고 권한을 잠근 뒤 시작하십시오.

cp .env.example .env
chmod 600 .env
docker compose up -d
docker compose logs -f

.env에는 공급자 키가 일반 텍스트로 저장되므로 최소 600 모드로 설정해야 합니다. docker compose 하위 명령어가 익숙하지 않다면 Docker Compose 명령어 치트 시트에서 일상적으로 사용하는 명령어를 확인하십시오.

포트가 0.0.0.0이 아닌 127.0.0.1에 게시되는 이유

-p 3000:3000은 호스트가 가진 모든 인터페이스에 포트를 게시합니다. -p 127.0.0.1:3000:3000는 루프백 인터페이스에만 게시하므로, VPS 내부에서만 접근할 수 있습니다. 컨테이너는 항상 내부적으로 3000번 포트에서 수신 대기하므로, 변경해야 할 부분은 왼쪽의 호스트 포트 설정입니다. 현재 설정을 확인하십시오:

docker port harnessrouter
sudo ss -ltnp | grep 3000

ss127.0.0.1:3000을 출력한다면 올바른 상태입니다. 0.0.0.0:3000는 콘솔이 공용 인터넷에 노출되어 있음을 의미합니다. 콘솔은 하네스를 생성하고, 모든 대화 내용을 읽으며, 에이전트를 실행하고, 해당 에이전트에게 셸과 실제 파일 시스템에 대한 접근 권한을 부여하므로, 대부분의 자가 호스팅 애플리케이션보다 보안 위험이 큽니다. 또한 연결된 공급자 키도 보관합니다. 보호되지 않은 콘솔에 접근할 수 있는 사람은 누구나 사용자의 작업을 읽고, 명령을 실행하며, 키를 사용하여 비용을 발생시킬 수 있습니다.

호스트 방화벽은 이 상황에서 보호 수단이 되지 않습니다. Docker는 커널의 nat 테이블에 자체 규칙을 직접 작성하여 포트를 게시하며, 이 규칙은 ufw가 관리하는 체인보다 먼저 평가됩니다. 따라서 sudo ufw status에서 거부된 것으로 표시되더라도 게시된 포트는 여전히 접근 가능합니다. 테스트는 VPS 내부가 아닌 다른 기기에서 수행하십시오. 그렇지 않으면 아무것도 테스트할 수 없습니다. 이는 dsh를 3080번 포트에서 헤드리스로 실행하기와 같은 교훈을 줍니다. 서비스를 루프백에 바인딩한 다음, 어떻게 접근할지 신중하게 결정하십시오.

다른 작업을 시작하기 전에 기본 로그인 정보 변경하기

http://localhost:3000에 사용자 이름 harnessrouter과 비밀번호 harnessrouter로 로그인합니다. 이 자격 증명은 비밀이 아닌 임시 값(placeholder)이므로 README에 명시되어 있습니다. 컨테이너는 이를 변경할 때까지 매번 시작할 때마다 경고를 표시합니다.

using the DEFAULT password. Set HR_AUTH_PASSWORD, or change it from the profile page, before exposing this instance.

Profile 페이지에서 변경하거나, 스크립트를 통한 배포 시 시작 시점에 설정할 수 있습니다. HR_AUTH_USERHR_AUTH_PASSWORD을 사용하면 기본값을 덮어쓸 수 있습니다.

docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  -e HR_AUTH_USER='you' \
  -e HR_AUTH_PASSWORD='the-password-you-chose' \
  harnessrouter/harnessrouter

계정 시스템이나 메일 서버가 없으므로 비밀번호 재설정 이메일 기능은 제공되지 않습니다. 비밀번호를 분실했다면 볼륨 내의 인증 파일을 삭제하고 재시작한 뒤, 다시 기본값으로 로그인하십시오.

docker stop harnessrouter
docker run --rm -v harnessrouter:/data alpine rm -f /data/selfhost-auth.json
docker start harnessrouter

HR_AUTH_DISABLED=1을 사용하면 로그인 관문을 완전히 제거할 수 있습니다. README에서는 이를 "아무도 접근할 수 없는 환경"으로 한정하고 있습니다. 공인 IP 주소를 가진 VPS는 이러한 환경이 아니므로, 노트북에서 실행하는 경우가 아니라면 로그인 관문을 그대로 유지하십시오.

버전을 확인하십시오. 구버전에는 인증 게이트가 없습니다

이 부분은 심각하게 고려해야 합니다. 0.1.x0.2.0 버전은 인증 게이트가 전혀 없이 출시되었습니다. 포트 3000에 접근할 수 있는 사람은 누구나 콘솔 내부로 진입할 수 있었습니다. 0.3.0 버전부터 로그인이 도입되었습니다. 해당 구버전 태그들은 여전히 게시되어 있고 가져오기(pull)가 가능하므로, 고정된 구버전 태그를 사용하거나 동료에게 복사받은 compose 파일을 사용하면 현재도 공개 포트에 인증 없는 콘솔이 노출될 수 있습니다.

2026년 8월 19일 기준으로 가장 최근에 게시된 태그는 2026년 8월 18일 자의 0.5.5이며, latest이 이를 가리키고 있습니다. 현재 사용 중인 버전을 확인한 뒤 Docker Hub의 태그 목록과 비교하십시오.

docker image ls harnessrouter/harnessrouter

0.3.0 미만의 모든 버전은 즉시 교체해야 하며, 일정을 미뤄서는 안 됩니다. 해당 버전 이상이라 하더라도 비밀번호를 변경해야 합니다. 포트 3000을 스캔하는 공격자에게는 기본 비밀번호가 설정된 상태나 비밀번호가 없는 상태나 동일하기 때문입니다. 이 페이지에 기재된 버전 번호를 최신 정보로 간주하지 마십시오. 해당 번호는 상단에 명시된 날짜 기준이며, 이 프로젝트는 빠르게 업데이트됩니다.

공급자 연결

모델 공급자를 연결하기 전까지는 아무것도 실행되지 않습니다. 콘솔의 Integrations 페이지에서 추가하거나, 환경 변수 docker run에 전달하십시오. 값은 JSON 형식이므로 셸에서 따옴표로 묶어야 합니다.

-e HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC='{"name":"anthropic","provider":"anthropic","api_key":"sk-ant-…"}'

.env.example는 공급자 제품군당 하나의 연결 변수를 지정합니다. HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC은 claude-code 백엔드용, HR_SECRET_GLOBAL_HARNESS_CONN_OPENAI은 codex 백엔드용, HR_SECRET_GLOBAL_HARNESS_CONN_CUSTOM는 집계 도구나 자체 추론 서버가 위치하는 모든 OpenAI 호환 엔드포인트용입니다. 대응하는 HR_SECRET_GLOBAL_HARNESS_POLICY_CLAUDE, HR_SECRET_GLOBAL_HARNESS_POLICY_CODEX, HR_SECRET_GLOBAL_HARNESS_POLICY_HERMES 변수는 각 백엔드가 기본적으로 사용할 연결을 지정합니다. HR_SECRET_KEY은 별도의 항목이며, 에이전트에 데이터베이스를 연결할 때만 필요합니다.

HR_BACKENDSHR_BACKENDS=claude,codex,hermes에서와 같이 로드할 백엔드를 선택합니다. 문제가 발생하기 전에 알아두어야 할 알려진 이슈가 하나 있습니다. hermes를 제외한 값을 설정하면 컨테이너가 오류 메시지 없이 즉시 상태 코드 1로 종료됩니다. 시작 후 1초 뒤에 docker ps -a에서 Exited (1)을 보게 되며, docker logs에는 유용한 정보가 표시되지 않습니다. 업스트림에서 수정될 때까지 hermes을 목록에 유지하십시오. Hermes만 사용하는 것이 목적이라면 Hermes 에이전트를 별도의 VPS에서 실행하는 것이 더 작은 규모의 배포 방식입니다.

콘솔 없이 API 호출하기

콘솔은 선택 사항입니다. 동일한 API가 양쪽 모두를 지원하며, Responses 스타일의 계약을 따릅니다. 먼저 로그인하여 세션 쿠키를 획득하십시오:

curl -c hr.cookies http://localhost:3000/api/selfhost/login \
  -H 'content-type: application/json' \
  -d '{"username":"harnessrouter","password":"your-password"}'

그런 다음 metadata.harness_id에 하네스 이름을 지정하고 연결된 공급자가 실제로 제공하는 모델을 사용하여 작업을 전송하십시오:

curl -s -b hr.cookies http://localhost:3000/api/harness/v1/responses \
  -H 'content-type: application/json' \
  -d '{"input":"Reply with exactly this and nothing else: it works.",
       "metadata":{"harness_id":"codex"},
       "model":"gpt-5.4-mini",
       "stream":false}'

출력 블록과 토큰 수를 포함한 JSON 객체가 반환되면 하네스가 정상적으로 실행된 것입니다. harness_idcodex에서 claude로 변경하면 동일한 요청이 다른 하네스로 전송되며, 이러한 교체 기능이 바로 이 소프트웨어가 존재하는 이유입니다. 위와 같은 사용자 지정 연결 방식은 VPS에서 자체 호스팅하는 DeepSeek 하네스를 연결하는 것과 같이, 이미 호스팅 중인 OpenAI 호환 엔드포인트로 하네스를 가리키는 방법입니다.

포트를 공개하지 않고 노트북에서 접속하기

두 가지 방법이 있으며, 어느 쪽도 0.0.0.0에 원시 포트를 열지 않습니다.

SSH 터널은 가장 비용이 적게 드는 방법이며 서버에 별도의 소프트웨어를 설치할 필요가 없습니다. 이 방법은 로컬 머신의 포트를 VPS의 루프백 주소로 전달합니다.

ssh -N -L 3000:127.0.0.1:3000 you@your-vps

이 명령을 실행해 둔 상태에서 브라우저로 http://localhost:3000에 접속합니다. 만약 SSH가 bind: Address already in use 오류를 출력한다면, 노트북의 3000번 포트를 이미 다른 프로세스가 사용 중인 것이므로 -L 3100:127.0.0.1:3000을 사용하여 다른 로컬 포트를 지정한 뒤 3100번 포트로 접속하십시오.

종단 리버스 프록시는 다른 사용자의 접근이 필요할 때 사용하는 방법입니다. 프록시가 TLS(전송 계층 보안) 인증서를 관리하고 루프백으로 요청을 전달합니다. README에는 다음과 같은 Caddy 설정이 제공됩니다.

console.example.com {
    encode zstd gzip
    reverse_proxy 127.0.0.1:3000 {
        flush_interval -1      # agent turns stream for minutes; never buffer them
    }
}

flush_interval -1는 사용자들이 자주 놓치는 설정입니다. 에이전트는 스트림 토큰을 수 분 동안 생성하며, 응답을 버퍼링하는 프록시는 턴이 끝날 때까지 해당 토큰을 붙잡아 둡니다. 이 때문에 콘솔이 멈춘 것처럼 보이다가 한꺼번에 모든 내용이 출력됩니다. Nginx에서는 location 블록 안에 proxy_buffering off;을 설정하면 동일한 효과를 낼 수 있습니다. 어떤 도구를 선택하든 DNS 이름은 프록시를 가리키게 하고 컨테이너는 루프백에서 실행하십시오. 리버스 프록시로서의 Nginx, Caddy, Traefik 비교에서 각 환경에 적합한 도구를 확인할 수 있습니다.

root가 아닌 전용 사용자로 실행하기

Docker daemon은 root 권한으로 실행되며, docker 그룹의 멤버십은 root 권한과 동일합니다. 해당 그룹의 멤버는 호스트 파일 시스템을 마운트하는 컨테이너를 시작할 수 있기 때문입니다. 따라서 "팀원을 docker 그룹에 추가"하는 행위는 공급자 키(provider key)가 저장된 서버의 root 권한을 부여하는 것과 같습니다.

간단한 방법은 compose 파일과 .env를 소유하는 서비스 계정을 생성하고, 해당 파일들을 공유 홈 디렉터리에 두지 않는 것입니다.

sudo adduser --disabled-password --gecos "" harness
sudo install -d -o harness -g harness -m 750 /srv/harnessrouter

더 강력한 방법은 rootless Docker를 사용하는 것입니다. 이 방식에서는 daemon 자체가 권한이 없는(unprivileged) 사용자로 실행됩니다. 이를 위해서는 newuidmapnewgidmap을 위한 uidmap 패키지가 필요하며, 해당 사용자에 대해 /etc/subuid/etc/subgid 내에 최소 65536개의 하위 UID가 할당되어야 합니다.

sudo apt install -y uidmap docker-ce-rootless-extras
sudo loginctl enable-linger harness
sudo -iu harness
dockerd-rootless-setuptool.sh install
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
systemctl --user enable --now docker

여기서 loginctl enable-linger은 선택 사항이 아닙니다. 이 설정이 없으면 마지막 세션이 종료될 때 사용자의 systemd 인스턴스도 함께 중지되므로, 로그아웃 시 컨테이너가 종료됩니다. Security Options 아래에 rootless이 나열되는지 docker info 명령으로 결과를 확인하십시오. Rootless 모드에서는 추가 설정 없이는 1024 미만의 포트를 바인딩할 수 없으나, 여기서는 포트 3000을 사용하므로 문제가 되지 않습니다. 계정 설정 자체는 VPS에서 최소 권한 사용자 생성하기에서 다룹니다.

무엇이 문제이며, 어떤 현상이 나타나는가

컨테이너가 시작된 지 1초 만에 종료되고 로그가 비어 있습니다. docker ps -aExited (1)를 보여줍니다. 이는 위에서 언급한 HR_BACKENDS 문제입니다. 설정값에서 hermes이 누락되었습니다. 다시 추가하십시오.

첫 시작이 완료되지 않습니다. 로그가 installing 줄에서 멈추고 ready on :3000가 나타나지 않습니다. 이미지에 agent CLI가 포함되어 있지 않아 서버가 네트워크에 연결하여 이를 가져올 수 없는 상태입니다. 아웃바운드 경로 또는 프록시 설정을 수정한 뒤 재시작하십시오.

콘솔은 로드되지만 모든 작업이 실패합니다. 연결된 공급자가 없습니다. 이미지 내부에 번들로 제공되는 모델이나 무료 티어(free tier)가 없으므로, 새로 생성된 인스턴스는 로그인은 가능해도 아무런 작업을 수행할 수 없습니다.

프록시 뒤에서 콘솔이 답변 도중 멈춥니다. 응답이 끝날 때 출력 내용이 한꺼번에 나타납니다. 이는 응답 버퍼링 때문입니다. Caddy에서는 flush_interval -1을, Nginx에서는 proxy_buffering off;을 설정하십시오.

터널은 활성화되어 있는데 노트북에서 접속할 수 없습니다. 서버에서 docker port harnessrouter를 실행하십시오. 아무것도 출력되지 않는다면 컨테이너가 아무것도 게시(publish)하지 않은 것이며, 이는 -p 없이 시작되었기 때문입니다.

이것을 실행할 가치가 있습니까?

여러 개의 하네스를 실제로 사용하고 있으며, 각각 3개씩 필요한 엔드포인트와 자격 증명 저장소를 하나로 통합하고 싶다면 실행할 가치가 있습니다. 또한 그 위에 제품을 구축하고 있으며 하네스를 재작성하는 대신 구성 값으로 처리하고 싶을 때도 유용합니다. 이것이 UHP가 제공하는 이점이지만, 프로토콜이 아직 초기 단계라는 점은 유의해야 합니다.

하네스를 하나만 사용한다면 실행할 가치가 없습니다. 서버에 해당 CLI를 설치하는 편이 구성 요소가 더 적고, 사용자와 도구 사이에 로그인 과정도 없습니다. 또한 여러 하네스 앞에 하나의 API를 두는 것이 아니라 여러 에이전트가 하나의 작업에 협력하는 방식을 원한다면 이 도구는 적합하지 않습니다. 해당 패턴은 Omnigent와 같은 멀티 에이전트 하네스를 참조하십시오. 어떤 경우든 배포 규칙은 변하지 않습니다. 루프백 바인딩, 변경된 비밀번호, 0.3.0 이상의 고정된 태그, 그리고 전용 사용자 계정을 사용해야 합니다.

FAQ

HarnessRouter를 3000번 포트로 공개해도 안전합니까?

아니요. 콘솔은 하네스를 생성하고, 모든 트랜스크립트를 읽으며, 셸 및 파일 시스템 접근 권한을 가진 에이전트를 실행하고, 연결된 공급자 키를 보관하므로 포트를 개방하면 이 모든 것이 노출됩니다. -p 127.0.0.1:3000:3000를 사용하여 루프백 주소로 게시하고 SSH 터널이나 TLS 종료 리버스 프록시를 통해 접근하십시오. 호스트 방화벽만으로는 충분하지 않습니다. Docker는 자체 규칙을 커널 nat 테이블에 직접 작성하므로, ufw에서 거부된 것으로 표시되더라도 게시된 포트는 인터넷에서 응답할 수 있습니다. sudo ss -ltnp | grep 3000로 확인하십시오. 이 명령은 127.0.0.1:3000를 출력해야 합니다.

HarnessRouter의 어느 버전부터 로그인 게이트가 추가되었습니까?

0.3.0입니다. 0.1.x0.2.0 버전은 인증 기능 없이 출시되었으며, 두 태그 모두 여전히 게시되어 있고 가져올 수 있으므로 해당 버전을 실행 중인 사용자는 아무도 포트를 찾지 못할 것이라는 점에 의존하고 있는 셈입니다. 2026년 8월 19일 기준으로 최신 태그는 2026년 8월 18일자 0.5.5입니다. docker image ls harnessrouter/harnessrouter를 실행하여 현재 버전을 확인하고, 이 페이지가 아닌 Docker Hub의 태그 목록과 비교하십시오. 최신 버전을 사용하더라도 기본 비밀번호는 반드시 변경하십시오.

HR_BACKENDS를 설정한 직후 컨테이너가 종료되는 이유는 무엇입니까?

hermes을 포함하지 않는 모든 HR_BACKENDS 값은 컨테이너를 즉시 상태 코드 1로 종료시키며 오류 메시지를 출력하지 않습니다. 이는 프로젝트 README에 알려진 문제입니다. 증상은 1~2초 내에 docker ps -a에서 Exited (1)이 발생하는 것이며, docker logs에는 유용한 정보가 남지 않습니다. 업스트림에서 수정될 때까지 HR_BACKENDS=claude,codex,hermes과 같이 hermes을 목록에 유지하십시오.

HarnessRouter는 첫 시작 시 인터넷 연결이 필요합니까?

네. 에이전트 CLI는 이미지에 포함되어 있지 않고 첫 시작 시 다운로드되는데, 이는 각 에이전트가 고유한 라이선스를 포함하고 있기 때문입니다. 아웃바운드 경로가 없는 서버는 installing 줄을 출력한 뒤 ready on :3000에 도달하지 못합니다. 다운로드는 볼륨당 한 번만 수행되므로, 이후 시작 시에는 몇 초 정도만 소요되며 연결된 모델 공급자 외에는 네트워크가 필요하지 않습니다.

콘솔 비밀번호를 분실했습니다. 어떻게 다시 접속합니까?

계정 시스템이나 메일 서버가 없으므로 비밀번호 재설정 이메일 기능은 없습니다. 컨테이너를 중지하고 볼륨에서 /data/selfhost-auth.json를 삭제한 뒤, 컨테이너를 다시 시작하십시오. 이후 기본 자격 증명으로 로그인하여 프로필 페이지에서 새 비밀번호를 설정하십시오. 컨테이너와 볼륨 이름이 모두 harnessrouter인 경우, docker stop harnessrouter을 실행한 다음 docker run --rm -v harnessrouter:/data alpine rm -f /data/selfhost-auth.json, 그리고 docker start harnessrouter을 수행하면 됩니다.