콘텐츠로 이동

시작하기

Evo Docs 작성근거 · framework/evomind/web/workflow-project-evo-service기준 · 릴리스 v0.12.0커밋 · 2e32c6cc파일 · site/authored/evo-chat/getting-started.md기준선 · 2026-11-12

Evo Chat은 조직 안에서 여러 LLM 모델을 연결해 쓰는 웹 채팅 서비스입니다. 브라우저 화면은 Evo Chat이고, 로그인·대화·관리 기능을 처리하는 백엔드 API는 Evo Service입니다. 화면에 보이는 서비스 이름은 evo입니다.

설치는 Docker Compose로 하는 납품 번들로 제공되며, 폐쇄망에서도 번들만으로 설치할 수 있습니다.

번들의 Compose 파일(프로젝트 이름 evomind-chat)은 다음 세 컨테이너를 실행합니다.

서비스 이미지 역할 호스트 포트
web evo-chat 채팅 화면(nginx가 정적 화면을 제공) WEB_PORT (기본 80)
app evo-api Evo Service API. 로그인, 대화, 관리 기능, DB 마이그레이션 APP_PORT (기본 8080)
postgres postgres:17 데이터베이스. 데이터는 pgdata 볼륨에 저장 외부에 열지 않음

브라우저는 web에서 화면을 받은 뒤 app의 API를 직접 호출합니다. 그래서 .env의 API_BASE_URL과 CORS_ALLOWED_ORIGINS를 두 주소에 맞춰 둡니다.

작업 공간(웹 workflow)을 켜면 workspace 프로필의 컨테이너 세 개(workspace-runner, workspace-gateway, workspace-egress)가 함께 뜹니다. docker compose up -d만으로는 뜨지 않고, 켤 때 따로 --profile workspace로 띄웁니다. 작업 공간은 기본 꺼짐이며, 배포 구성과 설정은 작업 공간 배포를 보세요.

  • Docker와 Docker Compose(docker compose 명령)
  • 납품 번들 evo-chat-0.7.0.tar.gz와 체크섬 파일 evo-chat-0.7.0.tar.gz.sha256
    • Nexus 릴리스 폴더에서 받습니다(공개, 로그인 필요 없음). 지금 버전은 release/latest 파일(버전 한 줄)에 있고, 특정 버전은 release/<버전>/ 폴더에 있습니다. 예: https://nexus.bluewindsky.com/repository/evo-bin/evo-chat/release/0.7.0/evo-chat-0.7.0.tar.gz
  • 연결할 LLM의 OpenAI 호환 엔드포인트(주소는 /v1까지)
  1. 번들 체크섬을 확인하고 압축을 풉니다.

    터미널 창
    sha256sum -c evo-chat-0.7.0.tar.gz.sha256
    tar -xzf evo-chat-0.7.0.tar.gz
    cd evo-chat-0.7.0
  2. ./install.sh를 처음 실행합니다. 스크립트는 번들 안의 sha256sums로 파일 무결성을 확인하고, .env.example을 .env로 복사한 뒤 멈춥니다.

  3. .env를 열어 CHANGE_ME로 남은 값을 모두 채웁니다. CHANGE_ME가 남아 있으면 스크립트가 기동하지 않습니다.

  4. ./install.sh를 다시 실행합니다. 무결성 확인 → 이미지 로드(postgres, evo-api, evo-chat, 번들에 들어 있으면 evo-workspace) → .env의 EVOMIND_IMAGE·EVOMIND_WEB_IMAGE(작업 공간 이미지가 있으면 EVOMIND_WORKSPACE_IMAGE) 채우기 → docker compose up -d 순으로 진행됩니다.

  5. docker compose ps로 app과 web이 healthy가 될 때까지 기다립니다. DB 마이그레이션은 앱이 기동할 때 자동으로 적용됩니다.

번들에는 업그레이드 안내(UPGRADE.md)와 upgrade.sh도 들어 있습니다. 이전 버전에서 0.7.0으로 올릴 때도 새 번들의 upgrade.sh로 그대로 업그레이드되며 데이터는 유지됩니다. 필요한 DB 마이그레이션은 앱이 기동할 때 자동으로 적용되며(0.5.0보다 이전 버전에서 올릴 때는 V27~V31, 0.6.0의 채팅 첨부 표, 0.10.0의 종단간 암호화 키 표 V34, 0.12.0의 상대 기기 키 기억·재전송 확인 표 V35와 도구 흔적 표 V36), 기존 데이터를 바꾸는 마이그레이션은 없습니다.

값은 이 문서에 적지 않습니다. 비밀값은 .env에만 두고, .env를 저장소나 메신저에 올리지 않습니다. 기본값이 “비움”인 항목은 값을 넣지 않으면 그 기능이 꺼집니다.

항목 기본 의미
DB_PASSWORD CHANGE_ME PostgreSQL 비밀번호
JWT_SECRET CHANGE_ME 로그인 토큰 서명 키. 32바이트 이상 무작위 문자열
ADMIN_USERNAME admin 최초 관리자 아이디
ADMIN_PASSWORD CHANGE_ME 최초 관리자 비밀번호. 사용자가 한 명도 없을 때 처음 기동하면서 한 번만 쓰입니다
항목 기본 의미
WEB_PORT 80 화면 포트. 사용자는 이 포트로 접속합니다
APP_PORT 8080 API 포트
APP_MEMORY_LIMIT 2g 선택. API 컨테이너 메모리 상한. JVM 최대 힙은 이 값의 75%(기본 약 1.5GB)이며, 상한을 넘으면 컨테이너가 재시작됩니다. 메모리가 더 필요하면 키웁니다
API_BASE_URL 비움 브라우저가 호출할 API 주소. 비우면 화면과 같은 주소의 /api
CORS_ALLOWED_ORIGINS 비움 화면 주소(출처). 쉼표로 여러 개
SELF_SIGNUP_ENABLED false 사용자 자가 가입 허용 여부
FEATURE_PERMISSION_MODE roles 기능 권한 판정 방식. roles는 역할이 허용한 기능만 사용, legacy는 이전 방식
OPENAI_COMPATIBLE_BASE_URL, OPENAI_COMPATIBLE_API_KEY, OPENAI_COMPATIBLE_MODELS 비움 선택. 연결이 하나도 없을 때 처음 기동하면서 기본 LLM 연결과 모델(쉼표 구분)을 등록
항목 기본 의미
OIDC_ENABLED false SSO(OIDC) 로그인. 켜면 로그인 화면에 SSO 버튼이 나타납니다
OIDC_ISSUER_URI, OIDC_CLIENT_ID, OIDC_CLIENT_SECRET, OIDC_SUCCESS_REDIRECT_URI 비움 SSO 발급자, 클라이언트, 로그인 후 돌아갈 화면 주소
OIDC_SCOPES openid,profile,email 요청할 범위
OIDC_GROUPS_CLAIM groups 그룹 claim 경로
OIDC_GROUP_PREFIX 비움 이 접두사로 시작하는 그룹만 동기화
KEYCLOAK_SYNC_CLIENT_ID, KEYCLOAK_SYNC_CLIENT_SECRET 비움 앱에서 바꾼 SSO 계정의 그룹 소속을 Keycloak에도 반영하는 서비스 계정
LDAP_ENABLED false LDAP 로그인. 켜면 LDAP_URL, LDAP_BASE_DN 등이 필요합니다
항목 기본 의미
CLI_SESSION_ENABLED false evo CLI 조직 로그인용 CLI 세션 API
CLI_OIDC_ISSUER_URI 비움 CLI 로그인 토큰의 발급자
CLI_OIDC_CLIENT_IDS evo-cli CLI 로그인에 허용할 클라이언트 ID. evo-api를 직접 부르는 클라이언트(evo CLI, 데스크톱 앱 등)만 두고, MCP 서버 전용 로그인 클라이언트는 넣지 않습니다 — 넣으면 그 MCP 서버가 받은 토큰으로 사용자의 CLI 키를 받을 수 있게 됩니다
CLI_OIDC_AUDIENCE 비움 선택. 값을 넣으면 로그인 토큰의 aud에 그 값이 있어야 합니다(없거나 다르면 401). 켜기 전에 Keycloak·evo CLI가 그 스코프를 요청하도록 맞춰야 하며, 맞추지 않으면 구판 evo CLI가 로그인하지 못합니다
CLI_KEY_TTL PT12H CLI 세션 키 수명
CLI_RATE_LIMIT_PER_MINUTE 20 IP·사용자별 분당 요청 상한
CLI_LITELLM_CONNECTION, CLI_LITELLM_ADMIN_KEY 비움 둘 다 있으면 CLI에 사람별 LiteLLM 가상 키를 발급
CLI_LITELLM_TEAM_ID 비움 선택. 가상 키를 발급할 LiteLLM 팀 ID
CLI_LITELLM_PUBLIC_URL 비움 선택. CLI에 알려 줄 LiteLLM 접속 주소(연결 주소에 CLI가 닿을 수 없을 때)
CLI_LITELLM_BUDGET_DURATION 1mo 선택. 월 사용 금액 한도에 쓰는 LiteLLM 사용자 예산 주기(LiteLLM budget_duration 표기). 이 표기를 모르는 LiteLLM이면 30d로 바꿉니다
CLI_LITELLM_SPEND_CACHE_TTL PT30S 선택. 채팅 전 누적 금액 조회 결과를 다시 쓰는 시간(ISO-8601). 0이면 매번 조회합니다
CLI_LITELLM_SPEND_TIMEOUT PT3S 선택. 누적 금액 조회 제한 시간. 넘거나 조회가 실패하면 채팅을 막지 않고 경고 로그를 남깁니다
GATEWAY_USER_PREFIX 비움 업스트림 요청의 사용자 표기 앞부분. 비우면 발급자 주소의 마지막 경로
항목 기본 의미
DISPATCH_ENABLED false 웹 대화를 작업 요청 세션으로 쓰는 연동. DISPATCH_URL도 있어야 켜집니다. SSO 계정만 쓸 수 있습니다
DISPATCH_URL 비움 dispatch 서버 기본 주소(/v1·/mcp는 붙이지 않음)
DISPATCH_HEARTBEAT_INTERVAL PT20S 활성 신호 주기
DISPATCH_LEASE_TTL PT75S 브라우저 탭이 대화를 붙잡고 있는 시간
DISPATCH_TIMEOUT PT5S dispatch 호출 시간 제한
DISPATCH_MAX_ACTIVE_CONVERSATIONS 10 선택. 사용자당 동시에 활성(연결)일 수 있는 대화 수(다른 탭·기기 포함). 넘으면 새 대화는 연결하지 않고 안내만 보입니다. 0 이하면 제한 없음. 기본값만 쓰면 따로 넣지 않아도 됩니다
DISPATCH_E2E_ENABLED true 세션 작업 요청의 종단간 암호화. 끄면 공개키를 싣지 않고 세션 요청을 보낼 수 없습니다(평문 받기만 됨). “평문으로 보내기” 경로는 없습니다
DISPATCH_E2E_KEY_SECRET 비움 비어 있으면 JWT 서명 비밀에서 유도하는, 기기 개인키를 감싸는 비밀. 바꾸면 그 전에 온 안 읽은 암호 메시지는 읽을 수 없습니다. 로그·응답에 쓰지 않습니다
DISPATCH_BUGS_ENABLED false 계정 메뉴의 “버그 신고”(화면 캡처 첨부, 내 버그 상태 보기). dispatch 연동이 켜져 있고 dispatch 서버의 버그 신고 공간도 켜져 있어야 합니다. 값이 없으면 옛 DISPATCH_BOARD_ENABLED 값을 이어받습니다
DISPATCH_BUGS_PRODUCTS CHAT,CLI,EMULATOR,MAC,WINDOWS,DISPATCH 고를 수 있는 버그 분류(쉼표 구분, 첫 값이 기본). dispatch 서버 설정과 맞춥니다
DISPATCH_BUGS_TIMEOUT PT30S 버그 신고 호출 시간 제한. 이미지를 실어 보내 DISPATCH_TIMEOUT보다 깁니다
TITLE_MODEL, TITLE_LLM_BASE_URL 비움 선택. 둘 다 있으면 대화 제목을 모델(Ollama)로 만들고, 아니면 첫 메시지 앞부분을 제목으로 씁니다

모델이 웹을 검색하고 공개 페이지를 읽는 기본 도구입니다. 별도 MCP 서버 없이 evo-api에 들어 있고 기본은 켜짐입니다.

항목 기본 의미
WEB_SEARCH_ENABLED true false면 검색·페이지 읽기 두 도구를 모두 끕니다
WEB_SEARCH_TOOLS tavily,searxng,duckduckgo 검색 중계에 묻는 도구 순서. 401이면 바로 멈추고, 그 밖의 실패는 다음 도구로 넘어갑니다
WEB_SEARCH_MAX_PER_TURN 5 응답 1건의 검색 횟수 상한(최대 20)
WEB_FETCH_ENABLED true false면 페이지 읽기(web_fetch)만 끕니다

검색은 그 답변에 쓰는 모델 연결(openai_compatible = LiteLLM)의 주소·키로 POST /v1/search/{도구}를 부릅니다. 연결 키가 이 경로를 허용해야 하며, 채팅 경로만 허용하면 검색이 403으로 실패합니다(대화는 그대로 진행). 연결이 LiteLLM이 아니면 검색은 열리지 않고 페이지 읽기만 됩니다.

첫 관리자 로그인과 관리자 설정

섹션 제목: “첫 관리자 로그인과 관리자 설정”
  1. 설치한 서버에서 브라우저로 http://localhost를 엽니다(WEB_PORT를 바꿨으면 http://localhost:<WEB_PORT>, 예: http://localhost:8080). 다른 PC에서 열 때는 그 서버의 주소를 씁니다. 앞단에 TLS 프록시를 두었다면 프록시가 넘겨주는 실제 접속 주소를 씁니다 — 그 주소는 .env의 API_BASE_URL·CORS_ALLOWED_ORIGINS와 같아야 하고, 배포 담당자가 정합니다.
  2. ADMIN_USERNAME과 ADMIN_PASSWORD로 로그인합니다. 최초 비밀번호는 이후 “설정” → “계정”의 “비밀번호 변경”으로 바꿉니다.
  3. 머리글의 “⚙”(관리자 설정)를 눌러 관리자 화면으로 갑니다. 관리자 화면은 admin 그룹 구성원만 열 수 있습니다.

관리자 화면의 탭은 “프로바이더 연결”, “모델 프리셋”, “그룹 · 권한”, “사용자”, “CLI 키”, “사용량”, “감사 로그”, “API 게이트웨이”, “MCP 서버”, “스킬”, “관측성”, “설정”입니다. 탭마다 화면 캡처와 함께 관리자 설명서에서 자세히 안내합니다. 처음에는 다음 순서로 확인합니다.

  1. “프로바이더 연결”: .env로 기본 연결을 등록하지 않았다면 여기서 LLM 연결을 추가합니다. OpenAI 호환 주소는 /v1까지 넣습니다.
  2. “모델 프리셋”: 사용자에게 보여 줄 프리셋을 만듭니다.
  3. “사용자”: 계정의 표시명·이메일·계정 구분·활성 여부를 바꾸고, “역할”·“허용 모델”·“쿼터”(월 토큰·요청 상한)를 보거나 정하며, 로컬 계정은 “비밀번호”로 재설정합니다.
  4. “그룹 · 권한”: 그룹과 역할, 그룹별 허용 모델과 월 쿼터를 관리합니다.
  • 기본 그룹은 user와 admin이며 삭제할 수 없습니다. user에는 채팅·대화 기록·프리셋을 모두 허용하는 기본 역할 basic이 연결되어 있고, admin 구성원은 모든 권한을 가집니다.
  • user 또는 admin 그룹에 속한 계정만 로그인할 수 있습니다. 새로 만드는 로컬 계정은 역할에 맞는 기본 그룹에 자동으로 들어갑니다.
  • 사용자의 역할은 직접 부여한 역할과 소속 그룹 역할의 합입니다. 기능은 어느 역할이든 허용하면 쓸 수 있고, 어떤 역할도 허용하지 않으면 쓸 수 없습니다.
  • SSO 계정의 그룹 소속은 로그인할 때마다 Keycloak의 같은 이름 그룹에 맞춰집니다. 앱은 Keycloak 그룹을 새로 만들지 않으므로, Keycloak에 user·admin 그룹을 만들고 대상자를 넣어 둡니다.
  • LDAP 계정은 user 그룹에 자동으로 들어가지 않습니다. 디렉터리 그룹을 user로 맞추거나 관리자가 앱에서 넣어 줍니다.
  • 마지막 활성 관리자는 강등하거나 비활성화할 수 없습니다.