yona is a free, open source project & work management project written in Kotlin and released under Apache-2.0. It has 500 GitHub stars, 157 forks and 234 open issues, and was last pushed 65 minutes ago. On this registry it ranks #64 of 67 tracked projects in Project & Work Management, with 5 head-to-head comparisons available.

[English]

yona

21세기 협업 개발 플랫폼
  • Official Site: http://yona.io
  • 이 저장소는 Yona(Play Framework/Java/Ebean 기반의 설치형 프로젝트 협업 플랫폼)를 Kotlin + Spring Boot + JPA(Hibernate) 스택으로 새로 옮겨 쓴 프로젝트입니다. 화면 구조·데이터 모델·동작 방식은 legacy Yona와 최대한 동일하게 유지하면서, 런타임과 빌드 도구만 현재 JVM 생태계로 교체하는 것을 목표로 합니다.

Yona란?

  • Git/SVN/Mercurial 저장소가 내장된 설치형 이슈 트래커 + 게시판 + 코드 리뷰 플랫폼
  • 네이버/네이버랩스를 비롯해 여러 기업·공공기관에서 수년간 실사용되며 다듬어진 애플리케이션

주요 기능

  • 서비스 종료나 데이터 종속 걱정 없는 설치형
  • 프로젝트 기반의 유연한 이슈 트래커와 게시판 — 프로젝트 간 이슈 이동, 서브 태스크, 본문 변경이력, 이슈 템플릿
  • 내장 코드 저장소 — Git / SVN / Mercurial 3종 선택 가능, 온라인 수정·커밋, HTTP(S)뿐 아니라 SSH로도 접근 가능, 프로젝트 멤버 전용 접근 제어, Git LFS 지원
  • 블록 기반 코드 리뷰 — 코드 블록 단위 리뷰 스레드, 리뷰 점수
  • 그룹(조직) 기능 — 그룹 단위 이슈/게시글 통합 관리, 그룹 프로젝트·멤버
  • 한글 기반 — 프로젝트 이름 및 그룹 이름에 한글 사용 가능
  • 계정 보안 — LDAP 지원, 소셜 로그인(OAuth2), 2단계 인증(TOTP 앱 + WebAuthn/패스키), 백업 코드, 로그인 브루트포스 방지, 알려진 기기 인식
  • 저장소 접근/서명 — SSH 공개키 등록, GPG 커밋 서명 검증, 저장소별 Deploy Key
  • API 및 자동화 — 범위(scope) 지정 가능한 개인용 API 토큰(PAT), 서드파티 앱을 위한 OAuth2 Authorization Server(Dynamic Client Registration 포함), MCP(Model Context Protocol) 서버 내장 — Claude 등 AI 에이전트가 OAuth2로 인증해 이슈/PR/위키에 직접 접근 가능 (아래 참고)
  • 감사 로그 — 주요 보안/관리 이벤트 추적
  • 다른 서비스·다른 Yona 인스턴스로의 마이그레이션(GitHub 프로젝트 Import 등)

추가 읽을거리

Yona (New): 무엇이 바뀌었나

Old Yona New Yona
언어 Java / Scala 템플릿 Kotlin
프레임워크 Play Framework 2.x Spring Boot
ORM Ebean JPA / Hibernate
뷰 엔진 Scala Template(.scala.html) Thymeleaf
JDK Java 8 Java 21
지원 DB MariaDB(기본) 또는 H2(내장형) MariaDB / PostgreSQL / MySQL / SQL Server / CUBRID / H2(내장형)
지원 VCS Git / SVN Git / SVN / Mercurial

포팅 진행 상황과 legacy 대비 의도적으로 남겨둔 차이점은 docs/parity/index.md, docs/TEMPLATE_BACKLOG.md, docs/coverage/index.md에 기록돼 있습니다.

이식 과정에서 legacy에는 없던 기능도 새로 추가됐습니다:

  • Mercurial 저장소 지원(기존 Git/SVN 2종에서 3종으로)
  • 2단계 인증(TOTP 앱 + WebAuthn/패스키) 및 로그인 보안 강화(브루트포스 방지, 알려진 기기 인식)
  • GPG 커밋 서명 검증, 저장소별 Deploy Key
  • 범위 지정 API 토큰(PAT)OAuth2 Authorization Server(서드파티 앱 연동, Dynamic Client Registration)
  • MCP(Model Context Protocol) 서버 내장 — 자세한 내용은 아래 참고
  • 감사 로그(보안/관리 이벤트 추적)

프론트엔드 위젯: Vue 3 Web Components로 점진 전환

일부 화면 위젯은 jQuery 기반 vanilla JS에서 Vue 3 Web Components로 옮겨가고 있습니다. 각 위젯은 하이브리드 어댑터 방식으로 적용됩니다 — 기존 vanilla yona.*.js 파일이 대상 엘리먼트가 새 커스텀 엘리먼트인지 확인해 맞으면 그 컴포넌트에 위임하고, 아니면 원래 로직을 그대로 씁니다. 그래서 화면 템플릿을 건드리지 않는 위젯(Typeahead/Pagination 등)도 있고, 템플릿의 태그 하나만 바뀌는 위젯도 있습니다.

  • 위젯 소스: yona-projects/components (Vue 3 SFC를 네이티브 커스텀 엘리먼트로 빌드, 위젯마다 자체 Shadow DOM을 가짐)
  • 빌드 산출물은 src/main/resources/static/lib/yona-vue-widgets/에 그대로 커밋돼 있어서, components 저장소를 따로 클론/빌드하지 않아도 이 저장소만으로 바로 실행됩니다.
  • 현재 적용된 위젯(17개): Dialog, Toast, Popover, LoginDialog, Switch, Dropdown, Typeahead, Pagination, Attachments, ScrollElevator, PageSlide, ReviewForm, 마크다운 도움말(HelpMarkdown), 라벨 편집기 3종(새 라벨 폼, 카테고리 편집 다이얼로그, 라벨 편집 다이얼로그)
  • 화면 전반에서 공유하는 마크다운 에디터 프래그먼트는 이번 전환 범위에서 제외했습니다 — 에디터의 ``가 Shadow DOM에 완전히 캡슐화돼 있어, 그 프래그먼트를 참조하는 기존 JS(첨부파일 드래그드롭, 임시저장 등)가 여러 화면에서 깨지기 때문입니다. ReviewForm 안에서 쓰는 마크다운 에디터는 그 공용 프래그먼트와 무관한 별개 인스턴스라 이 문제가 없어 전환 대상에 포함했습니다.

AI 에이전트 연동 (MCP 서버)

yona는 MCP(Model Context Protocol) 서버를 내장하고 있어, Claude 같은 AI 에이전트가 이슈·PR·위키 페이지를 직접 조회·조작할 수 있습니다.

  • 엔드포인트는 /mcp(Streamable HTTP) 하나이며, spring-ai-starter-mcp-server-webmvc@Tool로 표시된 메서드를 자동으로 노출합니다(IssueMcpTools/PullRequestMcpTools/WikiMcpTools).
  • 인증은 OAuth2(yona 자체가 Dynamic Client Registration을 지원하는 OAuth2 Authorization Server 역할을 겸함) 또는 범위 지정 API 토큰(PAT) 둘 다로 가능합니다 — 도구 호출마다 McpScopeGuard가 해당 토큰/토큰의 스코프로 실제 접근 가능한지 재검사합니다.
  • API 토큰 발급/스코프 관리는 사용자 설정 화면(API 토큰)에서, OAuth 앱 등록은 사용자 설정 화면 (OAuth 앱)에서 할 수 있습니다.

요구 사항

  • JDK 21
  • 운영/테스트 DB 중 하나: MariaDB(기본), PostgreSQL, MySQL, SQL Server, CUBRID, H2(설치 없이 바로 써보기)

빌드 & 실행

# Linux / macOS
./gradlew bootRun

# Windows
gradlew.bat bootRun

테스트:

./gradlew test        # Linux/macOS
gradlew.bat test       # Windows

데이터베이스 선택

기본 Spring 프로파일은 mariadb입니다. 다른 DB로 운영하려면 spring.profiles.active를 아래 중 하나로 지정하세요(src/main/resources/application.yml에 각 프로파일의 접속 설정이 있습니다). 로컬 개발용 MariaDB/PostgreSQL 컨테이너는 저장소 루트의 docker-compose.yml로 바로 띄울 수 있습니다.

프로파일 DB
mariadb (기본값) MariaDB
postgres PostgreSQL
mysql MySQL
mssql Microsoft SQL Server
cubrid CUBRID
h2 H2(내장형) — Docker/별도 서버 설치 없이 파일 기반으로 바로 실행(./data/h2/yona)
java -jar yona.jar --spring.profiles.active=postgres

# 설치 없이 바로 써보기(H2)
java -jar yona.jar --spring.profiles.active=h2

통합 테스트는 실제 Docker 컨테이너(Testcontainers) 기준으로 5개 서버 DB 전부 검증돼 있습니다 (H2는 내장형이라 컨테이너가 필요 없습니다). 특정 DB로만 테스트를 돌리려면(동시에 두 개 이상 돌리면 gradle 빌드 출력 디렉터리가 꼬이니 항상 한 번에 하나씩만 실행하세요):

./gradlew test -Dyona.it.db=postgres   # mariadb|postgres|mysql|mssql|cubrid|h2

운영 환경 설정 (특히 Windows)

물리 저장소(git bare repo, svn repo, git-lfs 객체, 첨부파일 업로드)를 디스크의 어느 경로에 둘지는 아래 4개 설정으로 제어합니다. 기본값이 /tmp/yona/... 형태의 유닉스 절대경로이기 때문에, Windows에서 운영할 때는 반드시 아래 값들을 Windows 경로로 재설정해야 합니다.

설정 키 기본값 용도
yona.git.base-dir /tmp/yona/git Git bare 저장소 루트
yona.svn.base-dir /tmp/yona/svn SVN 저장소 루트
yona.lfs.base-dir /tmp/yona/lfs Git LFS 객체 저장 루트
yona.upload.base-dir ${yona.data:data}/uploads (상대경로) 첨부파일 업로드 루트

설정 변경 방법

  1. application.yml에 직접 지정 (가장 확실한 방법)

    yona:
      git:
        base-dir: "D:/yona-data/git"
      svn:
        base-dir: "D:/yona-data/svn"
      lfs:
        base-dir: "D:/yona-data/lfs"
      upload:
        base-dir: "D:/yona-data/uploads"
    

    Windows 경로도 슬래시(/)로 적으면 됩니다(자바가 두 구분자를 모두 인식합니다). 백슬래시를 쓸 경우 YAML 이스케이프 때문에 \\로 두 번 써야 하므로, 슬래시 표기를 권장합니다.

  2. 실행 시 커맨드라인 인자로 지정 (application.yml을 건드리지 않고 배포별로 다르게 줄 때)

    java -jar yona.jar --yona.git.base-dir=D:\yona-data\git --yona.svn.base-dir=D:\yona-data\svn --yona.lfs.base-dir=D:\yona-data\lfs --yona.upload.base-dir=D:\yona-data\uploads
    

    -D로 JVM 시스템 프로퍼티를 주는 방식(java -Dyona.git.base-dir=D:\... -jar yona.jar)도 동일하게 동작합니다.

  3. 환경 변수 — Spring Boot의 relaxed binding 규칙상 yona.git.base-dir에 대응하는 환경 변수명은 YONA_GIT_BASEDIR처럼 하이픈(-)이 빠진 형태입니다(다른 YONA_* 설정들처럼 밑줄로 치환되는 게 아님). 헷갈리기 쉬우므로 1번(yml) 또는 2번(커맨드라인 인자) 방식을 권장합니다.

Windows에서 Fork(하드링크 복제) 사용 시 전제 조건

프로젝트 Fork는 저장소를 실제로 복사하지 않고 파일시스템 하드링크로 복제합니다 (ProjectServiceImpl.cloneHardLinkedRepository). 이 방식이 정상 동작하려면:

  • yona.git.base-dir(및 yona.svn.base-dir) 전체가 하나의 NTFS 볼륨(드라이브) 안에 있어야 합니다. 서로 다른 드라이브 간에는 하드링크가 불가능해 Fork가 실패합니다(폴백 복사 없음, 의도적 설계).
  • 저장 위치가 NTFS여야 합니다. FAT32/exFAT로 포맷된 외장 디스크나 일부 네트워크 드라이브는 하드링크 자체를 지원하지 않아 Fork가 실패합니다.

서버 관련 설정

  • LDAP: application.ymlldap 섹션
  • 소셜 로그인(OAuth2): application.ymlspring.security.oauth2 섹션
  • WebAuthn(패스키): application.ymlyona.security.webauthn.relying-party-id/ relying-party-name — 배포 도메인에 맞게 반드시 재설정해야 합니다(기본값은 localhost).
  • 2단계 인증(TOTP) 암호화 키: 환경변수 YONA_TOTP_ENCRYPTION_PASSWORD/ YONA_TOTP_ENCRYPTION_SALT배포 전 반드시 설정해야 합니다. 기본값은 저장소에 커밋된 placeholder 값(yona-totp-dev-only-password 등)이라, 프로덕션에서 이 값을 그대로 쓰면 모든 사용자의 TOTP 시크릿이 소스코드로 노출된 키로 암호화되어 2단계 인증이 실질적인 보호 효과가 없어집니다. 이 값을 설정하지 않고 부팅하면 서버 로그에 [SECURITY WARNING] TOTP encryption key is still the committed placeholder default 에러가 남으니, 배포 파이프라인에서 이 로그를 감시하는 것도 권장합니다(TotpEncryptionKeyGuard).
  • SSH(Git/Mercurial 접근, SSH 키 등록): SSH: 시스템 sshd 연동
  • GPG 커밋 서명 검증, Deploy Key, API 토큰/OAuth2 앱은 별도 설정 없이 기본 활성화되어 있으며, 사용자별 설정 화면에서 바로 쓸 수 있습니다.

Google Analytics

  • legacy와 동일하게 Google Analytics 트래킹 스크립트가 실제로 구현되어 있습니다 (GlobalModelAttributeAdvicesendYonaUsage 모델 속성을 채우면 templates/site/layout.html이 그 값에 따라 GA 스크립트를 렌더링합니다).

  • 다만 기본값은 legacy(application.send.yona.usage = true, 기본 켜짐)와 반대로 꺼짐(false) 입니다. 켜고 싶다면 application.yml에서 아래 항목을 true로 설정합니다.

    yona:
      analytics:
        send-usage: true
    

마이그레이션

  • GitHub 프로젝트를 이 저장소로 Import하는 기능을 제공합니다(MigrationService, MigrationApiController). github.client.id / github.client.secret / github.allow.migration 설정으로 활성화합니다.
  • Yona의 별도 백업/이관 도구인 Yona Export는 이 저장소(Kotlin/Spring 이식판) 대상으로는 아직 포팅되지 않았습니다 — 진행 상황은 docs/parity/index.md 참고.

Contribution

  • 코드 기여의 기준이 되는 브랜치는 next입니다(main은 오래된 스냅샷이라 실제 개발은 전부 next에서 이루어지고 있습니다 — 저장소의 기본 브랜치도 next입니다).

readme truncated — read the full docs on github

Frequently asked questions

Is yona free to use?

yona is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does yona do?

Project Hosting SW

What is yona written in?

yona is primarily written in Kotlin. Its source is publicly available at https://github.com/yona-projects/yona, and it has 500 GitHub stars.