본문으로 건너뛰기

Docker: 테스트, 개발, 배포

반복 가능한 테스트, Go 없이 진행하는 프런트엔드 개발, 프로덕션 배포, CI에서의 자동화된 skill 검증에 Docker를 사용하세요.

모드 선택 다이어그램

명령어 매핑:

명령misemake
테스트 (오프라인)mise run test:dockermake test-docker
테스트 (온라인)mise run test:docker:onlinemake test-docker-online
Playground (시작 + 쉘)mise run playgroundmake playground
Playground (중지)mise run playground:downmake playground-down
Sandbox (고급)./scripts/sandbox.sh <up|down|shell|reset|status|logs|bare>
Devcontainer (시작 + 쉘)mise run devcmake devc
Devcontainer (시작만)mise run devc:upmake devc-up
Devcontainer (중지)mise run devc:downmake devc-down
Devcontainer (재시작)mise run devc:restartmake devc-restart
Devcontainer (완전 초기화)mise run devc:resetmake devc-reset
Devcontainer (상태)mise run devc:statusmake devc-status
Dev API 서버mise run dev:dockermake dev-docker
Dev 중지mise run dev:docker:downmake dev-docker-down
Docker 빌드mise run docker:buildmake docker-build
Docker 멀티아치mise run docker:build:multiarchmake docker-build-multiarch

무엇에 사용할 수 있나요

모드적합한 용도네트워크라이프사이클
오프라인 테스트 샌드박스안정적인 회귀 검사 (build + unit + integration)비활성화일회성
온라인 테스트 샌드박스선택적인 원격 install/update 검사활성화일회성
인터랙티브 playground수동 명령어 탐색 및 데모활성화지속형
Dev profileDocker 내 Go API 서버 + 호스트의 Vite HMR활성화지속형
DevcontainerVS Code / Codespaces 원클릭 개발 환경활성화지속형
Production 이미지경량 배포 (docker/production/)활성화지속형
CI 이미지파이프라인에서의 skill 검증 (docker/ci/)활성화일회성

일반적인 시나리오

1. 로컬 install/update 로직을 결정적으로 검증하기

install / update 동작을 변경하면서 CI와 유사한 로컬 게이트를 원할 때 사용하세요.

mise run test:docker
make test-docker

이는 local-path 및 file:// 워크플로를 격리된 환경에서 검증합니다.

2. 선택적인 원격 소스 검사 실행

네트워크 접근이 필요한 GitHub/원격 소스 검증에 사용하세요.

make test-docker-online

3. 전용 playground를 열고 모든 명령어 탐색하기

시작하고 진입하는 명령어 하나:

make playground
mise run playground

playground 내부에서는 skillsharess를 바로 사용할 수 있습니다. Global mode와 Project mode 모두 사전 초기화되어 있습니다.

skillshare --help
ss status
skillshare list

Playground의 Project Mode

playground는 샘플 skill과 claude target이 포함된 데모 프로젝트를 ~/demo-project에 자동으로 설정합니다. 바로 project mode를 탐색할 수 있습니다.

cd ~/demo-project
skillshare status # project mode를 자동 감지
skillshare list
skillshare sync --dry-run

웹 대시보드를 실행하려면 내장 alias를 사용하세요.

skillshare-ui            # global mode 대시보드 → http://localhost:19420
skillshare-ui-p # project mode 대시보드 (~/demo-project) → http://localhost:19420

그런 다음 호스트 머신에서 http://localhost:19420을 여세요 (포트는 Docker Compose를 통해 매핑됩니다).

GitHub Token (Search용)

playground는 skillshare search를 위해 호스트에서 GitHub token을 자동으로 가져옵니다. 순서대로 확인합니다: $GITHUB_TOKEN$GH_TOKENgh auth token. 이미 호스트에서 인증되어 있다면 추가 설정이 필요 없습니다.

# 감지되지 않으면 playground를 시작하기 전에 설정하세요:
export GITHUB_TOKEN=ghp_your_token_here
make playground

완료되면:

make playground-down

역할별 사용 사례

개인 개발자

시나리오사용할 것대체하는 것
Go/Node를 설치하지 않고 skillshare 사용해 보기docker run ghcr.io/runkids/skillshareGo + Node + pnpm 설치 후 소스에서 빌드
PR을 열기 전에 전체 테스트 스위트 실행make test-docker로컬 툴체인 의존 (Go 버전 불일치 = 결과 불안정)
Go를 설치하지 않고 프런트엔드 작업make dev-docker + cd ui && pnpm run devAPI 서버 실행을 위해 로컬에 Go 1.25+ 설치 필요
동료에게 skillshare 데모 보여주기make playground:19420에서 Web UI전체 로컬 설치 과정을 안내
Apple Silicon에서 Linux 동작 검증make docker-buildCI에 푸시하고 대기

팀과 오픈소스 기여자

시나리오사용할 것해결하는 것
신규 기여자 온보딩make playground — 명령어 하나로 준비 완료"Go 설치, PATH 설정, clone, build" 안내서가 더 이상 필요 없음
CI에서 자동화된 skill 품질 게이트docker run ghcr.io/.../skillshare-ci audit /skills이전에는 모든 워크플로에서 Go 설치 및 소스 빌드가 필요했음
기여자마다 "내 컴퓨터에서는 되는데" 문제Docker가 Go 1.25.5 + 모든 의존성을 고정서로 다른 로컬 Go 버전으로 인한 테스트 불안정
이슈를 재현하는 PR 리뷰어./scripts/test_docker.sh --cmd "go test -run TestXxx ..."재현하려면 clone 및 전체 로컬 설정이 필요

엔터프라이즈 및 자체 호스팅 배포

시나리오사용할 것가치
내부 skill 관리 대시보드Production 이미지 + skill용 volume mount컨테이너 하나, 서버에 Go/Node 불필요
Kubernetes 배포Production 이미지 (healthcheck + graceful shutdown + non-root)readiness/liveness probe 준비 완료, PodSecurityPolicy 통과
자동화된 skill PR 리뷰GitHub Actions에서 CI 이미지 + skillshare audit안전하지 않은 skill의 병합 차단 — 워크플로에 한 줄만 추가
컨테이너 보안 준수read_only + cap_drop: ALL + no-new-privilegesCIS Docker Benchmark, Trivy, Aqua 스캔 통과
비용 절감을 위한 ARM 서버 (AWS Graviton)make docker-build-multiarch에뮬레이션 오버헤드 없는 네이티브 arm64 이미지

빠른 예시

skill을 영구 보존하는 자체 호스팅 대시보드:

docker run -d \
-p 19420:19420 \
-v skillshare-data:/home/skillshare/.config/skillshare \
ghcr.io/runkids/skillshare

GitHub Actions에서의 CI skill 감사:

- name: Audit skills
run: |
docker run --rm \
-v ${{ github.workspace }}/skills:/skills \
ghcr.io/runkids/skillshare-ci audit /skills

Kubernetes 배포 (최소):

apiVersion: apps/v1
kind: Deployment
metadata:
name: skillshare
spec:
replicas: 1
template:
spec:
containers:
- name: skillshare
image: ghcr.io/runkids/skillshare:latest
ports:
- containerPort: 19420
livenessProbe:
httpGet:
path: /api/health
port: 19420
readinessProbe:
httpGet:
path: /api/health
port: 19420
securityContext:
runAsNonRoot: true
readOnlyRootFilesystem: true

Dev Profile

Vite HMR로 프런트엔드를 개발하는 두 가지 방법:

Go가 로컬에 설치된 경우 (명령어 하나):

make ui-dev              # Go API 서버 + Vite dev 서버를 함께 시작
# http://localhost:5173 열기

Go 없이 (Go API는 Docker에서 실행되며, Go 변경 시 자동으로 재빌드됨):

# 터미널 1
make dev-docker # Docker의 Go API + Compose Watch (localhost:19420)

# 터미널 2
cd ui && pnpm run dev # Vite dev 서버 (localhost:5173, /api를 :19420으로 프록시)

# 완료되면
make dev-docker-down

두 방법 모두 ui/ 변경 사항에 대해 즉각적인 HMR을 제공합니다. Docker 방식은 Go 툴체인을 고정하므로 기여자 간에 백엔드 동작이 일관됩니다. Go 파일을 편집하면 Compose Watch가 변경을 감지해 컨테이너를 재빌드하고 API 서버를 자동으로 재시작합니다. Docker Compose v2.22+가 필요합니다.

참고: make ui-dev를 사용할 때 Go 코드 변경은 서버 재시작이 필요합니다 (Ctrl+C 후 재실행). make dev-docker는 Compose Watch를 통해 이를 자동으로 처리합니다.


Devcontainer (VS Code / Codespaces / CLI)

로컬에 Go, Node, pnpm이 필요 없는, 바로 코딩 가능한 컨테이너에서 프로젝트를 여세요. VS Code가 있어도 없어도 작동합니다.

Devcontainer vs Playground

둘 다 동일한 기본 이미지와 데모 콘텐츠를 사용합니다. playground (make playground)는 명령어를 탐색하기 위한 터미널 전용 환경입니다. devcontainer는 skillshare 코드베이스 자체를 개발하기 위한 개발 도구(Go, Node, pnpm, air)를 추가한 것으로, VS Code, Codespaces, 또는 일반 터미널에서 사용할 수 있습니다.

사전 준비 사항

  • Docker Desktop 실행 중
  • 옵션 A (터미널): 추가 도구 불필요 — make devc가 모든 것을 처리
  • 옵션 B (VS Code): Dev Containers 확장이 설치된 VS Code
GitHub Codespaces

GitHub에서 Code → Codespaces → New codespace를 클릭하세요. devcontainer 설정이 자동으로 적용됩니다 — 로컬 Docker나 확장이 필요 없습니다.

시작하기

터미널에서 (VS Code 불필요):

make devc            # 이미지 빌드 → 컨테이너 시작 → 설정 → 쉘 진입

첫 실행은 몇 분 걸립니다 (이미지 빌드, 의존성 설치). 이후 실행은 기존 설정을 감지해 바로 쉘로 이동합니다.

기타 라이프사이클 명령어:

make devc-up         # 시작만 (쉘 없음)
make devc-down # 컨테이너 중지
make devc-restart # 재시작 + start-dev.sh 재실행
make devc-reset # 완전 초기화 (volume 제거), 이후 make devc로 재초기화
make devc-status # 컨테이너 상태 표시

VS Code에서:

  1. VS Code에서 프로젝트 폴더 열기
  2. Ctrl+Shift+P (macOS에서는 Cmd+Shift+P)를 누르고 Dev Containers: Reopen in Container 선택
  3. 컨테이너 빌드를 기다리세요 (처음에는 몇 분, 이후에는 빠름)
  4. 준비되면 설정 스크립트가 바이너리를 빌드하고 데모 skill을 자동으로 생성합니다

포함된 것

devcontainer는 sandbox와 동일한 docker/sandbox/Dockerfile을 재사용하므로 다음을 제공합니다.

  • Go 1.25 툴체인
  • Node.js 24 + pnpm (Docker 이미지에 번들됨) — 컨테이너 내부에서 make ui-devcd website && pnpm start를 사용할 수 있음
  • VS Code 확장: Go, Tailwind CSS, ESLint, Prettier
  • 포트 포워딩: 45173 (Vite HMR), 49420 (Go API), 48888 (Docusaurus) — 호스트의 다른 프로젝트와 충돌하지 않도록 의도적으로 흔치 않은 값을 사용
  • /workspace에 마운트된 소스 코드
  • 사전 구성된 데모 환경 — 인터랙티브 playground와 동일:
    • PATH에 등록된 단축 명령어 (ss, ui, docs)
    • 미리 설치된 프런트엔드 의존성 (ui/website/)
    • 전역 데모 skill (audit 예시, 배포 체크리스트)
    • 커스텀 audit 규칙 (global + project)
    • project-mode skill이 포함된 ~/demo-project 데모 프로젝트

컨테이너가 열린 후 빠른 시작

ss status                 # global mode — 이미 초기화됨
ss list # 데모 skill 확인 (flat + nested)
ss audit # 커스텀 규칙으로 audit 실행

cd ~/demo-project
ss status # project mode를 자동 감지
ss audit # project 수준 audit
ui -p # API를 project mode로 전환 → http://localhost:45173

프런트엔드 개발

포트서비스명령어
45173Vite (React UI + HMR)ui 또는 ui -p
49420Go API 백엔드ui / ui -p로 시작됨
48888Docusaurusdocs
ui                        # global mode: API + Vite → http://localhost:45173
ui -p # project mode: API + Vite → http://localhost:45173
ui stop # API + Vite 중지
docs # 문서 사이트 → http://localhost:48888
docs stop # Docusaurus 중지

ui는 Go API 백엔드(포트 49420, 백그라운드)와 Vite dev 서버(포트 45173, HMR)를 모두 시작합니다. uiui -p 사이를 전환하면 새 모드로 API가 자동으로 재시작됩니다. VS Code는 포트를 호스트 브라우저로 자동 포워딩합니다.

Token 구성

private repo 접근용 token (GITHUB_TOKEN, GITLAB_TOKEN 등)은 여러 소스에서 올 수 있습니다. 다음 순서로 확인됩니다.

우선순위소스설정 방법
1.devcontainer/.env.env.example.env로 복사, 값 채우기 (gitignore 처리됨)
2호스트 환경 변수~/.zshrc에 설정 — devcontainer.jsonremoteEnv를 통해 전달됨
3gh auth login컨테이너 시작 시 GITHUB_TOKEN 자동 감지 (GitHub 전용)

모든 소스는 선택 사항입니다. 컨테이너 내부에서 언제든 export를 수동으로 사용할 수도 있습니다.

현재 상태 확인:

credential-helper status

Private repo 테스트

VS Code Dev Containers는 호스트의 git credential을 컨테이너로 자동으로 전달합니다. 즉, 명시적인 token 환경 변수가 없어도 private repo의 git clone이 성공할 수 있습니다 — 전달된 credential helper가 인증을 조용히 처리합니다.

테스트를 위해 모든 인증(credential helper + token 환경 변수)을 비활성화하려면:

eval "$(credential-helper --eval off)"    # 모두 비활성화
eval "$(credential-helper --eval on)" # 모두 복원
credential-helper status # 현재 상태 확인

--eval 없이는 git credential helper만 토글됩니다 (token 환경 변수는 계속 활성 상태).

테스트 실행

make test          # unit + integration
make test-unit # unit만
make lint # go vet

Production 및 CI 이미지

이미지 비교

세 가지 Dockerfile은 서로 다른 목적을 가집니다.

ProductionCISandbox
이미지ghcr.io/runkids/skillshareghcr.io/runkids/skillshare-ci로컬 빌드 전용
Dockerfiledocker/production/Dockerfiledocker/ci/Dockerfiledocker/sandbox/Dockerfile
베이스debian:bookworm-slimdebian:bookworm-slimgolang:1.25.5-bookworm
포함 내용git, curl, tinigit만Go 툴체인, gh, jq, air, delve, 미리 빌드된 UI
Non-root예 (UID 10001)아니오아니오
PID 1tini기본값기본값
Healthcheck예 (/api/health)아니오아니오
Entrypointskillshare ui (Web 대시보드)skillshare (직접 CLI)entrypoint.sh (테스트 러너)
사용 사례자체 호스팅 대시보드, KubernetesCI/CD skill 검증개발, 테스트, playground
GHCR에 게시됨아니오
멀티아키텍처amd64 + arm64amd64 + arm64호스트 아키텍처만

언제 무엇을 사용할지:

  • Production — 서버나 Kubernetes 클러스터에 Web UI 대시보드 배포
  • CI — GitHub Actions / GitLab CI에서 audit, install --dry-run 등의 검증 명령어 실행
  • Sandbox — 로컬 개발 (make test-docker, make playground, make dev-docker)

Production 이미지

내장된 Web UI가 포함된 경량 production 이미지를 빌드합니다.

make docker-build                          # 현재 플랫폼만 (빠름, 로컬 테스트용)
make docker-build-multiarch # linux/amd64 + linux/arm64 (느림, 레지스트리 푸시용)

docker-build는 사용 중인 머신 아키텍처의 이미지만 생성합니다 — Apple Silicon에서 만든 arm64 이미지는 x86 서버에서 실행되지 않습니다. 레지스트리에 푸시할 때는 모든 플랫폼이 올바른 이미지를 자동으로 받도록 docker-build-multiarch를 사용하세요.

production 이미지는 PID 1로 tini를 사용하고, non-root 사용자(UID 10001)로 실행되며, healthcheck를 포함하고, 첫 실행 시 config를 자동 초기화합니다. 기본 명령어: skillshare ui -g --host 0.0.0.0 --no-open.

게시된 이미지는 GHCR에서 확인할 수 있습니다 (태그 시 자동으로 푸시됨).

# Pull 및 실행 (amd64 또는 arm64 자동 선택)
docker run -d -p 19420:19420 ghcr.io/runkids/skillshare

# 영구 skill 데이터와 함께
docker run -d -p 19420:19420 \
-v skillshare-data:/home/skillshare/.config/skillshare \
ghcr.io/runkids/skillshare

CI 이미지

CI 파이프라인에서 skill을 검증하기 위한 최소 이미지입니다.

docker build -f docker/ci/Dockerfile -t skillshare-ci .
docker run --rm -v ./my-skills:/skills skillshare-ci audit /skills

CI 이미지의 entrypoint는 skillshare 자체이므로, 하위 명령어를 직접 전달합니다.

# threshold를 지정한 audit
docker run --rm -v ./skills:/skills ghcr.io/runkids/skillshare-ci audit /skills --threshold HIGH

# repo 검증을 위한 dry-run install
docker run --rm ghcr.io/runkids/skillshare-ci install org/repo --dry-run

Sandbox 이미지

sandbox 이미지는 로컬 개발 및 테스트 전용입니다 (GHCR에는 게시되지 않음). 전체 Go 툴체인, 개발 도구(air, delve), GitHub CLI, 미리 빌드된 프런트엔드 자산을 포함합니다.

사용처: make test-docker, make test-docker-online, make playground, make dev-docker.

사용법은 위의 PlaygroundDev Profile 섹션을 참고하세요.

이미지 태그와 버전 관리

태그 푸시(v*) 시, docker-publish GitHub Actions 워크플로가 production과 CI 이미지를 멀티아키텍처로 빌드해 GHCR에 푸시합니다.

각 이미지는 세 가지 패턴으로 태그됩니다.

태그 패턴예시설명
v<major>.<minor>.<patch>v0.16.1정확한 버전 (불변)
<major>.<minor>0.16이 minor 버전의 최신 patch (rolling)
sha-<short>sha-153464aGit commit SHA (불변)

재현성을 위해 production에서는 정확한 버전 태그(v0.16.1)를 사용하세요. patch 업데이트를 자동으로 받으려면 minor 태그(0.16)를 사용하세요. 특정 커밋에 고정하려면 sha- 태그를 사용하세요.

게시된 버전은 GitHub Packages에서 확인할 수 있습니다.


제한 사항 및 유의점

  • Playground와 dev profile은 포트 19420을 공유합니다 — 한 번에 하나만 실행하세요. 다른 쪽을 먼저 중지하세요 (make playground-down 또는 make dev-docker-down).
  • 오프라인 sandbox는 네트워크 의존 기능을 검증할 수 없습니다 (예: GitHub에서의 원격 install).
  • Playground는 컨테이너 로컬 HOME을 사용하므로 실제 호스트의 home config를 직접 수정하지 않습니다.
  • Go 코드 변경은 자동으로 반영됩니다 (마운트된 소스에서 컨테이너 내부의 go build가 실행됨). 프런트엔드(ui/) 변경은 devcontainer 내부에서 make ui-dev(Vite HMR)를 실행할 때 즉시 반영됩니다. devcontainer와 playground 모두 Node.js와 pnpm을 포함합니다.
  • 커스텀 실험이 필요하면 명령어를 직접 전달하세요.
./scripts/test_docker.sh --cmd "go test -v ./tests/integration/..."
./scripts/sandbox_playground_shell.sh "skillshare list"

참고