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

OneCLI 직접 호스팅 방법: Docker Compose 구축 가이드

OneCLI를 자체 서버에 배포하는 상세 과정을 안내합니다. Docker Compose와 PostgreSQL 설정법을 포함하며, 에이전트 샌드박스당 2GiB 메모리가 필요한 실제 하드웨어 사양과 7개 구성 요소의 역할을 명확히 정리했습니다.

OneCLI를 직접 호스팅할 때 얻는 것

OneCLI를 직접 호스팅하면 팀원 각자가 자신만의 에이전트를 갖게 됩니다. 각 에이전트는 독립된 샌드박스에서 실행되며, API 키는 에이전트가 직접 읽을 수 없는 게이트웨이에 보관됩니다. 설치는 http://localhost:10254에서 접근 가능한 PostgreSQL을 포함한 Docker Compose 스택 형태입니다. 실제 서버 환경을 고려하십시오. 문서화된 기본값은 에이전트 샌드박스당 2 GiB 메모리이므로, 1 GB RAM의 VPS에서는 실행하기 어렵습니다.

해당 스택에는 7개의 구성 요소가 포함되어 있으며, 각 역할을 이해하면 이 가이드를 읽기가 더 수월해집니다.

  • Web dashboard (Next.js), 포트 10254. 에이전트 생성, 채팅, 메모리 및 기술 편집, 연결 및 보안 정보 관리.
  • API server, 포트 10256. 제어 평면: 데이터베이스, 대화 처리, 작업 큐.
  • Rust gateway, 포트 10255. 에이전트의 아웃바운드 요청을 가로채어 자격 증명을 주입.
  • Runner. README에 따르면 "에이전트 샌드박스를 시작, 정지, 회수하는 구성 요소입니다. 아웃바운드 전용이며 데이터베이스에는 접근하지 않습니다."
  • Sandbox Supervisor. README에 따르면 "각 샌드박스 내부에서 실행되며, 벤더 중립적인 하니스 인터페이스를 사용하여 에이전트 런타임을 교체 가능하게 만듭니다."
  • Channel adapter. Slack 앱을 연결하는 데몬으로, 에이전트가 채널이나 DM에서 자신의 이름으로 답변할 수 있게 합니다.
  • PostgreSQL. 제공된 compose 파일은 postgres:18-alpinepgdata 볼륨과 함께 실행합니다.

이름은 CLI지만, 제품은 서버입니다

OneCLI는 서버 플랫폼입니다. 이름 때문에 노트북에 설치하는 명령줄 도구라고 생각하기 쉽지만, 이 가이드에서 다루는 대상과는 거리가 있습니다. 별도의 명령줄 클라이언트가 onecli/onecli-cli 저장소에 존재하기는 하며, 이는 로컬 코딩 에이전트의 트래픽을 게이트웨이를 통해 라우팅하는 역할을 합니다. 여기서 배포할 대상은 다중 사용자 웹 애플리케이션입니다. 첫 번째 계정이 인스턴스의 소유권을 가지는 계정 시스템, 대화와 비밀 정보를 저장하는 데이터베이스, 그리고 컨테이너를 실행하는 러너로 구성됩니다.

개인별 모델이 전체 설계의 핵심입니다. README에 따르면 "사람마다 에이전트를 생성하고, 각 에이전트에 필요한 접근 권한을 부여합니다. 에이전트는 샌드박스 안에서 작동하며, 자격 증명을 주입하고 정책을 강제하는 게이트웨이를 통해 라우팅됩니다." 각 에이전트는 고유한 파일 시스템과 셸, 대화 페이지, 플랫폼이 유지하는 메모리, 그리고 한 번 작성하면 재사용 가능한 스킬을 가집니다. 자격 증명은 일반적인 설정과 반대 방식으로 작동합니다. 각 사용자의 환경에 API 키를 복사하는 대신, 키를 한 번 저장한 뒤 이를 사용할 권한이 있는 에이전트에 부여하는 방식입니다.

시작하기 전에 필요한 사항

  • Docker 및 2.19 버전 이상의 Compose 플러그인. compose 파일은 API가 대기하는 일회성 마이그레이션 서비스를 사용하며, 해당 의존성 형태는 2.19 버전을 요구합니다.
  • 메모리. 실제 제약 사항이므로 플랜을 선택하기 전에 아래의 사이징 섹션을 읽어 보십시오.
  • 사용 가능한 루프백 포트 10254, 10255, 102565432.

PostgreSQL을 직접 설치할 필요는 없습니다. compose 파일이 이를 서비스로 실행합니다. Node.js나 Rust도 필요하지 않습니다. 해당 도구들은 mise이 툴체인을 고정하는 소스 빌드 경로에서만 사용됩니다.

VPS 한 대당 에이전트 샌드박스를 몇 개나 실행할 수 있습니까?

러너의 공식 문서에서는 추측이 아닌 실제 수치를 제공합니다. 각 샌드박스는 2048 MB의 메모리(RUNNER_SANDBOX_MEMORY_MB), CPU 1개(RUNNER_SANDBOX_CPUS), 512개의 프로세스(RUNNER_SANDBOX_PIDS)를 할당받습니다. 동시성 제한은 4(RUNNER_MAX_SANDBOXES)이며, 문서에서는 해당 제한을 충족하기 위해 기본 스택 외에 약 10 GiB의 여유 메모리를 확보할 것을 권장합니다.

ChartConcurrent agent sandboxes per box, at the documented 2 GiB default
The data behind this chart
[
  {
    "plan": "2 GB box",
    "ram_gb": 2,
    "sandbox_slots": 0
  },
  {
    "plan": "4 GB box",
    "ram_gb": 4,
    "sandbox_slots": 1
  },
  {
    "plan": "8 GB box",
    "ram_gb": 8,
    "sandbox_slots": 3
  },
  {
    "plan": "16 GB box",
    "ram_gb": 16,
    "sandbox_slots": 7
  },
  {
    "plan": "32 GB box",
    "ram_gb": 32,
    "sandbox_slots": 15
  }
]

이 슬롯 개수는 벤치마크가 아닌 산술적인 계산 결과입니다. 전체 메모리에서 PostgreSQL과 4개의 상시 실행 서비스를 위한 약 2 GB를 제외한 뒤, 샌드박스 제한인 2 GiB로 나눈 값입니다. 이 기준에 따르면 2 GB box0개의 샌드박스를 수용할 수 있으므로, 가장 저렴한 플랜에서는 호스팅된 에이전트를 전혀 실행할 수 없습니다. 16 GB box 플랜은 7개의 샌드박스를 수용할 수 있는 여유가 있어, 기본 제한인 4개와 러너 문서에서 권장하는 약 10 GiB의 여유 메모리 조건을 충분히 만족합니다. 32 GB box 플랜을 선택하면 15개의 샌드박스를 수용할 수 있습니다.

이 산술 계산에는 두 가지 변수가 있습니다. 백그라운드 프로세스가 실행 중인 샌드박스는 절대 대기 상태로 전환되지 않으므로 슬롯을 영구적으로 점유합니다. 따라서 RUNNER_MAX_SANDBOXES를 설정할 때는 가장 바쁜 순간이 아닌 지속적인 부하를 기준으로 산정해야 합니다. 또한 CPU보다 메모리가 먼저 고갈됩니다. 각 샌드박스는 CPU 1개로 제한되므로 4개의 바쁜 에이전트는 4개의 코어를 요구하지만, 유휴 상태인 4개의 에이전트도 여전히 8 GiB의 메모리를 점유합니다.

변경을 고려할 만한 러너 설정
  • RUNNER_MAX_SANDBOXES (기본값 4): 동시에 실행할 샌드박스 개수입니다.
  • RUNNER_SANDBOX_MEMORY_MB (기본값 2048): 샌드박스당 메모리 제한입니다.
  • RUNNER_SANDBOX_CPUS (기본값 1): 샌드박스당 CPU 제한입니다.
  • RUNNER_SANDBOX_PIDS (기본값 512): 샌드박스당 프로세스 제한입니다.
  • RUNNER_NETWORK_INTERNAL (기본값 true): 샌드박스 네트워크의 외부 경로를 차단합니다. 이 설정을 유지하십시오.
  • RUNNER_SANDBOX_NETWORK (기본값 onecli-sandboxes): 샌드박스가 참여할 네트워크입니다.
  • RUNNER_RECONCILE_SECONDS (기본값 60): 러너가 상태를 조정하는 주기입니다.
  • RUNNER_ORPHAN_GRACE_SECONDS (기본값 3600): 고아 컨테이너 및 볼륨을 삭제할 기준 시간입니다.
  • RUNNER_AGENT_IMAGE: 샌드박스 이미지를 재정의합니다. 기본적으로는 ONECLI_VERSION을 따릅니다.

Docker Compose로 OneCLI 설치하기

업스트림의 셀프 호스팅 문서에서는 다음 순서를 정확히 따르도록 안내합니다. compose 파일 옆의 docker/.env에 세 가지 비밀 값을 기록한 뒤 스택을 시작합니다.

git clone https://github.com/onecli/onecli.git && cd onecli/docker
cat > .env <<EOF
SECRET_ENCRYPTION_KEY=$(head -c 32 /dev/urandom | base64)
GATEWAY_INTERNAL_SECRET=$(head -c 32 /dev/urandom | base64)
BETTER_AUTH_SECRET=$(head -c 32 /dev/urandom | base64)
COMPOSE_PROFILES=runner
EOF
chmod 600 .env
docker compose up -d --wait

실행하기 전에 해당 블록을 읽어보십시오. heredoc 마커에 따옴표가 없으므로, 셸이 각 head -c 32 /dev/urandom | base64를 실행하고 그 결과를 기록합니다. SECRET_ENCRYPTION_KEY은 데이터베이스 내 모든 비밀 값을 위한 AES-256-GCM 키입니다. GATEWAY_INTERNAL_SECRET은 게이트웨이에서 API로 인증할 때 사용합니다. BETTER_AUTH_SECRET은 세션 쿠키 서명에 사용됩니다. COMPOSE_PROFILES=runner는 가장 중요한 줄입니다. runner 서비스가 Compose 프로필 뒤에 숨어 있기 때문입니다. 이 설정을 누락하면 스택은 정상적으로 올라오지만 에이전트 샌드박스는 전혀 시작되지 않습니다.

--wait은 모든 서비스가 정상(healthy) 상태라고 보고할 때까지 셸을 대기시킵니다. 따라서 0이 아닌 종료 코드가 반환된다면 무언가 잘못되었다는 첫 번째 신호입니다. 그 후 실제로 어떤 서비스가 실행되었는지 확인하십시오.

docker compose ps
docker compose logs migrations

버전을 고정하십시오. ONECLI_VERSION은 모든 서비스의 태그를 한 번에 설정합니다. RUNNER_AGENT_IMAGE가 다른 곳을 가리키지 않는 한 에이전트 샌드박스 이미지도 이 태그를 따릅니다. 2026년 8월 19일 기준으로 현재 릴리스는 v2.0.1이며, 2026년 8월 18일에 게시되었습니다. 이 값을 같은 파일에 추가하고 스택을 다시 올리십시오.

echo 'ONECLI_VERSION=v2.0.1' >> .env
docker compose up -d --wait

curl -fsSL https://onecli.sh/install | sh라는 설치 프로그램도 존재합니다. 이 프로그램은 ~/.onecli/.env에 설정을 기록하며 동일한 작업을 수행합니다. Compose 방식은 실행 전에 모든 파일을 직접 읽어볼 수 있다는 장점이 있으며, 이미 다른 Compose 스택을 운영 중인 서버에 권장되는 방식입니다. 소스 빌드는 세 번째 경로이며, 복제된 저장소에서 pnpm install을 실행한 뒤 pnpm run setup을 수행하도록 문서화되어 있습니다. 이 방식은 어차피 mise, 게이트웨이를 위한 Rust, 그리고 Docker가 필요하며, 코드를 직접 수정하려는 사용자를 위해 존재합니다.

노트북에서 대시보드 접속하기

제공된 compose 파일에 정의된 모든 포트는 ${ONECLI_BIND_HOST:-127.0.0.1}에 바인딩됩니다. VPS 환경에서는 대시보드가 실행 중이더라도 외부에서 직접 접근할 수 없음을 의미합니다. 이 기본 설정은 올바른 상태이므로, 설정을 유지한 채 다음 명령으로 터널링을 수행하십시오.

ssh -N -L 10254:127.0.0.1:10254 you@your-server

이제 노트북에서 http://localhost:10254에 접속하십시오. 트래픽은 SSH 연결을 통해 전달되므로, 암호화되지 않은 대시보드가 공용 인터넷에 노출되지 않으며 방화벽에 별도의 포트를 열 필요도 없습니다.

ONECLI_BIND_HOST=0.0.0.0 설정을 사용하면 대시보드가 일반 HTTP로 공개되며, PostgreSQL도 함께 노출됩니다. 여러 사용자가 대시보드에 접근해야 한다면, 포트 10254 앞에 TLS(Transport Layer Security)를 지원하는 리버스 프록시를 배치하고 바인딩 호스트 설정은 변경하지 마십시오. 이 작업은 인스턴스에 소유자가 지정되기 전에 수행해야 합니다. 업스트림 문서에서는 그 이유를 다음과 같이 명확히 밝히고 있습니다: "설정 전까지는 인스턴스에 소유자가 없으며, 접근 가능한 호스트에 먼저 도달하는 사람이 소유자가 됩니다." 만약 다른 셀프 호스팅 애플리케이션을 운영 중인 프록시가 이미 있다면, 셀프 호스팅 SSO 계층을 통해 인증을 연동하십시오. 이를 통해 팀이 이미 사용 중인 로그인 시스템 뒤로 대시보드를 보호할 수 있으며, 특정 사용자의 권한을 회수할 때 해당 경로에 대한 접근도 함께 차단할 수 있습니다.

첫 번째 계정을 생성하고 모델 키 권한 부여하기

대시보드를 열고 즉시 계정을 생성하십시오. 해당 계정이 인스턴스의 소유자가 되며, 계정이 생성된 이후에는 초대장을 통해서만 참여할 수 있습니다.

에이전트를 생성하기 전에 모델 키를 먼저 저장하십시오. 호스팅된 에이전트는 부여된 모델 키가 필요하며, 순서가 중요합니다. 대시보드에 키를 저장하고, 에이전트에 권한을 부여한 뒤에 대화를 시작해야 합니다. 권한 부여 단계를 건너뛰면 샌드박스가 실행되지 않으며, 에이전트가 아무런 동작도 하지 않는 상태로 남게 됩니다.

권한은 필요한 만큼만 제한적으로 부여하십시오. 각 에이전트는 부여받은 권한만 사용할 수 있으며, 게이트웨이가 모든 요청에 대해 이를 강제합니다. 따라서 특정 저장소를 읽는 에이전트는 결제 서비스 제공업체의 키에 접근할 수 없습니다. 동일한 권한 목록을 사용하여 비용을 제어할 수 있습니다. 개별 사용자가 소유한 모든 모델을 호출할 수 있는 에이전트는 사용자별로 청구서가 발생하므로, 에이전트를 10개 이상 배포하기 전에 에이전트의 모델 호출 비용 제한 방법을 읽어보는 것이 좋습니다.

게이트웨이가 에이전트로부터 키를 보호하는 방식

게이트웨이는 Rust로 작성된 HTTPS 프록시이며 10255 포트에서 대기합니다. 에이전트의 HTTP 클라이언트는 이 게이트웨이를 가리키며, 에이전트는 실제 자격 증명 대신 자리 표시자(placeholder) 자격 증명을 소지합니다. 게이트웨이는 아웃바운드 요청을 해당 에이전트의 권한과 대조하고, 실제 비밀 값을 복호화하여 요청에 삽입한 뒤 전달합니다. 비밀 값은 PostgreSQL에 AES-256-GCM(Advanced Encryption Standard, 256-bit, Galois/Counter Mode)으로 암호화되어 저장되며, 요청 시점에만 복호화됩니다. 모든 호출은 에이전트의 식별 정보와 대상과 함께 기록되는데, 이는 키가 10명의 셸 프로필에 분산되어 있을 때는 얻을 수 없는 감사 추적(audit trail)입니다.

배포 방식을 결정하는 두 가지 메커니즘은 다음과 같습니다.

  • HTTPS 가로채기는 중간자 공격(man-in-the-middle) 방식입니다. 게이트웨이는 로컬 인증 기관(CA)을 생성하고 에이전트가 이를 신뢰하게 한 뒤, 에이전트의 TLS 연결을 종료하고 업스트림 서비스로 향하는 새로운 연결을 엽니다. 이것이 바로 HTTP 클라이언트가 게이트웨이 인증 기관을 신뢰하지 않는 에이전트가 인증 오류가 아닌 인증서 검증 오류로 실패하는 이유입니다.
  • 에이전트는 Proxy-Authorization 헤더로 자신을 식별합니다. 에이전트와 게이트웨이가 내부 Docker 네트워크를 공유하는 단일 장비 환경에서는 해당 헤더가 사용자가 제어하지 않는 네트워크를 통과하지 않습니다. 장비 외부의 에이전트를 게이트웨이에 연결할 때는 프록시 포트에 별도의 TLS 설정이 필요한데, 해당 헤더가 베어러 토큰(bearer token)이기 때문입니다.

정직한 거래: 게이트웨이는 설계상 에이전트가 만드는 모든 요청을 평문으로 읽습니다. 이는 해당 장비에서 가장 민감한 프로세스입니다. 따라서 호스트를 그에 맞게 관리하고, 로그인 가능한 인원을 최소 권한 Linux 사용자로 제한하십시오.

러너가 인바운드 포트를 필요로 하지 않는 이유

러너는 아웃바운드 전용으로 동작합니다. 러너 문서에 따르면 "러너는 외부에서 접근 가능한 포트를 열지 않으므로, 노트북, 홈랩, NAT 뒤에 있는 VPC 등 어떤 환경에서도 인그레스 설정, 터널링, TLS 종료 과정 없이 작동합니다." NAT는 네트워크 주소 변환(Network Address Translation)을 의미하며, 일반적인 가정용 공유기가 수행하는 기능입니다. 러너는 제어 평면(control plane)으로 먼저 연결을 시도하여 작업을 가져오기 때문에, 포트 포워딩을 하거나 방화벽을 열 필요가 없습니다.

이러한 설계는 샌드박스 네트워크에서 큰 이점을 제공합니다. compose 파일은 internal: true으로 표시된 두 번째 네트워크를 정의하는데, Docker에서 이는 호스트 외부로 나가는 경로가 전혀 없음을 의미합니다. 샌드박스는 이 네트워크에 참여합니다. 게이트웨이는 두 네트워크 모두에 연결된 듀얼 홈(dual-homed) 상태이므로, 외부로 나가는 유일한 통로가 됩니다. 러너 문서는 이 점을 명확히 설명합니다. "게이트웨이가 듀얼 홈으로 연결된 internal 네트워크는 게이트웨이 전용 이그레스를 단순한 권고 사항이 아닌 강력한 경계로 만듭니다." 따라서 임의의 주소로 소스 코드를 전송하려는 에이전트는 이를 수행할 경로를 찾을 수 없습니다.

위 내용을 단순히 믿기보다 직접 자신의 장비에서 확인하십시오.

docker network ls
docker network inspect onecli-sandboxes | grep -i internal

"Internal": true가 출력되어야 합니다. 만약 false으로 표시된다면 이그레스 제어 기능이 꺼진 상태이며, 게이트웨이는 다시 단순한 권고 사항으로 전락합니다. onecli-sandboxes은 기본값일 뿐이므로, docker network ls이 출력하는 샌드박스 네트워크 이름을 사용하십시오.

OneCLI 샌드박스의 보안 수준은 어느 정도인가?

이 섹션은 천천히 읽어야 합니다. 프로젝트 설명에서 "샌드박스(sandboxed)"라는 표현은 매우 중요하게 다뤄지지만, 정작 그 메커니즘은 단 한 곳에서만 설명하고 있기 때문입니다.

README에는 각 에이전트가 "파일 시스템과 셸을 갖춘 고유의 격리된 샌드박스"를 가진다고 명시되어 있으며, "각 샌드박스 내부에서 실행되어 벤더 중립적인 하니스 인터페이스를 통해 에이전트 런타임을 교체 가능하게 만드는" 구성 요소로 Sandbox Supervisor를 언급합니다. 하지만 이 문장들 어디에도 격리가 구체적으로 어떻게 구현되는지는 나와 있지 않습니다. 러너(runner)의 문서를 보면 기본 백엔드가 Docker(RUNNER_BACKEND=docker)이며, 샌드박스는 메모리 제한, CPU 제한, 프로세스 제한이 설정되고 내부 네트워크에 연결된 Docker 컨테이너임을 알 수 있습니다. 코드에는 다른 백엔드를 위한 연결 지점이 마련되어 있고, 문서에는 누군가 구현해야 할 모듈로서 Kubernetes나 microVM 같은 예시가 언급되어 있습니다. 현재 귀하의 서버에서 샌드박스는 곧 컨테이너입니다.

문서에서 언급하지 않는 부분도 중요합니다. 위협 모델에 대한 정의가 없습니다. Docker 데몬을 rootless로 실행하는지, 사용자 네임스페이스 리매핑(user namespace remapping)을 사용하는지, Docker 기본값 이상의 seccomp나 AppArmor 프로필을 적용하는지, gVisor나 microVM과 같은 커널 경계가 존재하는지에 대한 언급이 없습니다. 따라서 좁은 의미로 해석해야 합니다. 설정된 제한은 리소스 제한일 뿐입니다. 내부 네트워크는 확실한 외부 통신(egress) 제어 수단입니다. 에이전트와 호스트 사이의 격리는 일반적인 Docker 컨테이너가 제공하는 수준이며, 컨테이너는 호스트 커널을 공유합니다.

고려해야 할 두 번째 사실이 있습니다. 러너 서비스는 /var/run/docker.sock을 마운트하는데, 이것이 샌드박스를 생성하는 방식이기 때문입니다. Docker 소켓에 접근할 수 있다는 것은 호스트의 root 권한을 가진 것과 같습니다. 해당 API를 호출할 수 있는 사람은 누구나 호스트 파일 시스템을 내부에 마운트한 컨테이너를 시작할 수 있기 때문입니다. 모든 Docker 기반 러너가 이런 방식으로 작동합니다. 결과적으로 러너 프로세스는 게이트웨이만큼이나 민감한 보안 대상입니다.

업스트림에서 명확히 문서화하기 전까지는 이 경계를 신뢰할 수 없는 것으로 간주하십시오. 실무적으로는 다음 세 가지 습관을 권장합니다.

  1. OneCLI는 다른 작업이 없는 전용 서버에서 실행하십시오. 관련 없는 운영 서비스, 공유 데이터베이스, 다른 팀의 데이터가 있는 서버는 피해야 합니다.
  2. 샌드박스 내부에서 임의 코드 실행 권한을 얻은 에이전트가 호스트까지 도달할 수 있다고 가정하십시오. 해당 상황이 발생하더라도 서버 외부의 백업을 통해 복구할 수 있도록 대비하십시오.
  3. 동료에게 에이전트가 완벽히 격리되어 있다고 말하기 전에 apps/runner/src을 읽어보거나 업스트림에 문의하십시오.

문서화된 보안 경계가 어떤 모습인지, 그리고 업스트림에 어떤 질문을 던져야 할지 파악하려면 실제 에이전트 샌드박스 경계의 예시와 비교해 보십시오. 차이점은 메커니즘이 명확히 기술되어 있는지, 그리고 무엇을 막지 못하는지가 명시되어 있는지에 달려 있습니다.

라이선스 분리와 빌드 전 확인이 필요한 이유

OneCLI의 핵심 코드는 Apache-2.0 라이선스를 따르며, 프로덕션 환경에서 직접 호스팅하는 것이 허용됩니다. ee/라는 이름의 디렉터리는 별도의 OneCLI Enterprise License를 따릅니다. 이 라이선스는 개발, 테스트, 평가 용도로는 무료이지만, 프로덕션 환경에서 사용하려면 구독이 필요합니다. 2026년 8월 18일에 릴리스된 v2.0.1 릴리스 노트에는 GitHub에서 감지 가능한 Apache-2.0 라이선스 파일을 복구했다는 내용이 포함되어 있어, 최근 저장소 페이지의 배지 정보가 변경되었습니다. 특정 날짜에 작성된 요약본을 보기보다는 실제로 배포하려는 태그를 직접 확인하십시오.

cd onecli && find . -type d -name ee -not -path '*/node_modules/*'

해당 경로 아래에 있는 모든 항목은 상용 라이선스 대상입니다. 의존하려는 기능이 해당 경로에 포함되어 있다면, 프로세스를 구축하기 전에 비용을 먼저 산정하십시오.

업그레이드, 마이그레이션, 그리고 절대 잃어버려선 안 될 파일 하나

업그레이드는 버전 업데이트와 재시작으로 이루어집니다. 모든 up마다 API가 실행되기 전에 일회성 마이그레이션 서비스가 먼저 작동하며, 마이그레이션이 실패하면 스택은 절반만 마이그레이션된 스키마로 서비스를 제공하는 대신 실행을 거부합니다. 이는 의도된 동작입니다. 업그레이드 실패가 조용한 데이터 손상으로 이어지는 대신 서비스 중단으로 나타나게 하기 위함이며, 그 이유는 docker compose logs migrations에 설명되어 있습니다.

cd onecli/docker
docker compose pull
docker compose up -d --wait
docker compose logs migrations

만약 설치 스크립트를 사용하여 설치했다면, 수동으로 이미지를 가져오기(pull)보다는 해당 스크립트를 다시 실행하십시오. 그래야 compose 파일이 참조하는 이미지와 일치하는 상태를 유지할 수 있습니다.

두 가지를 반드시 백업하십시오. PostgreSQL은 에이전트, 대화 내용, 메모리, 그리고 암호화된 비밀 정보를 보관합니다. docker/.env 파일은 SECRET_ENCRYPTION_KEY을 담고 있으며, 이 키가 없으면 암호화된 비밀 정보를 읽을 수 없습니다. 따라서 데이터베이스 덤프만으로는 아무것도 복구할 수 없습니다.

cd onecli/docker
docker compose exec -T postgres pg_dump -U onecli onecli | gzip > ~/onecli-db.sql.gz
install -m 600 .env ~/onecli-env.backup

두 백업본 모두 서버 외부의 안전한 곳에 보관하십시오. 이는 상태를 유지하는 모든 Compose 스택에 필요한 동일한 절차입니다. 이미 Docker Compose 스택 백업 및 업그레이드를 정기적으로 수행하고 있다면, 이 두 경로를 백업 목록에 추가하고 더 이상 고민하지 마십시오.

작동하지 않을 때

  • 스택이 정상 상태가 되지 않고 docker compose up -d --wait이 0이 아닌 종료 코드를 반환합니다. API가 해당 서비스를 의도적으로 대기하므로 docker compose logs migrations을 먼저 읽어보십시오.
  • 에이전트가 유휴 상태로 머물고 샌드박스가 나타나지 않습니다. COMPOSE_PROFILES=runnerdocker/.env에 있는지, 그리고 docker compose ps에 러너가 나열되어 있는지 확인하십시오. 그런 다음 에이전트에 부여된 모델 키가 있는지 확인하십시오. 모델 키 없이는 샌드박스가 실행되지 않습니다.
  • 슬롯이 부족합니다. RUNNER_MAX_SANDBOXES의 기본값은 4이며, 백그라운드 프로세스가 실행 중인 샌드박스는 슬롯을 영구적으로 점유합니다. docker ps을 통해 실제로 활성화된 항목을 확인할 수 있습니다.
  • 컨테이너가 사라지거나 호스트가 매우 느려집니다. 메모리가 부족한 상태입니다. dmesg -T | grep -i oom는 커널의 OOM(Out-of-Memory) 킬 기록을 담고 있으며, 샌드박스 하나가 단독으로 2048 MB를 점유할 수 있습니다.
  • 에이전트의 HTTPS 호출이 인증 오류가 아닌 인증서 검증 오류로 실패합니다. HTTP 클라이언트가 게이트웨이의 인증 기관(CA)을 신뢰하지 않는 경우입니다.
  • 에이전트를 삭제한 후에도 이전 컨테이너나 볼륨이 남아 있습니다. 러너는 60초마다 조정 작업을 수행하며 RUNNER_ORPHAN_GRACE_SECONDS(기본값 3600)보다 오래된 고아 리소스를 삭제합니다. 따라서 누수라고 판단하기 전에 1시간 정도 기다려 보십시오.

이 도구를 실행하는 것이 적절한 선택입니까?

적합성 테스트는 짧습니다. 여러 사람이 각자 에이전트를 필요로 하고 자격 증명을 한곳에서 관리해야 할 때 OneCLI가 유용합니다. 자격 증명을 순환시킬 저장소 하나, 감사 로그 하나, 그리고 특정인의 접근 권한을 취소했을 때 실제로 권한이 회수되는 대시보드 하나가 필요하기 때문입니다. 이는 실질적인 운영상의 문제이며, API 키를 6대의 노트북에 복사하는 것은 이에 대한 나쁜 해결책입니다.

한 명의 사용자에게는 이득에 비해 시스템 구성이 너무 복잡합니다. 단일 에이전트를 사용하기 위해 PostgreSQL, 제어 평면(control plane), 게이트웨이, 러너를 모두 실행해야 합니다. 키를 본인만 소유하고 있다면 게이트웨이가 해결하는 자격 증명 문제는 거의 존재하지 않습니다. 대신 더 작은 서버에서 단일 하네스를 실행하십시오. VPS에서의 단일 에이전트 하네스는 훨씬 적은 메모리로 해당 작업을 수행합니다. 아직 방향을 정하지 않았다면 셀프 호스팅 AI 에이전트 비교 설문 조사를 먼저 확인하는 것이 더 경제적인 첫걸음입니다.

FAQ

OneCLI를 자체 호스팅하기 위한 최소 서버 사양은 무엇입니까?

Docker Compose 플러그인 2.19 버전 이상과 충분한 메모리가 필요합니다. PostgreSQL은 compose 파일에 포함되어 있으므로 별도로 설치할 필요가 없습니다. 메모리 용량에 따라 플랜이 결정됩니다. 러너(runner)는 기본적으로 에이전트 샌드박스당 2048 MB를 할당하며, 기본값인 4개의 샌드박스를 운영하려면 기본 스택 외에 약 10 GiB의 여유 메모리가 필요합니다. PostgreSQL과 4개의 상시 실행 서비스에는 약 2 GB가 소요됩니다. 4 GB 메모리 서버에서는 한 번에 하나의 에이전트만 실행할 수 있습니다. 16 GB 메모리 서버는 기본 설정치를 충분히 수용합니다. 1 GB 또는 2 GB VPS에서는 호스팅된 에이전트를 전혀 시작할 수 없습니다.

OneCLI는 PostgreSQL이 필요한가요, 아니면 SQLite를 사용할 수 있나요?

PostgreSQL이 반드시 필요합니다. DATABASE_URL은 PostgreSQL 연결 문자열로 문서화되어 있으며, 제공된 compose 파일은 pgdata 볼륨을 사용하는 postgres:18-alpine을 실행합니다. 또한 API가 시작되기 전에 별도의 마이그레이션 서비스가 스키마를 적용합니다. SQLite 옵션은 문서화되어 있지 않습니다. 이미 다른 곳에서 PostgreSQL을 운영 중이라면 DATABASE_URL를 해당 서버로 지정하고 마이그레이션 서비스를 유지하십시오. 마이그레이션이 실패할 경우 스키마가 절반만 적용된 상태로 서비스되는 것을 방지하기 위해 스택 전체를 중단시키는 것이 좋습니다.

OneCLI 에이전트 샌드박스는 실제 보안 경계 역할을 하나요?

문서화된 메커니즘은 메모리, CPU, 프로세스 제한이 적용된 Docker 컨테이너이며, internal: true으로 표시된 네트워크에 연결되어 게이트웨이를 통하지 않고는 외부로 나가는 경로가 없습니다. 외부 통신 제어는 확실하며 docker network inspect을 통해 확인할 수 있습니다. 호스트 격리는 컨테이너 수준이며, 업스트림에서 위협 모델, rootless 또는 사용자 네임스페이스 지원, gVisor나 microVM과 같은 커널 수준의 경계에 대해 명시한 바가 없습니다. 또한 러너는 호스트의 root 권한과 동일한 /var/run/docker.sock를 마운트합니다. 업스트림의 공식 입장이 있기 전까지는 에이전트와 호스트 사이의 경계를 신뢰할 수 없는 것으로 간주하고, OneCLI를 전용 서버에서 실행하며 백업은 해당 서버 외부에 보관하십시오.

OneCLI를 위해 인바운드 포트를 열어야 하나요?

아니요. 러너는 아웃바운드 전용이며 외부에서 접근 가능한 포트를 열지 않으므로, 터널링 없이 NAT 환경 뒤에서도 작동합니다. compose 파일은 기본적으로 대시보드, 게이트웨이, API, PostgreSQL을 127.0.0.1에 바인딩합니다. 대시보드에 접근하려면 SSH 터널을 사용하거나, 여러 사용자가 접근해야 할 경우 10254 포트 앞에 TLS를 지원하는 리버스 프록시를 배치하십시오. 10255 포트의 게이트웨이는 에이전트용이며, 단일 서버 환경에서는 에이전트들이 내부 Docker 네트워크를 통해 해당 포트에 접근합니다.

OneCLI를 회사 내부에서 무료로 사용할 수 있나요?

핵심 코드는 Apache-2.0 라이선스를 따르며, 상업용 라이선스 없이 자체 호스팅 환경에서 프로덕션 용도로 사용할 수 있습니다. ee/라는 이름의 디렉터리는 OneCLI Enterprise License의 적용을 받습니다. 이는 개발, 테스트, 평가 용도로는 무료이지만 프로덕션 환경에서는 구독이 필요합니다. 라이선스 범위는 릴리스마다 변경될 수 있으며, 2026년 8월 18일 자 v2.0.1 릴리스 노트에는 GitHub에서 감지 가능한 Apache-2.0 라이선스 파일을 복구했다는 내용이 포함되어 있습니다. 따라서 특정 기능을 기반으로 워크플로우를 구축하기 전에 배포하려는 정확한 태그 버전에서 LICENSEee/ 디렉터리를 확인하십시오.