Skip to Content

macmini host setup

본 페이지의 위치: 비전 = “macmini 10대 × customer 직원 1-2명/customer 시스템 개선” (D-dev-platform-1). 각 customer 머신 셋업의 SSOT. 신규 customer onboard 시 본 페이지 위에서 자동화 CLI (B-axe-host-bootstrap-cli) 가 진행할 task의 인간이 읽을 reference.

운영자 ritual: 본 페이지 변경 시 = 운영 실패 / 함정 발견 / 신규 layer 추가의 trigger. 모든 macmini 변경의 SSOT.

13 layer + 본 머신 (axe-macmini) 의 현재 값을 짝지어 정리.

Layer 0 — Hardware

  • Mac mini (Apple silicon 권장 — M1/M2/M3/M4). 외장 SSD 1개 (backup tier B).
  • 본 머신 = AXEs-Mac-mini (Soohun 운영).

Layer 1 — macOS + system tunables

항목값 (본 머신)신규 setup
macOS version26.3.1 (Build 25D771280a)26.0+ 권장
Remote Loginon (sshd active port 22)sudo systemsetup -setremotelogin on
kern.tty.ptmx_max511 (default)leak 함정 — Claude Desktop app 의 PTY leak 으로 한도 도달 가능. sudo sysctl -w kern.tty.ptmx_max=2047 + launchd plist 영구화 (B-axe-pty-max-launchd)
launchctl limit maxfiles256 / unlimited낮음 — heavy MCP/Docker 운영 시 부족할 수 있음
launchctl limit maxproc5333 / 8000충분
FileVault(확인 필요)권장 ON (외장 SSD backup 도 암호화)
Time Machine(선택)restic 백업이 primary, TM 은 보조

Layer 2 — macOS users + dev group (D-dev-platform-1)

본 머신:

  • axe (UID 501) — ai@ 봇 전용 (자동화/cron/MCP container 운영자)
  • soohun.kang (UID 502) — 운영자 본인 dev 계정
  • taehun.kang (UID 503) — axev 대표 dev 계정
  • group dev (GID 501) — 위 3명 모두 가입

신규 setup:

sudo bash <<'OPSCRIPT' set -e dseditgroup -o create -r "AXE Developers" -n . dev 2>/dev/null || true dseditgroup -o edit -a axe -t user dev OPSCRIPT # user 추가 (각 사람마다) sudo sysadminctl -addUser <shortname> -fullName "<Full Name>" -password <random> -shell /bin/zsh -home /Users/<shortname> -GID 501 sudo createhomedir -c -u <shortname> sudo dseditgroup -o edit -a <shortname> -t user dev sudo install -d -o <shortname> -g dev -m 700 /Users/<shortname>/.ssh sudo install -m 600 -o <shortname> -g dev /dev/null /Users/<shortname>/.ssh/authorized_keys # password 는 Vaultwarden item 'axe-macmini local: <shortname>' 에 등재

repo 공유 — /Users/axe/{blueprint,frame,hive,axelabs-docs} = group dev + setgid + git core.sharedRepository=group:

for d in blueprint frame hive axelabs-docs; do sudo chgrp -R dev "/Users/axe/$d" sudo find "/Users/axe/$d" -type d -exec chmod g+rwsX {} + git -C "/Users/axe/$d" config core.sharedRepository group done

Layer 3 — sudoers (/etc/sudoers.d/ai-axe, D-dev-platform-1)

ai@ subprocess 가 NOPASSWD 로 실행 가능한 좁은 명령 set:

Cmnd_Alias AI_USER = /usr/sbin/dseditgroup, /usr/sbin/sysadminctl, /usr/bin/dscl ., /usr/sbin/createhomedir Cmnd_Alias AI_SSH = /bin/launchctl kickstart -k system/com.openssh.sshd, /usr/sbin/sshd -t Cmnd_Alias AI_FS = /usr/bin/install, /usr/sbin/chown, /usr/bin/tee /Users/*, /usr/bin/tee /etc/ssh/sshd_config*, /bin/mv /etc/ssh/sshd_config* axe ALL=(ALL) NOPASSWD: AI_USER, AI_SSH, AI_FS

설치: sudo install -m 440 /dev/stdin /etc/sudoers.d/ai-axe <<<'<content>' + sudo visudo -cf /etc/sudoers.d/ai-axe.

금지: tee 의 wildcard 가 /Users/* 또는 /etc/ssh/sshd_config* 로 제한 — tee 자체 무제한 NOPASSWD = root takeover.

Layer 4 — SSH 강화 (D-dev-platform-1)

/etc/ssh/sshd_config.d/200-axe-hardening.conf:

PasswordAuthentication no ChallengeResponseAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes PermitRootLogin no

검증: sudo sshd -t → reload: sudo launchctl kickstart -k system/com.openssh.sshd.

Layer 1 보호 = Cloudflare Tunnel + Zero Trust (Microsoft Entra SSO 게이트). host SSH 는 layer 2 = key-only.

Layer 5 — Tailscale + Cloudflare Tunnel

항목본 머신
Tailscale IP100.127.210.30 (host: axe-macmini)
Cloudflare tunnel UUIDd8efecdd-2c3f-42de-9925-501433e21394 (container axelabs-tunnel)
외부 hostname (axe.axelabs.ai)/blueprint/mcp /frame /hive /vault /index (catch-all → blueprint-app)
추가 hostnamessh.axe.axelabs.ai (host SSH, Zero Trust App) [D-dev-platform-5]
Cloudflare Zero Trust Appb903d8cd-... (Self-hosted, Email policy *@axellc.com)
Zoneaxelabs.ai (zone id 850053fec240de9d83f165cd3e6f10a5)
Account6e6bbb05187c8bfea52d63fa1a06460b

신규 customer 머신:

  • Tailscale install + tailnet 합류 (Microsoft Entra SSO)
  • 새 cloudflared tunnel UUID 발급 (Cloudflare 대시보드)
  • DNS CNAME <customer>.axelabs.ai → tunnel hostname
  • Zero Trust App ssh.<customer>.axelabs.ai (선택 — 외부 dev access 시)

Layer 6 — Microsoft Entra ID

용도
Frame MCP회계 backend 접근 (PKCE public client)
Hive MCPHR backend 접근 (PKCE public client)
Blueprint MCPplatform MCP at apex (PKCE public client)
Vaultwardenpassword vault SSO (OIDC confidential, secret 보관)
Blueprint Webweb UI NextAuth (OIDC)

axe tenant ID = 122fb574-7efa-476a-95b6-bee81bce2cce (axellc.com).

신규 customer = 자기 tenant 별도. 본 머신의 5 앱 패턴 미러. 자동 등록: ops/runbook/customer-onboarding.

Layer 7 — Vaultwarden (D-ops-11 Timshel fork, D-ops-24/26/27/29 SSO)

  • 컨테이너: axe-vaultwarden (host axe.axelabs.ai/vault)
  • bw CLI: 2025.7.0 (Timshel fork schema 호환 — D-ops-28)
  • SSO: Microsoft Entra (SSO_AUTHORITY single-tenant)
  • 환경 vars: SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION=true, SIGNUPS_ALLOWED=true, SSO_ONLY=false, ORGANIZATION_INVITE_AUTO_ACCEPT=true
  • org: AXE (0c5d8bbd-ad85-42b4-8b8a-2849031981b1)
  • collections: Default · frame-jwt-axec · frame-jwt-axev · frame-jwt-operators

신규 customer = vault 인스턴스 별 (또는 same vault 다른 org). axe customers vault-bootstrap <id> (D-dev-platform-3) 가 3 collection 자동.

Vault session 관리 (D-dev-platform-6): axe vault unlock 운영자 1회 → macOS Keychain (axe.vault.session / [email protected]) 에 BW_SESSION push. ai@ subprocess 가 _vault_env() 로 자동 fetch. BW_SESSION 채팅 회신 패턴 폐기.

Layer 8 — Docker stacks

Container용도
axe-tunnel · axelabs-tunnel · artemis-tunnelCloudflare cloudflared (외부 ingress)
axe-caddy · axe-blueprint-mcp-proxy · axe-frame-proxy · axe-hive-proxy · axe-vault-caddyreverse proxy (Caddy 2)
axe-vaultwardenVaultwarden (password vault)
blueprint-app · blueprint-postgres · blueprint-mcp-blue · blueprint-mcp-greenBlueprint platform
frame-mcp-blue · frame-mcp-green · frame-postgres · frame-workerframe 회계
hive-mcp-blue · hive-mcp-green · hive-postgreshive HR
axelabs-docsdocs.axelabs.ai (Nextra)
axelabs · axe-console-appplatform UIs
artemis-api · artemis-web · artemis-db · artemis-collector_*artemis (filings/news)
mysrt-app · mysrt-nginx · mysrt-postgresmysrt SRT 자동 예매

Docker networks: artemis_default · blueprint_default · frame_default · hive_default · mysrt_default · vault_default · console_default.

신규 customer = 동일 stack 일부 (frame + hive + blueprint + vault + cloudflared 가 핵심). axe customer deploy <id> (B-dev-platform-customer-deploy) 자동화 예정.

Layer 9 — launchd jobs

본 머신 활성:

  • com.cortex.frontend / com.cortex.backend / com.cortex.cloudflared (Cortex)
  • com.artemis.filings / collectors / index / index_intraday / reporters / logrotate / backup
  • com.mysrt.app (간접 — mysrt container)
  • com.axe.blueprint-usage-digest (Teams 일일 사용량 09:00 KST)
  • com.axe.blueprint-skills-sync (git webhook → ~/.claude/skills/)
  • com.axe.blueprint-rebuild-watcher (rebuild trigger file polling)
  • com.axe.health-check (매분 7 도메인 + bind-mount probe)
  • com.axe.secret-check (09:00 KST vault drift)
  • com.axe.operator-alert-notify (docker logs tail → osascript notification)
  • com.axe.backup.local (외장 SSD restic)
  • com.axe.restore-drill (분기별 restore 검증)
  • com.axe.ring.push (frame data ring push)
  • com.axe.console.refresh (axe-console-app refresh)

신규 customer = 본 머신 set 의 subset (customer 별 deploy script 가 깔아줌).

Layer 10 — CLI tools

도구설치비고
Homebrew/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"macOS 표준
axe CLI/Users/axe/.axe/bin/axe (local Python single file, git 미관리)별도 git repo 화 backlog
bw CLIbrew install [email protected] (D-ops-28 다운그레이드)Timshel fork 호환
cloudflaredbrew install cloudflaredTunnel + Access SSH
gh CLIbrew install gh + gh auth login --with-tokenaxe-labs-ai PAT (Vault) — D-dev-platform-4
dockerDocker Desktop for Macfile sharing + memory 8GB+
python3macOS 기본 (또는 brew install [email protected])axe CLI venv 자동
pnpm / nodebrew install pnpm (node 자동)Blueprint dev

git config (global):

git config --global user.email [email protected] git config --global user.name "AXE Labs AI"

Layer 11 — Git repos + GitHub

본 머신:

  • /Users/axe/blueprint, frame, hive, axelabs-docs (4 core)
  • /Users/axe/artemis, cortex, axelabs, mysrt, kolon-discussion, distributa, magnet, stream (별 service)
  • /Users/axe/.axe/ — local-only (git 미관리)

GitHub org = axelabs-ai (Free plan, D-dev-platform-5). 4 core repo 에 CODEOWNERS skeleton + PR template (B-dev-platform-cf-zerotrust 완료).

신규 customer = 자기 GitHub user 발급 + axelabs-ai/<customer>-developers team 가입 (axe customers github-team <id>D-dev-platform-3).

Layer 12 — OneDrive sync

운영자 Microsoft OneDrive client 설치 (Soohun 개인 + 공유). symlink 로 ~/OneDrive → workspace 자료. Blueprint Workspace.drivePath = OneDrive 폴더 GUID.

신규 customer = 본인 OneDrive 또는 SharePoint site. Blueprint 의 trinity 모델 (Workspace × OneDrive × TeamsChat).

Layer 13 — Backup (D-config-14 DR cold storage)

  • axe-backup launchd (daily) — restic snapshot
  • Tier A: blueprint-postgres + hive-postgres + customers.yaml + Vaultwarden data dir
  • Tier B: 외장 SSD rotation (사용자 manual swap)
  • restore drill 분기별 (com.axe.restore-drill)

신규 customer = 자기 외장 SSD + 본 머신 patterns 미러.

신규 macmini setup 순서 (요약)

  1. Layer 0-1 (Hardware + macOS) — 운영자 manual
  2. Layer 2 (users + dev group) — axe user add (B-dev-platform-user-add-cli) 자동화 예정
  3. Layer 3-4 (sudoers + SSH) — axe host bootstrap (B-axe-host-bootstrap-cli) 자동화 예정
  4. Layer 5 (Tailscale + Cloudflare) — Tailscale CLI + axe customers dns-placeholder <id> (B-dev-platform-dns-placeholder-cli)
  5. Layer 6 (Entra ID) — 운영자 Azure CLI + 도메인 verify (수동)
  6. Layer 7 (Vault) — axe customers vault-bootstrap <id> + axe vault bootstrap
  7. Layer 8 (Docker) — axe customer deploy <id> (B-dev-platform-customer-deploy) 자동화 예정
  8. Layer 9 (launchd) — axe customer deploy 가 install
  9. Layer 10 (CLI) — axe customer deploy 가 brew install
  10. Layer 11 (Git) — axe customers github-team <id> + 직원 별 collaborator
  11. Layer 12 (OneDrive) — 운영자 수동
  12. Layer 13 (Backup) — axe customer deploy 가 launchd 등재

함정 + 알려진 미해결

함정결과회피 / 결정
kern.tty.ptmx_max=511 한도 + Claude Desktop PTY leakforkpty: Device not configured → 새 terminal 못 열림Claude Desktop 재시작 또는 sysctl 늘림 + launchd plist 영구화 (B-axe-pty-max-launchd)
launchctl limit maxfiles=256heavy MCP/Docker 시 fd 부족per-process 명령 또는 launchd plist 늘림
sudoers wildcard 부정확 — tee 전체 NOPASSWDroot takeovertee 경로 한정 (/Users/*, /etc/ssh/sshd_config*)
Cloudflare API token 의 scope 가 notes 와 실제 다름API 호출 불필요 failcurl /user/tokens/verify 로 실 권한 검증
Bitwarden CLI 2025.8.0+ 가 Timshel fork schema rejectbw 명령 모두 fail2025.7.0 pin (D-ops-28)
BW_SESSION 만료 + ai@ subprocess stdin tty 없음bw CLI 호출 failKeychain-backed session (D-dev-platform-6)
Docker bind-mount file source 손상container “not a directory” 거부file → dir 변환 + restic restore
Fine-grained PAT 의 Resource owner = 본인 (org 아님)org repo 접근 시 “Could not resolve to a Repository” (404), org membership 와 무관발급 시 Resource owner dropdown = org 선택 (D-dev-platform-4)
GitHub UI 에서 PAT regenerate → keyring stalegh auth status ✓ 인데 모든 API 401 (gh CLI 가 옛 token cached)gh auth logout -h github.com -u <user> + gh auth login --with-token 새 PAT 으로 재로그인
bw CLI subprocess 호출 시 BW_SESSION env 누락bw 가 master password prompt → subprocess stdin pipe → hang 또는 JSON parse failpython subprocess.run(..., env={**os.environ, "BW_SESSION": ..., "NODE_EXTRA_CA_CERTS": ...}) 명시 전달 (D-dev-platform-6)

관련 페이지

Last updated on