Fly.io에서 Hermes Agent 실행하기
Hermes는 Nous Research가 만든 AI 에이전트로, 자체 학습 루프가 내장되어 있어요. 즉 자기 출력을 지켜보며, 작업을 끝내기 위해 즉흥적으로 해야 했던 부분을 알아차리고 그 경험을 다음에 호출할 수 있는 재사용 가능한 스킬로 다시 기록합니다. 스킬 라이브러리는 사용할수록 커지기 때문에, Hermes는 수명이 짧은 샌드박스보다 오래 실행되는 영구 호스트에서 가장 잘 동작하며, 볼륨이 연결된 Fly Machine이 바로 그러한 환경을 제공합니다. 이 가이드는 Hermes를 Fly Machine에서 실행하고, 구성하고, 웹 대시보드에 노트북에서 접근하는 방법을 안내합니다.
출처: 문서
본문
Hermes는 Nous Research의 AI 에이전트로, 내장된 학습 루프를 갖추고 있어요. 자기 출력을 지켜보면서 작업을 끝내기 위해 즉흥적으로 행동해야 했던 순간을 알아차리고, 그 경험을 다음에 호출할 수 있는 재사용 가능한 스킬로 다시 기록합니다. 스킬 라이브러리는 사용할수록 커지기 때문에, Hermes는 수명이 짧은 샌드박스보다 영구 호스트에서 지속적으로 실행될 때 가장 잘 동작합니다. 볼륨이 연결된 Fly Machine이 바로 정확히 그러한 환경을 제공해요.
이 가이드는 Hermes를 Fly Machine에서 실행하고, 구성하고, 노트북에서 웹 대시보드에 접근하는 방법을 안내합니다.
flyctl 설치, Fly.io 계정(무료 체험으로 충분) 그리고 LLM API 키(Anthropic, OpenAI, Google Gemini, 또는 200개 이상의 모델에 접근할 수 있는 OpenRouter)가 필요합니다.
여러분은 Nous Research의 공식 프리빌트 이미지(nousresearch/hermes-agent:latest)를 사용하게 됩니다. 따라서 유지 관리할 Dockerfile도, 기다려야 할 원격 빌더도 없어요. Fly가 Docker Hub에서 이미지를 바로 가져옵니다.
앱과 볼륨 만들기
Hermes는 모든 상태를 컨테이너 내부의 /opt/data에 보관합니다. 여기에는 구성, API 키, 세션, 스킬, 메모리가 포함돼요. 이를 Fly 볼륨으로 백업해서 배포와 재시작에도 상태가 유지되도록 합니다.
앱 이름(Fly에서 전역적으로 고유해야 함)과 자신과 가까운 리전을 선택한 다음:
fly apps create <your-hermes-app>
fly volumes create data -a <your-hermes-app> --region <region> --size 3
3GB는 세션과 번들된 스킬 디렉터리에 넉넉한 여유 공간입니다.
fly.toml 작성하기
배포 구성을 위한 디렉터리를 만들고 그 안에 fly.toml을 넣으세요:
app = "<your-hermes-app>"
primary_region = "<region>"
machine_config = "machine_config.json"
[build]
image = "nousresearch/hermes-agent:latest"
[[mounts]]
source = "data"
destination = "/opt/data"
[[vm]]
memory = "4gb"
cpus = 2
machine_config 키는 다중 컨테이너 Machine의 컨테이너를 정의하는 JSON Machine 구성 파일을 가리킵니다. 그 containers 배열의 각 항목은 Machines API의 ContainerConfig 스키마를 따릅니다.
fly.toml 옆에 그 파일(이 예시에서는 machine_config.json)을 만드세요:
{
"containers": [
{
"name": "hermes",
"image": "nousresearch/hermes-agent:latest",
"cmd": ["gateway", "run"]
}
]
}
몇 가지 참고 사항:
[build.dockerfile]없음. Fly가 이미지를 직접 가져와요. 배포는 몇 분이 아니라 몇 초면 끝납니다.s6-overlay를 위한 다중 컨테이너 Machine.v2026.5.28이후에 게시된 Hermes 이미지는 컨테이너 내 슈퍼바이저로s6-overlay를 사용해요. s6-overlay의/init는s6-overlay-suexec를 호출하는데, 이는 무엇보다 먼저getpid() == 1을 확인하고 그렇지 않으면 중단합니다. Hermes를 다중 컨테이너 Machine(machine_config.json사용)의 컨테이너로 실행하면 자체 PID 네임스페이스를 얻으므로/init가 PID 1로 실행됩니다.[[services]]블록 없음. 게이트웨이는 채팅 플랫폼으로 아웃바운드 통신을 하므로 공용 포트가 필요하지 않아요. 대시보드는 API 키를 노출하므로 공개되면 안 되며, 아래의 Fly 프록시 터널을 통해 접근하게 됩니다.- 4GB / 2 CPU는 브라우저 도구(Playwright/Chromium)가 활성화된 경우 권장 크기입니다. 브라우저 도구를 사용하지 않는다면
shared-cpu-1x와 1–2GB로 낮출 수 있어요.
선택사항: API 키를 Fly 시크릿으로 전달하기
이 가이드는 첫 배포 후 hermes setup을 통해 API 키를 입력합니다. 키를 Fly 시크릿으로 관리하고 싶다면, 배포 전에 시크릿을 설정하세요:
fly secrets set ANTHROPIC_API_KEY=sk-... -a <your-hermes-app>
그런 다음 각 키를 machine_config.json의 컨테이너 secrets 배열 아래에 나열하세요. 각 항목은 { "env_var": "<NAME>" } 형식이며, <NAME>은 앱에 이미 존재하는 시크릿과 정확히 일치해야 합니다:
{
"containers": [
{
"name": "hermes",
"image": "nousresearch/hermes-agent:latest",
"cmd": ["gateway", "run"],
"secrets": [
{ "env_var": "ANTHROPIC_API_KEY" }
]
}
]
}
나열된 시크릿이 존재하지 않으면 Machine이 시작되지 않아요. fly logs에 오류 없이 배포가 타임아웃됩니다. fly secrets list -a <your-hermes-app>를 실행해 확인하세요. 전체 항목 형식은 MachineSecret를 참고하세요.
배포
fly deploy -a <your-hermes-app> --ha=false
--ha=false는 단일 Machine으로 유지합니다. 기본적으로 fly deploy는 가용성을 위해 Machine을 두 개 만듭니다. Fly 볼륨은 Machine 간에 공유할 수 없으므로 두 번째 Machine은 빈 볼륨을 얻고, 자체 구성, 세션, 스킬을 가진 별도의 Hermes 인스턴스를 실행하게 됩니다.
배포가 끝나면 머신이 부팅되고, 엔트리포인트가 /opt/data를 부트스트랩하며(.env, config.yaml, SOUL.md, sessions/, skills/ 등을 생성), hermes gateway run이 시작됩니다. 계속 실행되지만 아직 API 키가 없으므로 모델과 통신할 수 없어요.
살아있는지 확인하세요:
fly logs -a <your-hermes-app>
번들된 스킬이 동기화된 다음 게이트웨이가 시작되는 것을 볼 수 있어야 합니다.
Hermes 구성하기
머신에 SSH로 접속합니다. hermes 바이너리는 이미지 내부의 /opt/hermes/.venv/bin/hermes에 있지만, fly ssh console은 PATH를 리셋하는 로그인 셸을 열기 때문에 거기서 찾을 수 없어요. 항상 PATH에 있는 /usr/local/bin에 심볼릭 링크를 추가해서 hermes를 단순한 명령으로 사용할 수 있게 해 주세요:
fly ssh console -a <your-hermes-app> -C \
"ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes"
그런 다음 머신에서 셸을 열고 설정 마법사를 실행하세요:
fly ssh console -a <your-hermes-app>
hermes setup
마법사는 모델 선택, 도구 구성, 메시징 플랫폼 연결을 안내합니다. 끝나면 SSH 세션을 종료하세요.
게이트웨이가 새 구성을 적용하도록 머신을 다시 시작합니다:
fly machine restart <machine-id> -a <your-hermes-app>
<machine-id>는 fly machine list -a <your-hermes-app>에서 얻을 수 있어요.
웹 대시보드
Hermes는 포트 9119에 세션, 스킬, 구성을 관리하는 웹 대시보드를 갖추고 있어요. 대시보드는 API 키를 읽으므로, 상위 지침은 이를 공용 포트에 절대 노출하지 말라는 것입니다. 대신 터널로 접근하세요.
Fly 프록시는 Machine에 사설 IPv6 주소로 접근하므로, 대시보드는 localhost가 아닌 모든 인터페이스에서 수신해야 해요. Hermes가 루프백 주소 이외의 것에 바인딩하면 대시보드 인증을 요구합니다. 먼저 사용자 이름과 비밀번호를 설정하세요.
노트북에서 세션 시크릿을 생성합니다:
openssl rand -base64 32
그런 다음 머신에서 셸을 열고 볼륨의 Hermes .env에 자격 증명을 추가하세요. 생성한 값을 시크릿으로 붙여넣습니다:
fly ssh console -a <your-hermes-app>
cat >> /opt/data/.env <<'ENV'
HERMES_DASHBOARD_BASIC_AUTH_USERNAME=admin
HERMES_DASHBOARD_BASIC_AUTH_PASSWORD=<a-strong-password>
HERMES_DASHBOARD_BASIC_AUTH_SECRET=<generated-secret>
ENV
이 값들은 볼륨에 있으므로 배포와 재시작에도 유지됩니다.
같은 셸(또는 새 fly ssh console --pty 세션)에서 IPv6 와일드카드 주소에 바인딩해 대시보드를 시작하세요. ::를 대괄호 없이 전달합니다:
hermes dashboard --no-open --host ::
두 번째 터미널에서 노트북에서 Fly 프록시를 엽니다:
fly proxy 9119:9119 -a <your-hermes-app>
이제 브라우저에서 http://localhost:9119를 방문해 설정한 사용자 이름과 비밀번호로 로그인하세요. 트래픽은 인증된 WireGuard 터널을 통해 이동합니다. 대시보드는 공용 인터넷에 게시되지 않지만, 조직의 사설 네트워크에 있는 다른 Machine에서는 접근할 수 있어요.
다 끝나면 두 명령 모두 Ctrl+C로 종료하세요. 게이트웨이는 머신에서 계속 실행됩니다.
업그레이드
이미지는 무상태(stateless)이며, 데이터는 볼륨에 있습니다. 최신 Hermes를 가져오려면:
fly deploy -a <your-hermes-app>
fly ssh console -a <your-hermes-app> -C \
"ln -sf /opt/hermes/.venv/bin/hermes /usr/local/bin/hermes"
배포는 nousresearch/hermes-agent:latest를 다시 가져옵니다. 두 번째 명령은 /usr/local/bin/hermes 심볼릭 링크를 다시 만듭니다. 이 링크는 데이터 볼륨이 아닌 컨테이너의 파일시스템에 있으므로, 새 컨테이너는 링크 없이 시작됩니다.
VM 크기 조정
과중한 도구 사용이나 여러 동시 세션을 실행한다면 크기를 늘리세요:
fly scale memory 8192 -a <your-hermes-app>
fly scale vm shared-cpu-4x -a <your-hermes-app>
유용한 명령
| 명령 | 설명 |
|---|---|
fly logs -a <your-hermes-app> |
실시간 로그 스트리밍 |
fly ssh console -a <your-hermes-app> |
머신에 SSH 접속 |
fly ssh console -a <your-hermes-app> -C "hermes doctor" |
헬스 체크 |
fly machine restart <id> -a <your-hermes-app> |
구성 변경 후 재시작 |
fly status -a <your-hermes-app> |
머신 상태 확인 |
fly volumes list -a <your-hermes-app> |
연결된 볼륨 나열 |
fly ssh console -a <your-hermes-app> -C "hermes skills list" |
학습한 스킬 나열 |
문제 해결 (Troubleshooting)
게이트웨이가 시작되지 않음
누락된 API 키 또는 기타 진단이 있는지 hermes doctor를 확인하세요:
fly ssh console -a <your-hermes-app> -C "hermes doctor"
배포가 "timeout reached waiting for machine's state to change"로 타임아웃됨
fly logs가 "Successfully prepared image" 이후에 멈추고 Machine이 시작되지 않는다면, machine_config.json의 secrets 배열에 있는 모든 시크릿이 존재하는지 확인하세요:
fly secrets list -a <your-hermes-app>
누락된 시크릿은 Hermes가 실행되기 전에 Machine을 중지시키므로, Hermes 자체는 아무것도 기록하지 않습니다.
메모리 부족
RAM을 늘리세요:
fly scale memory 8192 -a <your-hermes-app>
처음부터 다시 시작해야 할 때
구성 파일을 지우세요(스킬, 세션, 메모리는 유지됩니다):
fly ssh console -a <your-hermes-app> -C \
"sh -c 'rm -f /opt/data/config.yaml /opt/data/.env'"
fly machine restart <machine-id> -a <your-hermes-app>
fly ssh console -a <your-hermes-app>
hermes setup
대화까지 모두 지우려면 볼륨을 파괴하고 다시 만드세요:
fly machine stop <machine-id> -a <your-hermes-app>
fly volumes destroy <volume-id> -a <your-hermes-app>
fly volumes create data -a <your-hermes-app> --region <region> --size 3
fly machine start <machine-id> -a <your-hermes-app>
스킬이 예상치 못하게 동작함
나열, 보기, 삭제:
fly ssh console -a <your-hermes-app>
hermes skills list
hermes skills view <skill-name>
hermes skills delete <skill-name>