Docker, Compose, 원클릭 PaaS
Distroless/Debian 이미지, Compose 배포, 헬스 체크, Podman, 그리고 Coolify/Dokploy/EasyPanel 템플릿.
Revka는 단일 자급자족 바이너리로 배포되므로 컨테이너 환경에 자연스럽게 적합합니다. 이 페이지에서는 Docker에서 Revka를 실행하는 방법을 다룹니다. 공개된 두 가지 이미지, 프로덕션용 docker-compose.yml, 컨테이너 환경 변수 레퍼런스, HEALTHCHECK 프로브, Podman 차이점, 그리고 세 가지 원클릭 PaaS 템플릿(Coolify, Dokploy, EasyPanel)과 각 릴리스와의 동기화 워크플로를 설명합니다.
서버 또는 PaaS 호스트에서 Revka를 장기 실행 게이트웨이로 운용하려는 경우 이 페이지를 참고하세요. 호스트의 OS init 시스템으로 직접 Revka를 관리하려면 백그라운드 서비스로 실행을 참고하세요. 컨테이너 내부 runtime.kind 샌드박스와 호스트 런타임의 차이에 대해서는 런타임 모드, 어댑터 및 리소스 제한을 참고하세요.
컨테이너 이미지
섹션 제목: “컨테이너 이미지”두 가지 멀티 아키텍처 이미지가 GitHub Container Registry에 게시됩니다. 동일한 빌드를 공유하지만 런타임 베이스가 다릅니다.
| 이미지 | 베이스 | 셸 | 사용 시점 |
|---|---|---|---|
ghcr.io/kumihoio/revka:latest | gcr.io/distroless/cc-debian13:nonroot | 없음 | 공격 표면을 최소화하고 에이전트가 셸 도구를 필요로 하지 않는 경우. |
ghcr.io/kumihoio/revka:debian | debian:bookworm-slim (bash, git, curl, ca-certificates 포함) | 있음 | 에이전트가 셸 기반 도구(ls, git, curl 등)를 필요로 하는 경우. |
두 이미지 모두 동일한 엔트리포인트를 사용합니다. revka daemon을 실행하며, 이는 게이트웨이, 채널, 하트비트, 스케줄러를 하나의 감독 프로세스 아래 통합한 완전 자율 런타임입니다. 두 이미지 모두 비권한 사용자 nobody(UID 65534)로 실행되고, 포트 42617을 노출하며, HOME=/revka-data와 워크스페이스 경로 /revka-data/workspace를 설정합니다.
빠른 시작
섹션 제목: “빠른 시작”런타임에 API 키를 제공하고, /revka-data를 명명된 볼륨에 유지하며, 게이트웨이 포트를 게시합니다.
docker run -d \ --name revka \ -e API_KEY=sk-or-... \ -e PROVIDER=openrouter \ -v revka-data:/revka-data \ -p 42617:42617 \ ghcr.io/kumihoio/revka:latest이후 http://localhost:42617/에서 대시보드를 열 수 있습니다. 이미지에는 allow_public_bind = true와 require_pairing = false가 설정된 기본 config가 내장되어 있어 컨테이너 외부에서 즉시 게이트웨이에 접근할 수 있습니다.
이미지 빌드 인수
섹션 제목: “이미지 빌드 인수”두 Dockerfile 모두 컴파일할 Cargo 기능 플래그를 제어하는 단일 빌드 인수를 허용합니다.
| Build ARG | 기본값 | 의미 |
|---|---|---|
REVKA_CARGO_FEATURES | channel-lark,whatsapp-web | cargo build --release --locked --features에 전달되는 쉼표로 구분된 Cargo 기능 목록. 기본 기능 세트만 빌드하려면 빈 값으로 설정하세요. |
# Build the distroless image with a custom feature setdocker build --build-arg REVKA_CARGO_FEATURES="channel-lark" -t revka:custom .
# Build the Debian (shell-equipped) variantdocker build -f Dockerfile.debian -t revka:debian .빌드는 멀티 스테이지 파이프라인입니다. web-builder 스테이지(Node 22 Alpine)에서 대시보드를 컴파일하고, builder 스테이지(Rust 1.95)에서 레지스트리/타겟 빌드 캐시를 사용하여 바이너리를 컴파일하며, 최종 스테이지에서 스트립된 바이너리를 distroless 또는 Debian 런타임에 복사합니다. 빌드 결과 바이너리가 1 MB 미만이면 빌드가 즉시 실패하는데, 이는 더미/캐시 전용 빌드 아티팩트를 감지하기 위함입니다. 전체 기능 목록은 Cargo 기능 플래그 및 ADR을 참고하세요.
컨테이너 환경 변수 레퍼런스
섹션 제목: “컨테이너 환경 변수 레퍼런스”이미지에는 /revka-data/.revka/config.toml에 동작하는 config.toml이 내장되어 있습니다. 일반적으로 API 키만 제공하면 되며, 나머지는 컨테이너에 적합한 기본값을 사용합니다. 환경 변수는 런타임에 내장된 config를 덮어씁니다.
| 변수 | 기본값 | 의미 |
|---|---|---|
API_KEY / REVKA_API_KEY | 없음 | LLM 공급자 API 키. 필수 — 런타임에 반드시 제공해야 합니다. |
PROVIDER | openrouter | LLM 공급자 ID. :latest 이미지는 설정하지 않아 config 파일 편집이 우선합니다. Debian/dev 이미지는 기본값으로 설정합니다. |
REVKA_MODEL | 공급자 기본값 | 모델 재정의(예: anthropic/claude-sonnet-4-20250514). |
REVKA_ALLOW_PUBLIC_BIND | true(Compose/템플릿에서 설정) | 컨테이너 네트워킹에 필수 — 없으면 게이트웨이가 루프백 외 바인드를 거부합니다. |
REVKA_GATEWAY_PORT | 42617 | 컨테이너 내부 게이트웨이 리슨 포트. |
LANG | C.UTF-8 | CJK 및 멀티바이트 입력을 올바르게 처리하기 위한 UTF-8 로케일. |
HOME | /revka-data | 홈 디렉터리. config는 /revka-data/.revka/에 위치합니다. |
REVKA_WORKSPACE | /revka-data/workspace | 에이전트 워크스페이스 경로. |
공급자별 키 변수(OPENROUTER_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY 등)도 사용 가능하며 범용 API_KEY보다 우선합니다. 전체 환경 변수 재정의 목록은 구성 개요를 참고하세요.
Docker Compose 배포
섹션 제목: “Docker Compose 배포”저장소에는 프로덕션에 최적화된 docker-compose.yml 참조 파일이 포함되어 있습니다. restart: unless-stopped, 리소스 제한, 명명된 볼륨, 헬스 체크가 구성되어 있습니다. 명령줄이나 .env 파일로 API 키를 제공하세요.
services: revka: image: ghcr.io/kumihoio/revka:latest # For ARM64 where distroless exits immediately, switch to: # image: ghcr.io/kumihoio/revka:debian container_name: revka restart: unless-stopped environment: - API_KEY=${API_KEY:-} - PROVIDER=${PROVIDER:-openrouter} - REVKA_ALLOW_PUBLIC_BIND=true - REVKA_GATEWAY_PORT=${REVKA_GATEWAY_PORT:-42617} volumes: - revka-data:/revka-data ports: - "${HOST_PORT:-42617}:${REVKA_GATEWAY_PORT:-42617}" deploy: resources: limits: cpus: "2" memory: 512M reservations: cpus: "0.5" memory: 32M healthcheck: test: ["CMD", "revka", "status", "--format=exit-code"] interval: 60s timeout: 10s retries: 3 start_period: 10s
volumes: revka-data:라이프사이클 명령어:
# Start in the background (inline key)API_KEY=sk-or-... docker compose up -d
# Stop and remove the container (the named volume is kept)docker compose down
# Follow logsdocker compose logs -f revka
# Publish on a different host port (e.g. 42617 is already taken)HOST_PORT=8080 docker compose up -d또는 Compose 파일 옆에 .env 파일로 설정을 관리할 수 있습니다.
API_KEY=sk-or-...PROVIDER=openrouterHOST_PORT=42617REVKA_GATEWAY_PORT=42617| 변수 | 기본값 | 의미 |
|---|---|---|
API_KEY | 없음 | 공급자 API 키(필수). |
PROVIDER | openrouter | 공급자 ID. |
HOST_PORT | 42617 | ports 매핑에서 호스트 측 포트. |
REVKA_GATEWAY_PORT | 42617 | 컨테이너 측 게이트웨이 포트. |
설정된 리소스 제한은 컨테이너를 최대 2 CPU / 512 MB로 제한하고 0.5 CPU / 32 MB를 예약합니다. Revka의 메모리 사용량은 적으므로 단일 인스턴스에는 충분한 기본값입니다. 다수의 채널이나 대용량 MCP 사이드카를 실행할 경우 제한을 높이세요.
헬스 체크
섹션 제목: “헬스 체크”두 Dockerfile과 Compose 파일 모두 동일한 활성 프로브를 사용합니다.
healthcheck: test: ["CMD", "revka", "status", "--format=exit-code"] interval: 60s timeout: 10s retries: 3 start_period: 10srevka status --format=exit-code는 표준 컨테이너 활성 확인 방법입니다. 사람이 읽을 수 있는 상태 보고서를 출력하는 대신, 설정된 게이트웨이에 경량 GET /health 요청을 수행하여 게이트웨이가 정상이면 0, **그렇지 않으면 1**을 종료 코드로 반환합니다. 프로브는 바인드 호스트가 [::] 또는 0.0.0.0이면 127.0.0.1로 정규화하고, 설정된 gateway.port를 사용하며, 5초 타임아웃을 적용합니다. start_period는 데몬에 10초의 바인드 대기 시간을 부여하여 재시도 예산에 영향을 주기 전에 초기화를 완료할 수 있도록 합니다.
실행 중인 컨테이너에서 수동으로 실행하려면:
docker exec revka revka status --format=exit-code; echo "exit=$?"Podman
섹션 제목: “Podman”이미지와 Compose 파일은 Podman에서도 동일하게 실행되며, 루트리스 Podman의 사용자 네임스페이스와 SELinux 처리를 위한 두 가지 조정이 필요합니다.
--userns keep-id를 추가하여 컨테이너의 UID65534가 호스트 사용자에게 올바르게 매핑되고 볼륨이 쓰기 가능한 상태를 유지하도록 합니다.- 볼륨 마운트에
:Z접미사를 추가하여 SELinux가 컨테이너용으로 재레이블링하도록 합니다.
podman run -d \ --name revka \ --userns keep-id \ -e API_KEY=sk-or-... \ -e PROVIDER=openrouter \ -v revka-data:/revka-data:Z \ -p 42617:42617 \ ghcr.io/kumihoio/revka:latestpodman compose는 동일한 docker-compose.yml을 읽습니다. 환경 변수, 헬스 체크, 게시된 포트 등 나머지는 Docker와 동일합니다.
원클릭 PaaS 템플릿
섹션 제목: “원클릭 PaaS 템플릿”Revka에는 세 가지 셀프 호스팅 PaaS 플랫폼을 위한 초안 템플릿이 있습니다. 각 템플릿은 동일한 컨테이너, revka-data 볼륨, 포트 42617, 표준 헬스 체크를 프로비저닝합니다. 차이점은 플랫폼별 이미지 고정 방식과 API 키 시크릿 생성 방식에 있습니다.
Coolify
섹션 제목: “Coolify”Coolify 템플릿(marketplace/coolify/revka.yaml)은 ghcr.io/kumihoio/revka:latest 태그를 대상으로 하는 Compose 서비스입니다. Coolify 사용자는 재배포 시 새 버전을 자동으로 받습니다. Coolify의 ${SERVICE_PASSWORD_APIKEY} 헬퍼를 통해 무작위 API 키가 자동 생성됩니다.
- Coolify에서 새 서비스 → Compose를 생성합니다(또는 병합 후 커뮤니티 템플릿 사용).
PROVIDER환경 변수를 설정하고(기본값openrouter), 자동 생성된API_KEY를 수락하거나 직접 입력합니다.- 배포합니다. 포트
42617이 노출되며, 리소스 기본값은 0.5–2 CPU 및 32M–512M 메모리입니다.
Dokploy
섹션 제목: “Dokploy”Dokploy 블루프린트(marketplace/dokploy/blueprints/revka/)는 고정된 이미지가 필요합니다. Dokploy는 latest 태그를 허용하지 않으므로 ghcr.io/kumihoio/revka:2026.4.21과 같은 CalVer 태그를 참조합니다. 블루프린트에는 도메인과 64자 API 키를 생성하는 docker-compose.yml과 template.toml이 포함되어 있습니다.
[variables]main_domain = "${domain}"api_key = "${password:64}"
[config]env = [ "API_KEY=${api_key}", "PROVIDER=openrouter", "REVKA_ALLOW_PUBLIC_BIND=true", "REVKA_GATEWAY_PORT=42617"]
[[config.domains]]serviceName = "revka"port = 42617host = "${main_domain}"- Dokploy에서 Templates를 열고 “Revka”를 검색합니다(리스팅 병합 후 사용 가능).
API_KEY(또는 생성된 키 수락)와PROVIDER를 설정합니다.- 배포합니다. Dokploy가 생성된 도메인을 포트
42617의 서비스에 할당합니다.
EasyPanel
섹션 제목: “EasyPanel”EasyPanel 템플릿(marketplace/easypanel/)도 고정된 이미지가 필요하며 스키마 기반 폼을 제공합니다. meta.yaml에는 네 가지 필드가 정의되어 있습니다.
| 필드 | 기본값 | 의미 |
|---|---|---|
appServiceName | revka | EasyPanel 내 서비스 이름. |
appServiceImage | ghcr.io/kumihoio/revka:2026.4.21 | 고정된 이미지 태그. |
apiKey | 없음 | LLM 공급자 API 키. |
provider | openrouter | openrouter, openai, anthropic, ollama 중 하나. |
- EasyPanel에서 **Apps → Browse Templates → “Revka”**로 이동합니다.
- API 키를 입력하고 공급자를 선택합니다.
- 배포합니다. 배포 후 게이트웨이에 포트
42617로 접근할 수 있습니다.
마켓플레이스 자동 동기화 워크플로
섹션 제목: “마켓플레이스 자동 동기화 워크플로”GitHub Actions 워크플로(marketplace/sync-marketplace-templates.yml)가 세 플랫폼의 리스팅을 최신 상태로 유지합니다. 각 안정 릴리스 이후 — Docker 이미지가 빌드되어 GHCR에 푸시된 후 실행 — Coolify, Dokploy, EasyPanel 업스트림 저장소에 새 이미지 태그가 포함된 풀 리퀘스트를 엽니다.
- 입력:
release_tag— CalVer 태그(예:2026.4.21). - 시크릿:
MARKETPLACE_PAT— 세 업스트림 저장소의KumihoIO포크에 푸시하고 PR을 열 수 있는repo+workflow스코프의 GitHub 토큰. - 트리거: Docker 작업 이후 안정 릴리스 파이프라인에서 자동 실행. 수동 디스패치도 가능합니다.
버전 처리는 플랫폼별로 다릅니다. Coolify는 :latest를 사용하므로 재배포 시 자동으로 업데이트되어 워크플로가 태그를 변경할 필요가 없습니다. 반면 Dokploy와 EasyPanel은 고정 태그가 필요하므로 워크플로가 각 릴리스마다 이미지 태그(및 EasyPanel의 변경 로그)를 재작성합니다. 각 플랫폼의 최초 리스팅은 자동 동기화가 시작되기 전에 수동 PR로 제출해야 합니다.