콘텐츠로 이동
Study NoteKeycloak 실습

Compose 실습 환경 준비

결론부터
이 덱의 본선은 Keycloak·PostgreSQL·앱 A/B·API·Samba를 한 Compose project에서 실행하며, kind와 kubectl을 요구하지 않는다.

개념 설명에서 확인하는 로그인·SSO·권한 결과는 labs/keycloak/의 한 실습 환경에서 나온다. 브라우저와 container 모두 같은 issuer를 쓰고, 웹 HTTPS CA와 디렉터리 LDAPS CA는 분리한다.

이 장에서 처음 나오는 말3개
Compose project
여러 container·network·volume을 하나의 이름으로 묶어 수명 주기를 관리하는 단위. 이 실습 이름은 keycloak-lab이다.
issuer
토큰을 발급한 주체를 식별하는 URL. 검증자는 토큰의 iss가 기대한 값과 정확히 같은지 확인한다.
CACertificate Authority
TLS 인증서의 신뢰 뿌리. 이 실습은 웹 HTTPS와 디렉터리 LDAPS의 CA를 서로 바꿔 쓸 수 없게 나눈다.
경계실습 값이유
project·networkkeycloak-lab 전용 Compose project와 bridge다른 로컬 workload와 자원 수명을 섞지 않음
공개 issuerhttps://keycloak.keycloak.test:30080/realms/studyhost와 container가 같은 iss·discovery·JWKS 사용
공개 앱앱 A 30081, 앱 B 30082, 모두 loopback publish브라우저 진입점만 host에 노출
내부 서비스PostgreSQL·API·Samba는 host port 없음Compose bridge 밖 우회 접근을 만들지 않음
영속 데이터Samba·PostgreSQL named volumecontainer 재생성과 데이터 초기화를 구분

이 구성은 학습과 장애 관찰용 단일 인스턴스다. 운영 HA를 검증한 결과가 아니며, Samba도 Microsoft AD DS가 아니라 AD 호환 디렉터리 대역이다.

  • 어느 runtime과 자원이 필요한가?
  • 시작한 환경을 브라우저에서 어떻게 확인하는가?
  • 보존 중단·재개와 처음부터 다시 시작하기는 어떻게 다른가?
  • 어떤 결과가 실제로 검증됐고 무엇이 아직 보류인가?

runtime·Compose plugin·buildx plugin 준비와 확인 명령은 Docker Compose 실습 환경을 따른다. 이 실습이 추가로 요구하는 것은 자원 계약과 검증 범위다.

Colima + Docker CLI가 기본 경로다. 이 저장소에서 검증한 profile은 4 logical CPU, 8 GiB RAM이며 시작 직전 가용 memory 5 GiB와 Docker data disk 20 GiB 이상을 확인했다. 로컬 image build가 BuildKit secret을 쓰므로 buildx plugin이 연결돼 있어야 한다.

터미널 창
colima status
docker buildx version
docker compose version

이미지와 package는 labs/keycloak/decisions.md의 digest·snapshot·lockfile로 고정돼 있다. 최초 준비/build에는 registry와 package 저장소 접근이 필요하지만, 준비 뒤 진단은 --pull never와 Compose 내부 endpoint를 사용한다. latest로 바꾸면 이 덱의 검증 기준에서 벗어난다.

  1. 저장소의 실습 디렉터리로 이동한다.

    터미널 창
    cd labs/keycloak
  2. 빈 실습 상태에서 CA·secret과 기반 세 service만 준비한다. Client·API·Federation은 아직 만들지 않는다.

    터미널 창
    ./scripts/first-start.sh --guided
  3. mode=guided stage=base, 기반 세 service와 뒤 단계의 not-started 표시를 확인한다.

    터미널 창
    ./scripts/status.sh

다음은 실습 코드에서 읽을 것과 Client를 연결하고 로그인 확인하기로 이어 간다. 기존 완성 환경이 있다면 초기화하지 않고 resume.sh 뒤 verify.sh로 결과를 복습한다. Client 부재 같은 중간 상태는 fresh guided에서만 보인다.

실습 전체는 시작 한 번, 단계마다 적용과 검사 한 쌍, 필요할 때 중단·재개, 처음부터는 초기화로 이뤄진다. 학습자는 scripts/의 공개 진입점만 호출하고, 각 단계에서 읽고 바꾸는 것은 keycloak/의 공개 JSON이다.

first-start로 base를 만든 뒤 단계마다 apply와 verify를 반복하고 stop·resume·reset으로 수명을 관리하는 흐름

status.sh의 첫 줄 mode=… stage=…는 .state/lifecycle/의 두 파일을 읽는다.

값뜻
mode=guided--guided로 시작해 기반만 만들고 나머지 단계를 학습자가 하나씩 올리는 경로
mode=ready인자 없는 시작이나 기존 환경처럼 모든 단계가 이미 적용된 완성 상태
stage지금까지 적용 완료된 단계. base → app-a → app-b → api → ldap → groups 순서로만 올라간다

두 파일이 없으면 ready와 groups로 읽는다. 그래서 guided 기능 이전에 만든 환경이나 완성 환경에서 --guided를 붙여 다시 시작해도 mode=ready stage=groups가 나온다. first-start.sh는 기존 volume이나 container가 있으면 초기화하지 않고 resume.sh를 안내하며 끝나므로, guided를 처음부터 보려면 처음부터 다시 시작하기의 reset.sh를 먼저 거쳐야 한다.

스크립트가 하는 일과 하지 않는 일

섹션 제목: “스크립트가 하는 일과 하지 않는 일”
스크립트인자하는 일하지 않는 일
first-start.sh--guided 또는 없음빈 상태에서 CA·secret을 만들고 기반 세 service를 띄운다. --guided는 base에서 멈추고, 인자 없음은 groups까지 모두 적용한다기존 volume·container가 있으면 초기화하지 않고 중단한다
status.sh[service]mode·stage와 현재 stage에 기대되는 service의 health를 보여 준다로그인 검사나 설정 확인은 하지 않는다
apply.shapp-a app-b api ldap groups해당 단계의 공개 JSON을 Admin REST로 적용하고, 필요한 service를 시작한 뒤 stage를 올린다앞 단계를 몰래 적용하지 않는다. 순서를 건너뛰면 exit 1
verify.shapp-a sso api ldap groups새 cookie jar로 실제 Code+PKCE 로그인을 수행해 token·session·API 결과를 검사한다설정을 만들거나 복구하지 않는다. 현재 stage보다 뒤 검사는 exit 1
stop.sh없음project의 container와 network만 내린다volume·CA·secret·mode·stage는 남긴다
resume.sh없음기록된 stage에 필요한 service만 다시 띄운다seed를 다시 적용하지 않는다
service.shstart|status <service>service 하나만 다시 시작하거나 상태를 본다stage보다 앞선 service는 필요한 apply 단계를 안내하고 실패한다
reset.sh--dry-run 또는 --confirm <문구>이 project의 volume·container·network와 .state를 지워 빈 상태로 되돌린다다른 Docker project·image·build cache는 건드리지 않는다

apply의 단계 이름과 verify의 검사 이름이 다른 곳은 app-b다. apply.sh app-b 뒤에는 두 앱의 세션 공유를 보는 verify.sh sso를 실행한다. 단계별 명령과 예상 출력의 정본은 labs/keycloak/README.md의 “guided 학습 순서” 절이다.

비밀번호·private key·token은 Git 제외 labs/keycloak/.state/에서 생성된다. 값을 환경 변수나 문서에 복사하지 않는다. 세부 명령과 예상 출력의 정본은 labs/keycloak/README.md, 실제 검증 기록은 labs/keycloak/verification.md다.

status.sh는 container가 healthy인지만 보고, verify.sh <단계>는 지나온 단계의 실제 로그인을 자동으로 수행한다. 같은 결과를 화면에서 직접 보려면 host에서 한 번만 로컬 HTTPS 실습을 브라우저로 보기의 세 준비를 이 실습 값으로 한다.

준비이 실습의 값
hosts 항목127.0.0.1 keycloak.keycloak.test app-a.keycloak.test app-b.keycloak.test
브라우저 프록시 예외*.keycloak.test (터미널 curl은 NO_PROXY에 .keycloak.test)
로컬 CA 등록 (선택)파일 labs/keycloak/.state/web-ca/ca.crt, nickname keycloak-lab-web-ca

CA를 등록하지 않아도 host별로 한 번씩 인증서 경고를 넘기면 모든 실습이 동작한다. 등록·삭제 명령은 위 장의 운영체제 탭에 있으며, 이 CA는 web HTTPS 전용이고 Samba LDAPS CA는 브라우저에 등록하지 않는다.

화면주소계정열리는 단계
Admin Consolehttps://keycloak.keycloak.test:30080/admin/lab-adminbase부터
Account Consolehttps://keycloak.keycloak.test:30080/realms/study/account/local-user, ldap부터 alice·bobbase부터
앱 Ahttps://app-a.keycloak.test:30081/위 사용자app-a부터
앱 Bhttps://app-b.keycloak.test:30082/위 사용자app-b부터

비밀번호는 first-start.sh가 만든 labs/keycloak/.state/secrets/의 파일에 있으며 로컬 터미널에서만 확인한다. Admin Console의 lab-admin은 keycloak-bootstrap-admin-password, local-user는 keycloak-local-user-password, alice·bob은 samba-alice-password·samba-bob-password다.

터미널 창
cat .state/secrets/keycloak-bootstrap-admin-password # labs/keycloak에서

Admin Console은 왼쪽 위 realm 선택을 study로 바꿔서 본다. base 직후에는 Users에 local-user만 있고 Client가 없다. 단계를 마칠 때마다 Client·Role·User federation·Mapper가 어디에 새로 보이는지는 labs/keycloak/README.md의 브라우저 절 표에 정리돼 있다.

Samba AD DC에는 웹 콘솔이 없고, 이 실습은 Samba port를 host에 publish하지 않는다. 원본 계정과 그룹은 container 안에서 조회하고, Keycloak이 가져온 결과는 ldap·groups 단계 뒤 Admin Console에서 본다.

터미널 창
docker exec keycloak-lab-samba samba-tool user list
docker exec keycloak-lab-samba samba-tool group listmembers app-users
터미널 창
./scripts/stop.sh
./scripts/resume.sh

stop.sh는 정확한 Compose project의 container와 network만 내리고 두 named volume과 .state를 남긴다. resume.sh 뒤에는 realm·사용자·디렉터리 SID가 그대로여야 한다.

빈 상태에서 다시 재현하려면 reset.sh로 Compose 데이터와 .state를 함께 지운다. 이 명령은 삭제 대상을 먼저 보여 주고 고정 확인 문자열을 요구한다.

  1. 삭제 대상을 본다. 이 명령은 아무것도 지우지 않는다.

    터미널 창
    ./scripts/reset.sh --dry-run
  2. 목록을 확인했으면 초기화한다.

    터미널 창
    ./scripts/reset.sh --confirm DELETE-keycloak-lab-compose-state
  3. 다시 시작한다. reset이 proxy CA 복사본도 지우므로 프록시 환경에서는 CORP_CA_FILE을 다시 지정한다.

    터미널 창
    export CORP_CA_FILE=/path/to/corporate-proxy-ca.crt # 프록시 환경에서만
    ./scripts/first-start.sh --guided
    ./scripts/status.sh
  4. web CA를 브라우저에 등록했었다면 옛 keycloak-lab-web-ca를 등록한 CA 지우기대로 지운 뒤 새 .state/web-ca/ca.crt를 다시 등록한다. 등록하지 않았다면 건너뛴다.

reset은 정확히 나열한 Compose의 PostgreSQL·Samba 데이터와 로컬 CA·secret·검증 산출물만 삭제한다. 다른 Docker project·전역 prune·Colima 초기화는 건드리지 않으며, image와 build cache도 남긴다.

2026-09-14 macOS 26.6.2 arm64와 Colima 0.10.3에서 빈 상태 최초 시작, 로컬 사용자 SSO/API, Samba 사용자 로그인·그룹 매핑, 보존 중단·재개를 kind·kubectl 없이 재현했다. curl과 진단 client는 web CA를 명시해 검증했다.

후속 검증에서는 현재 web CA를 macOS login keychain의 신뢰 root로 승인하고 실제 Chrome에서 Admin Console·Account Console과 앱 A Authorization Code + PKCE 로그인까지 확인했다. 네이티브 Ubuntu의 Samba P03과 전체 P11, Ubuntu 브라우저의 NSS DB 등록은 미실행이다. Ubuntu에서는 프록시 예외 추가 뒤 Admin Console 접속까지 확인했다. macOS 결과와 Ubuntu에서 성공했다는 기록을 구분한다.

  • 본선 환경은 하나의 keycloak-lab Compose project이며 kind·kubectl이 필요 없다.
  • host와 container는 같은 issuer를 쓰고, 내부 DB·API·Samba는 host에 publish하지 않는다.
  • runtime·plugin 준비와 브라우저의 hosts·프록시 예외·CA 등록은 실습 환경 덱을 따르고, 이 실습은 값만 지정한다. Samba는 웹 콘솔 없이 samba-tool로 본다.
  • 일반 중단은 현재 stage의 데이터를 보존한다. 처음부터 다시 시작할 때는 .state만 지우지 말고 reset.sh를 쓴다.
  • macOS 비브라우저 재현과 대표 Chrome 로그인을 통과했지만 네이티브 Ubuntu 검증은 보류다.