Hermes Agent 배포 문제 해결

개요 및 최종 구성 ← 이 문서는 배포 과정에서 발생한 문제 해결을 다룹니다.


문제 1: 포트 충돌 (port already allocated)

증상: 배포 로그에서 Bind for 0.0.0.0:8642 failed: port is already allocated 에러

원인: ports:로 호스트에 직접 바인딩 시 이전 컨테이너가 포트를 점유 중이면 충돌

해결: ports:expose: 로 변경. Dokploy Traefik이 내부 Docker 네트워크로 직접 라우팅하므로 호스트 포트 노출 불필요.

- ports:
-   - "8642:8642"
+ expose:
+   - "8642"

문제 2: Dashboard Restarting (1) 루프 ⭐

증상: Gateway는 정상 실행되나 Dashboard가 계속 Restarting (1) 상태

hermes-dydp3k-dashboard-1    Restarting (1) 25 seconds ago
hermes-dydp3k-gateway-1      Up About a minute

원인: hermes dashboard --host 0.0.0.0 명령어에 보안 가드 존재. Hermes 소스코드(hermes_cli/web_server.py:start_server) 확인 결과:

if host not in _LOCALHOST and not allow_public:
    raise SystemExit(
        "Refusing to bind to {host} — the dashboard exposes API keys..."
    )

0.0.0.0127.0.0.1, localhost, ::1이 아니므로 SystemExit(1) 발생 → Docker가 exit code 1 감지 → restart: unless-stopped에 의해 재시작 → 무한 루프

해결: --insecure 플래그 추가

- command: dashboard --host 0.0.0.0 --no-open
+ command: dashboard --host 0.0.0.0 --no-open --insecure

Note

Dokploy bridge 네트워크에서는 컨테이너가 격리되어 있으므로 0.0.0.0 바인딩이 필수. network_mode: host를 사용하면 127.0.0.1로도 가능하지만 Dokploy의 Traefik 라우팅과 호환되지 않음.


문제 3: Gateway API 서버 비활성화

증상: Dashboard 상태 화면에 Gateway가 “NOT RUNNING” / “STOPPED”로 표시됨. /api/status에서 gateway_running: false

원인: Gateway 컨테이너는 Docker 상에서 running이지만, 내부 Hermes 프로세스가 API_SERVER_HOST/API_SERVER_PORT 설정 없이 시작되어 API 서버가 비활성화됨

해결: Gateway 컨테이너에 API 서버 환경변수 추가

environment:
  API_SERVER_HOST: "0.0.0.0"
  API_SERVER_PORT: "8642"

문제 4: API 키 미인식 (Compose env vs .env 파일)

증상: Docker Compose environment:OPENAI_API_KEYOPENAI_BASE_URL을 주입했지만 Dashboard의 /api/env에서 is_set: false로 표시됨

원인: Hermes entrypoint가 .env 파일을 /opt/data/.env에 생성하지만, 환경변수로 전달된 값은 .env 파일에 기록되지 않음. Dashboard는 .env 파일을 읽어서 API 키 존재 여부를 확인

API 키 저장 방식 두 가지

  • Docker Compose environment: — 컨테이너 프로세스에 환경변수로 전달. Hermes entrypoint가 읽지만 .env 파일에는 반영 안 됨
  • Dashboard /api/env PUT — Hermes 내부 .env 파일에 직접 기록. Gateway가 실제로 참조함

해결: Dashboard API로 .env 파일에 직접 API 키 기록

TOKEN=$(curl -s https://gommes.jimin.io/ | grep -o '__HERMES_SESSION_TOKEN__="[^"]*"' | cut -d'"' -f2)
 
curl -X PUT "https://gommes.jimin.io/api/env" \
  -H "x-hermes-session-token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"key":"OPENAI_API_KEY","value":"sk-..."}'
 
curl -X PUT "https://gommes.jimin.io/api/env" \
  -H "x-hermes-session-token: ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"key":"OPENAI_BASE_URL","value":"https://api.jiminbox.com/v1"}'

문제 5: 502 Bad Gateway (gateway-only 배포 시)

증상: gateway만 단독 배포 시 https://gommes.jimin.io/ 접속하면 502

원인: Gateway의 기본 포트(8642)는 OpenAI 호환 API 서버로, 웹 UI 아님. 웹 UI는 dashboard(9119)에서 제공

해결: 도메인을 dashboard:9119로 라우팅


문제 6: 컨테이너 강제 교체 (redeploy가 안 될 때)

증상: dokploy_compose-redeploy로는 dashboard 컨테이너가 재생성되지 않음 (3일 전 이미지 그대로)

원인: Dokploy의 redeploy가 변경사항을 감지하지 못함

해결: dokploy_docker-stopContainer로 기존 컨테이너 중지 후 재배포하여 신규 컨테이너로 교체. 또는 compose 파일에 command를 약간 변경(예: --port 9119 추가)하여 변경 감지 트리거.