Agent skill
deploying-server
MiniPC 서버 배포, 컨테이너 관리, NixOS 설정, 도메인/SSL, 트러블슈팅 등 서버 인프라 관련 작업이면 반드시 이 스킬을 먼저 확인할 것. Triggers: "서버 배포", "컨테이너 재시작", "MiniPC", "anki.greenhead.dev", "nixos-rebuild", "Podman", "Docker", "서버 로그", "서버 에러", "Caddy", "리버스 프록시", "SSL 인증서", "배포", "deploy", "서버 접속", "Tailscale SSH", "서버 상태", "health check 실패", "컨테이너 로그", "이미지 업데이트", "서버 설정 변경", "agenix 시크릿", "AnkiConnect 서버", "headless Anki". Covers: MiniPC NixOS hosting, Podman container, Caddy reverse proxy, Tailscale networking, agenix secrets, systemd service order, and server troubleshooting.
Install this agent skill to your Project
npx add-skill https://github.com/greenheadHQ/awesome-anki/tree/main/.claude/skills/deploying-server
SKILL.md
서버 배포 및 운영
인프라 개요
사용자 (Tailscale VPN)
↓ HTTPS
anki.greenhead.dev (Caddy, :443)
↓ reverse_proxy
awesome-anki 컨테이너 (Podman, :3100)
↓ host network
AnkiConnect (headless Anki, :8765)
↓ 5분 주기 sync
Anki Sync Server (:27701)
MiniPC 접속
- 호스트명: greenhead-minipc
- Tailscale IP: 100.79.80.95
- SSH:
ssh greenhead@100.79.80.95(키 인증만 허용, 비밀번호 불가) - NixOS 설정:
~/Workspace/nixos-config(GitHub:greenheadHQ/nixos-config)
컨테이너 구성
| 항목 | 값 |
|---|---|
| 이미지 | ghcr.io/greenheadhq/awesome-anki:latest |
| 런타임 | Podman (NixOS virtualisation.oci-containers) |
| 포트 | 3100 (--network=host) |
| 메모리 | 1GB |
| CPU | 1 core |
| 볼륨 | /var/lib/docker-data/awesome-anki/data → /app/data |
/var/lib/docker-data/awesome-anki/output → /app/output |
|
| UID/GID | 1001 (anki) |
--network=host를 사용하는 이유: AnkiConnect가 Tailscale IP(100.79.80.95:8765)에서만 리스닝하므로, 컨테이너가 호스트 네트워크 스택을 공유해야 접근 가능. Tailscale 방화벽 + WireGuard 암호화로 보안 보장.
환경변수
| 변수 | 소스 | 용도 |
|---|---|---|
GEMINI_API_KEY |
agenix (awesome-anki-gemini-key.age) |
Split/검증 LLM |
OPENAI_API_KEY |
agenix (awesome-anki-openai-key.age) |
임베딩 |
ANKI_CONNECT_URL |
하드코딩 http://100.79.80.95:8765 |
AnkiConnect 연결 |
PORT |
3100 |
서버 포트 |
ANKI_SPLITTER_REQUIRE_API_KEY |
false |
Tailscale 내부망이므로 비활성화 |
환경변수 파일은 awesome-anki-env systemd oneshot 서비스가 agenix 시크릿을 복호화하여 /run/awesome-anki-env에 생성.
리버스 프록시 (Caddy)
- 도메인:
anki.greenhead.dev - 바인드: Tailscale IP만 (
100.79.80.95:443) - SSL: Cloudflare DNS-01 ACME (Let's Encrypt 자동 갱신)
- 보안 헤더: HSTS, X-Content-Type-Options, X-Frame-Options
- NixOS 설정:
~/Workspace/nixos-config/modules/nixos/programs/caddy.nix
systemd 서비스 기동 순서
tailscaled → anki-sync-server → anki-connect
↓
caddy-env → caddy awesome-anki-env → podman-awesome-anki
핵심 의존성: awesome-anki-env (시크릿 복호화) 완료 후에만 컨테이너 시작.
CI/CD 파이프라인
mainpush 또는v*태그 push → GitHub Actions 트리거- Docker Buildx로 이미지 빌드 (GHA 캐시)
ghcr.io/greenheadhq/awesome-anki레지스트리에 push- MiniPC
awesome-anki-auto-update타이머 (5분 주기)가latestdigest 변경 감지 →systemctl restart로 교체
태그 전략
| 트리거 | 생성 태그 |
|---|---|
| main push | latest, sha-<hash> |
v1.2.3 tag |
1.2.3, 1.2, latest |
v1.2.3-alpha tag |
1.2.3-alpha (latest 없음) |
자동 배포 흐름
main push → GitHub Actions (~3분) → GHCR latest 갱신
→ MiniPC awesome-anki-auto-update (5분 주기) → digest 변경 감지
→ podman pull → systemctl restart (10-30초 다운타임)
실패 시 이전 이미지로 자동 롤백. Tailscale 내부망 전용이므로 짧은 다운타임 수용.
빠른 작업 명령어
컨테이너 관리
# 상태 확인
systemctl status podman-awesome-anki
# 로그 확인
podman logs awesome-anki
journalctl -u podman-awesome-anki -n 50
# 재시작
systemctl restart podman-awesome-anki
# 이미지 업데이트 (자동)
# 5분마다 자동 실행 — 수동 개입 불필요
systemctl status awesome-anki-auto-update.timer # 타이머 상태
journalctl -u awesome-anki-auto-update -n 10 # 업데이트 로그
# 이미지 업데이트 (수동 — 긴급 시)
podman pull ghcr.io/greenheadhq/awesome-anki:latest
systemctl restart podman-awesome-anki
AnkiConnect 관리
# 상태 확인
systemctl status anki-connect
curl http://100.79.80.95:8765
# 재시작
systemctl restart anki-connect
# 수동 동기화
systemctl start anki-connect-sync
NixOS 설정 변경
# MiniPC에서 직접
cd ~/Workspace/nixos-config
sudo nixos-rebuild switch --flake .#greenhead-minipc
# MacBook에서 원격
nixos-rebuild switch --flake .#greenhead-minipc --target-host greenhead@100.79.80.95
데이터 경로
| 데이터 | 호스트 경로 | 컨테이너 경로 |
|---|---|---|
| Split 히스토리 DB | /var/lib/docker-data/awesome-anki/data/split-history.db |
/app/data/split-history.db |
| 프롬프트 | /var/lib/docker-data/awesome-anki/output/prompts/ |
/app/output/prompts/ |
| 임베딩 캐시 | /var/lib/docker-data/awesome-anki/output/embeddings/ |
/app/output/embeddings/ |
| 백업 | /var/lib/docker-data/awesome-anki/output/backups/ |
/app/output/backups/ |
| Anki 컬렉션 | /var/lib/anki/.local/share/Anki2/server/ |
- |
| Anki Sync 백업 | /mnt/data/backups/anki/{YYYY-MM-DD}/ |
- |
Health Check
- 엔드포인트:
GET /api/health(인증 불필요) - 응답:
{ status: "ok", timestamp: "..." } - Docker: 30초 간격, 5초 타임아웃, 3회 재시도, 30초 시작 대기
- 확인:
curl https://anki.greenhead.dev/api/health
상세 참조
references/nixos-config.md— NixOS 모듈 구조, 설정 옵션, 서비스 의존성references/container-setup.md— Dockerfile, CI/CD, 볼륨, 이미지 관리references/troubleshooting.md— 컨테이너/AnkiConnect/Caddy/NixOS 문제 해결
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
validating-cards
USE THIS SKILL for card content validation — fact-checking, freshness, similarity, context consistency, or anything about duplicate detection and card quality. Triggers: "팩트 체크 결과가", "유사한 카드 찾아줘", "문맥 검증", "검증 캐시", "최신성 검사", "중복 카드", "검증 상태 아이콘", "validate/all", "Jaccard", "임베딩 유사도", "중복 판정", "useValidateCard", "useBatchValidate", "검증 4종", "일괄 검증", "context-checker", "fact-checker", "freshness-checker", "similarity-checker", "findSimilarGroups", "analyzeCardGroup", "검증 폴백". Covers the 4 validation types: fact-check, freshness, similarity, context.
developing-web-ui
React 프론트엔드의 컴포넌트, 훅, 렌더링, 스타일 관련 작업이면 반드시 이 스킬을 먼저 확인할 것. Triggers: "React 컴포넌트 추가", "ContentRenderer 수정", "TanStack Query", "CSS 충돌", "웹 UI 버그", "페이지 추가", "Tailwind 스타일", "렌더링 문제", "shadcn", "shadcn 컴포넌트", "shadcn 마이그레이션", "variant API", "UI 마이그레이션", "마이그레이션", "toast", "sonner", "Toaster", "DiffViewer", "ContentPreview", "BottomSheet", "CompactSelector", "markdown 렌더링", "모바일 반응형", "useMediaQuery", "useIsMobile", "훅 추가", "query hook", "캐시 무효화", "staleTime", "분할 미리보기 UI", "분할 반려 UI", "카드 브라우저", "어려운 카드". Covers the React frontend, components, hooks, query patterns, rendering pipeline, and UI troubleshooting.
managing-embeddings
USE THIS SKILL for anything related to embeddings, vector similarity, or semantic search. Triggers: "임베딩 생성", "코사인 유사도", "캐시 어디에", "임베딩 상태", "의미 유사도", "text-embedding-3-large", "openai embedding", "벡터 차원", "3072", "임베딩 캐시", "embedding 마이그레이션", "레거시 캐시", "embedding fallback", "유사도 검사 임베딩 모드", "임베딩 배치", "rate limit 429". Covers OpenAI embedding API, file-based cache with migration, and text preprocessing.
understanding-project
프로젝트 구조, 아키텍처, 기술 스택, 패키지 역할 등 전반적인 이해가 필요할 때 사용. 코드가 어디에 있는지, 패키지 간 의존성이 어떤지, 왜 이 구조인지 궁금하면 이 스킬. Triggers: "모노레포 구조가 어떻게 돼", "기술 스택", "export 충돌", "패키지 간 의존성", "프로젝트 구조", "어떤 패키지에 있어", "파일 어디에 있어", "아키텍처", "디렉터리 구조", "코드 위치", "모듈 역할", "어떤 기술 쓰고 있어", "스택", "의존성". Covers the monorepo architecture, package roles, tech stack, and coding conventions.
managing-llm
LLM 추상화 계층, 프로바이더 어댑터, 가격표, 예산 가드 등 LLM 관련 작업이면 무조건 이 스킬. 모델 변경, 프로바이더 추가, 비용 계산, 토큰 카운트 등 모든 LLM 인프라를 다룬다. Triggers: "LLM 모델 변경", "프로바이더 추가", "비용 추정", "예산 가드", "pricing table", "모델 비교", "LLM 비용", "토큰 사용량", "모델 추가", "LLM 설정", "Gemini", "OpenAI", "API key", "model pricing", "budget cap", "token count", "adapter", "factory".
working-with-anki
AnkiConnect 연결, 카드/덱/모델 조회, 학습 데이터 복제, 백업/롤백, 어려운 카드 탐지, 커스텀 config 액션 등 Anki와의 모든 상호작용을 다룬다. Triggers: "AnkiConnect 연결", "test 프로필", "ease factor 복제", "카드 정보 조회", "학습 데이터", "AnkiConnect API", "Anki 프로필", "카드 모델", "어려운 카드", "난이도 탐지", "difficulty", "백업", "롤백", "분할 적용", "scheduling", "스케줄링", "getConfig", "setConfig", "커스텀 액션". Covers AnkiConnect API wrapper, scheduling clone, backup/rollback, difficulty detection, and custom config actions.
Didn't find tool you were looking for?