산돌이 서비스의 사용자 정보 및 인증을 중앙 집중 관리하는 MSA 서비스
- (이 Repository에서 사용하는 개발 프레임워크 및 주요 기술 스택을 작성하세요.)
keycloak: 사용자 인증 및 권한 관리
- (이 Repository가 담당하는 서비스의 역할을 간략히 설명하세요.)
- 사용자 관리 서비스
- (API 문서 링크를 삽입하세요.)
- 예시:
[API 문서 (Swagger)](링크),[API 문서 (Notion)](링크)
- 예시:
- (이 Repository에서 제공하는 서비스 관련 문서를 추가하세요.)
- 예시:
챗봇 명령어 목록,웹 서비스 이용 가이드,Webhook 사용법등
- 예시:
- Keycloak realm 백업/복원 절차는 이 README의
Keycloak realm 백업/복원섹션을 참고합니다.
- 모든 서비스는 Docker 기반으로 실행되므로, 로컬 환경에 별도로 의존하지 않음
- 환경 변수 파일 (
.env) 필요 시, 샘플 파일 (.env.example) 제공 - 루트
.env의SERVICE_DOMAIN은 Keycloak 컨테이너의KC_HOSTNAME으로 주입됨- 변수명을
KC_HOSTNAME으로 두지 않은 이유는 Keycloak 전용 값으로 고정하지 않고, 같은 도메인 값을 다른 서비스에서도 재사용할 수 있게 하기 위함
- 변수명을
- Docker Compose를 통해 서비스 간 네트워크 및 볼륨을 설정
- 프론트엔드 서비스(챗봇 서버, 웹 서비스)와 백엔드 서비스(API 서버)의 차이점을 반영하여 개별 실행 가능
docker compose up -ddocker compose up -d <서비스명>docker compose downdocker compose up -d --build이 저장소의 Keycloak realm JSON 파일은 Keycloak의 export 기능으로 생성한 결과물입니다.
- realm 설정 파일:
<realm>-realm.json - 사용자 파일:
<realm>-users-0.json,<realm>-users-1.json...
현재 저장소에서 확인되는 예시는 다음과 같습니다.
keycloak-export/Sandori-realm.jsonkeycloak-export/Sandori-users-0.jsonkeycloak-export/master-realm.jsonkeycloak-export/master-users-0.jsonbackup/keycloak-export/*.json도 같은 형식의 백업 사본으로 볼 수 있습니다.
Keycloak 공식 import/export 명령은 kc.sh export이며, 디렉터리 기준으로 내보내면 현재 저장소와 같은 파일 형식이 생성됩니다.
/opt/keycloak/bin/kc.sh export \
--dir /tmp/keycloak-export \
--users different_files \
--users-per-file 100특정 realm만 백업하려면 --realm 옵션을 추가합니다.
/opt/keycloak/bin/kc.sh export \
--dir /tmp/keycloak-export \
--realm Sandori \
--users different_files \
--users-per-file 100생성 후 /tmp/keycloak-export 아래에 다음과 같은 파일이 만들어집니다.
Sandori-realm.jsonSandori-users-0.json- 사용자 수가 많으면
Sandori-users-1.json같은 추가 파일
운영 서버에서 백업 파일을 갱신할 때는 export 결과를 꺼내서 별도 보관용 backup/keycloak-export/에 관리하면 됩니다.
Keycloak은 directory import 시 다음 파일명을 기준으로 realm을 읽습니다.
<realm>-realm.json<realm>-users-<번호>.json
이 저장소에는 Keycloak 백업/복원용 compose 파일이 있습니다.
- 루트
docker-compose.auth-bak.yml: 실제 운영 자동 백업 실행용 standalone compose 파일 sandol_user_service/docker-compose.auth-bak.yml: 값이 적용되지 않은 demo/template 파일- 루트
docker-compose.auth-restore.yml: 실제 운영 복원 실행용 standalone compose 파일 sandol_user_service/docker-compose.auth-restore.yml: 값이 적용되지 않은 demo/template 파일
이제 백업은 호스트 bind mount에 직접 쓰지 않고, 컨테이너 내부 임시 경로에 export한 뒤 결과를 복사하는 방식으로 수행합니다. 따라서 서버별 파일 권한 차이 때문에 Permission denied가 발생하는 문제를 줄일 수 있습니다.
루트 docker-compose.auth-bak.yml은 keycloak-db와 keycloak을 함께 포함하고 있어서, 실행 시 DB를 띄운 뒤 Keycloak이 자동으로 realm export를 수행하고 종료합니다.
services:
keycloak-db:
image: postgres:16-alpine
volumes:
- keycloak_db_data:/var/lib/postgresql/data
keycloak:
command:
[
"export",
"--dir",
"/tmp/keycloak-export",
"--realm",
"Sandori",
"--users",
"different_files",
"--users-per-file",
"100"
]
restart: "no"
depends_on:
keycloak-db:
condition: service_healthysandol_user_service/docker-compose.auth-bak.yml은 다음처럼 placeholder 기반으로 남겨두고, 실제 운영에는 루트 docker-compose.auth-bak.yml에 필요한 값을 반영해서 사용합니다.
services:
keycloak-db:
image: postgres:16-alpine
keycloak:
command:
[
"export",
"--dir",
"/tmp/keycloak-export",
"--realm",
"YOUR_REALM_NAME",
"--users",
"different_files",
"--users-per-file",
"100"
]루트 docker-compose.auth-restore.yml은 keycloak-db와 keycloak을 함께 포함하고 있고, keycloak은 /tmp/keycloak-import를 대상으로 import를 수행하도록 구성합니다.
services:
keycloak-db:
image: postgres:16-alpine
keycloak:
command:
[
"import",
"--dir",
"/tmp/keycloak-import",
"--override",
"true"
]
depends_on:
keycloak-db:
condition: service_healthy오프라인 import 명령 자체의 일반 예시는 다음과 같습니다.
/opt/keycloak/bin/kc.sh import --dir /opt/keycloak/data/import이 README에서 설명하는 standalone 복원 compose 흐름은 위 일반 예시와 별개로, 컨테이너 내부 /tmp/keycloak-import 경로를 사용합니다.
루트 docker-compose.yml과 docker-compose.dev.yml의 Keycloak 서비스는 현재 다음 특징을 가집니다.
command: ["start"]keycloak_db_data:/var/lib/postgresql/data볼륨과 연결된keycloak-db사용./sandol_user_service/web/keycloak-theme:/opt/keycloak/themes:ro마운트 사용- 백업 전용
keycloak-db+ export command는docker-compose.auth-bak.yml에서만 추가됨 --import-realm옵션 없음
즉, docker-compose.yml로 이미 실행 중인 서버는 백업 디렉터리만 준비한다고 자동으로 realm 백업이 생성되지는 않습니다.
운영 중인 서버에서 realm 백업을 생성하려면 다음 순서로 작업합니다.
- 기존 운영 Keycloak과 같은 DB를 바라보도록 루트
.env값(KC_DB_USERNAME,KC_DB_PASSWORD등)을 확인합니다. - 백업 결과를 받을 루트
backup/keycloak-export/디렉터리를 준비합니다. - 운영 중인 Keycloak 및 keycloak-db 서비스를 먼저 중지합니다. 백업용 compose도 같은 DB 볼륨을 사용하기 때문입니다.
docker compose stop keycloak keycloak-db- 루트
docker-compose.auth-bak.yml을 단독으로 실행합니다.
docker compose -f docker-compose.auth-bak.yml up --abort-on-container-exit --exit-code-from keycloak이 명령을 실행하면 keycloak-db가 먼저 올라오고, 이어서 keycloak의 export command가 자동으로 실행된 뒤 결과가 컨테이너 내부의 /tmp/keycloak-export에 생성됩니다.
- export가 성공적으로 끝난 것을 확인한 뒤, 이전 백업 조각이 남지 않도록 대상 디렉터리를 비우고 결과를 호스트로 복사합니다.
mkdir -p backup/keycloak-export
rm -f backup/keycloak-export/*.json
docker compose -f docker-compose.auth-bak.yml cp keycloak:/tmp/keycloak-export/. ./backup/keycloak-export- 백업 컨테이너를 정리합니다.
docker compose -f docker-compose.auth-bak.yml down- 작업이 끝나면 운영용 compose로
keycloak-db와keycloak서비스를 다시 기동합니다.
docker compose up -d keycloak-db keycloak- 기동 후
/auth/health/live및 Keycloak 관리자 콘솔에서 서비스가 정상 복구되었는지 확인하고,backup/keycloak-export/아래에Sandori-realm.json,Sandori-users-0.json등이 생성되었는지 확인합니다.
백업 파일이 서버의 backup/keycloak-export/에 생성된 뒤에는, 필요에 따라 운영 서버 밖으로 복사해 별도 보관할 수 있습니다.
서버 안에서 먼저 압축 파일을 만들려면:
tar -czf keycloak-export-backup.tar.gz -C backup keycloak-export그 다음 로컬 PC에서 서버로부터 직접 내려받으려면:
scp root@<server-host>:~/tuk_sandol_team/keycloak-export-backup.tar.gz .압축 없이 디렉터리째 바로 내려받으려면:
scp -r root@<server-host>:~/tuk_sandol_team/backup/keycloak-export ./keycloak-export다운로드한 뒤에는 로컬 보관소나 다른 백업 스토리지로 옮기기 전에 파일 목록을 확인합니다.
ls -l ./keycloak-export복원은 백업과 반대로, 호스트의 JSON 파일을 먼저 복원 컨테이너 내부로 복사한 다음 kc.sh import를 실행하는 방식으로 수행합니다.
- 복원할 JSON 파일이 루트
backup/keycloak-export/아래에 있는지 확인합니다. - 운영 중인 Keycloak 및 keycloak-db 서비스를 먼저 중지합니다.
docker compose stop keycloak keycloak-db- 복원용 compose에서 DB만 먼저 실행합니다.
docker compose -f docker-compose.auth-restore.yml up -d keycloak-dbkeycloak-db가healthy상태가 되었는지 확인합니다.
docker compose -f docker-compose.auth-restore.yml psSTATUS에 healthy가 보일 때까지 기다린 뒤 다음 단계로 진행합니다.
- import 컨테이너를 생성만 해둡니다.
docker compose -f docker-compose.auth-restore.yml create keycloak- 복원할 JSON 파일을 컨테이너 내부
/tmp/keycloak-import로 복사합니다.
docker compose -f docker-compose.auth-restore.yml cp ./backup/keycloak-export/. keycloak:/tmp/keycloak-import- import 컨테이너를 실행합니다.
docker compose -f docker-compose.auth-restore.yml start keycloak
docker compose -f docker-compose.auth-restore.yml logs -f keycloak- import가 끝나면 복원 컨테이너를 정리합니다.
docker compose -f docker-compose.auth-restore.yml down- 운영용 compose로
keycloak-db와keycloak서비스를 다시 기동합니다.
docker compose up -d keycloak-db keycloak- 기동 후
/auth/health/live및 Keycloak 관리자 콘솔에서 realm/client/user 정보가 정상 복원되었는지 확인합니다.
정리하면, 루트 docker-compose.yml은 평상시 운영용 구성이고, 자동 백업은 루트 docker-compose.auth-bak.yml을 단독 실행해서 수행합니다.
- Keycloak 공식 문서 기준으로
export/import는 서버가 실행 중이 아닐 때 수행하는 것이 안전합니다. - 루트
docker-compose.auth-bak.yml은 standalone 백업 전용 compose 파일입니다. - 루트
docker-compose.auth-restore.yml은 standalone 복원 전용 compose 파일입니다. sandol_user_service/docker-compose.auth-bak.yml은 demo/template 파일이므로, 그대로 운영에 사용하지 말고 루트docker-compose.auth-bak.yml에 필요한 값을 반영할 때 참고용으로만 사용합니다.sandol_user_service/docker-compose.auth-restore.yml도 demo/template 파일이므로, 그대로 운영에 사용하지 말고 루트docker-compose.auth-restore.yml에 필요한 값을 반영할 때 참고용으로만 사용합니다.- 루트
docker-compose.auth-bak.yml은 export 전용 command를 사용하므로, 이 파일을 실행하면 Keycloak 서버가 평소처럼 계속 떠 있는 것이 아니라 백업 수행 후 종료됩니다. - 루트
docker-compose.auth-restore.yml은 import 전용 command를 사용하므로, 복원할 JSON 파일을 먼저docker compose cp로 컨테이너 내부/tmp/keycloak-import에 넣어야 합니다. - 루트
docker-compose.auth-bak.yml은 운영용keycloak-db와 같은 DB 볼륨(keycloak_db_data)을 사용하므로, 메인keycloak-db가 살아 있는 상태에서 동시에 실행하면 안 됩니다. - 루트
docker-compose.auth-restore.yml도 같은 DB 볼륨(keycloak_db_data)을 사용하므로, 메인keycloak-db가 살아 있는 상태에서 동시에 실행하면 안 됩니다. - 루트
.env의COMPOSE_PROJECT_NAME이 운영 compose와 동일해야 같은keycloak_db_data볼륨을 바라봅니다. 다른 프로젝트 이름으로 실행하면 운영 데이터가 아닌 다른 볼륨을 보게 될 수 있습니다. - 백업 결과는 bind mount가 아니라 컨테이너 내부
/tmp/keycloak-export에 먼저 만들어지고, 이후docker compose cp로 호스트backup/keycloak-export/에 복사합니다. docker compose -f docker-compose.auth-bak.yml up ...가 실패하면docker compose cp는 실행하지 말고, 먼저 로그와 종료 코드를 확인해야 합니다.docker compose -f docker-compose.auth-restore.yml cp ...가 실패하면 import를 시작하지 말고, 컨테이너 생성 상태와 복사 대상 경로를 먼저 확인해야 합니다.- 현재 운영 Keycloak 실행 명령에는
--import-realm이 없으므로, 운영 compose를 다시 올린다고 자동 import는 실행되지 않습니다. 시작 시 자동 import가 필요하면 Keycloak 실행 명령에start --import-realm형태가 추가되어야 합니다. - 루트
docker-compose.yml과docker-compose.dev.yml만으로는 export 결과 복사 단계가 없으므로, 운영 중 서버에서 compose만 띄운다고 백업 파일이 자동 저장되지는 않습니다. sandol_user_service/base_data/Sandori-realm.json및Sandori-realm.noauthz.json은 서비스 내부 기준 데이터로 볼 수 있지만, 실제 백업/복원 작업 경로는 루트backup/keycloak-export/입니다.
- (CI/CD 적용 여부 및 배포 자동화 여부를 설명하세요.)
- 예시:
GitHub Actions 사용 여부,GCP Cloud Run 자동 배포,AWS Lambda 연동 여부등
- 예시:
- (배포 시 관리해야 할 환경 변수 및 보안 설정을 명시하세요.)
- 예시:
.env 파일의 API Key,Webhook URL,DB 접속 정보등
- 예시:
- (배포시 주의해야할 사항을 설명하세요.)
- 예시:
별도 domain 연결 필요,독립 Database 설정 필요등
- 예시:
- (디스코드 채널 링크를 삽입하세요)
🚀 산돌이 프로젝트와 함께 효율적인 개발 환경을 만들어갑시다!