Files
auto-stock/.claude/settings.local.json
shuim 19d25e5528 perf: NAS 도커 빌드 시간 단축 — CPU 전용 torch + 빌드 캐시 마운트
DS1517+(Atom C2538)에서 빌드가 30분 이상 걸리던 원인 두 가지를 제거.

1. PyTorch CPU 전용 휠 사용 (backend)
   PyPI 기본 torch 휠은 nvidia-cublas/cudnn 등 CUDA 패키지를 수 GB
   함께 내려받는데 NAS에는 GPU가 없어 전부 불필요했다.
   download.pytorch.org/whl/cpu 에서 먼저 설치하면 requirements.txt 의
   torch 줄은 충족되어 건너뛴다. ml_ensemble 은 이미 지연 임포트라 동작 동일.

2. pip/npm 캐시를 빌드 간 재사용 (backend, mcp-server, frontend)
   --no-cache-dir 제거하고 RUN --mount=type=cache 로 전환.
   requirements.txt 가 바뀌어도 받아둔 휠은 재다운로드하지 않는다.
   Jenkinsfile 에 DOCKER_BUILDKIT/COMPOSE_DOCKER_CLI_BUILD 추가.

부수: frontend Dockerfile 의 FromAsCasing 경고 정리 (as build → AS build).
세 Dockerfile 모두 docker build --check 통과.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-19 23:57:21 +09:00

204 lines
10 KiB
JSON

{
"permissions": {
"allow": [
"Bash(docker ps:*)",
"Bash(lsof:*)",
"Bash(./scripts/dev.sh:*)",
"Bash(curl:*)",
"Bash(ls:*)",
"Bash(docker compose:*)",
"Bash(docker-compose up:*)",
"Bash(docker-compose restart:*)",
"Bash(npm run build:*)",
"Bash(python3:*)",
"Bash(npm install:*)",
"Bash(docker exec:*)",
"Bash(docker restart:*)",
"mcp__auto-stock__get_recommendations",
"Bash(pip install:*)",
"Bash(python -c:*)",
"Bash(git pull:*)",
"Bash(git stash:*)",
"Bash(git -C /Users/commylife/myproject/java/workspace/auto-stock ls-files)",
"Bash(docker-compose ps:*)",
"Bash(docker build:*)",
"mcp__auto-stock__get_trade_history",
"mcp__auto-stock__get_portfolio",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git diff:*)",
"Bash(git status:*)",
"Bash(git log:*)",
"Bash(find:*)",
"Bash(grep:*)",
"Bash(cat:*)",
"Bash(cp:*)",
"Bash(mv:*)",
"Bash(mkdir:*)",
"Write(*)",
"Edit(*)",
"MultiEdit(*)",
"Bash(docker cp backend/app/api/endpoints/portfolio.py autostock-backend:/app/app/api/endpoints/portfolio.py)",
"Bash(make batch-test)",
"Bash(git push -u origin claude/naughty-carson)",
"Bash(gh auth status)",
"Bash(git remote get-url origin)",
"Bash(python *)",
"Bash(python3 *)",
"Bash(pip *)",
"Bash(pytest *)",
"Bash(cd *)",
"Bash(which *)",
"Bash(npm *)",
"Bash(npx *)",
"Bash(wc -l /private/tmp/claude-501/-Users-commylife-myproject-java-workspace-auto-stock/9a0e3e65-94e8-4083-8cea-995f6eb28298/tasks/*.output)",
"Bash(docker cp:*)",
"Bash(chmod:*)",
"Bash(bash /Users/commylife/myproject/java/workspace/auto-stock/backend/monitor_trading.sh 2>&1)",
"WebFetch(domain:finance.naver.com)",
"Bash(xargs -I {} python -m py_compile {})",
"Bash(for f:*)",
"Bash(do python:*)",
"Bash(echo \"$f OK\")",
"Bash(done)",
"Bash(find /Users/commylife/myproject/java/workspace/auto-stock -type f \\\\\\(-name *.tmp -o -name *.bak -o -name *.swap \\\\\\))",
"Bash(source /Users/commylife/myproject/java/workspace/auto-stock/.venv/bin/activate:*)",
"Bash(/Users/commylife/myproject/java/workspace/auto-stock/.venv/bin/python:*)",
"Bash(/Users/commylife/myproject/java/workspace/auto-stock/.venv/bin/python3:*)",
"Bash(/Users/commylife/myproject/java/workspace/auto-stock/.venv/bin/pip:*)",
"Bash(/Users/commylife/myproject/java/workspace/auto-stock/.venv/bin/pytest:*)",
"Bash(.venv/bin/python:*)",
"Bash(.venv/bin/python3:*)",
"Bash(.venv/bin/pip:*)",
"Bash(.venv/bin/pytest:*)",
"Bash(ssh:*)",
"Bash(find /Users/commylife/myproject/java/workspace/auto-stock/frontend/src -type f \\\\\\(-name *.tsx -o -name *.ts \\\\\\))",
"Bash(git push:*)",
"Bash(git fetch:*)",
"Bash(sqlite3 /Users/commylife/myproject/java/workspace/auto-stock/data/trading_db.sqlite \"SELECT sql FROM sqlite_master WHERE type=''table'' AND name=''trade_history'';\")",
"Bash(git rev-list *)",
"Bash(/usr/sbin/ab -n 100 -c 10 -k -s 20 \"https://dev-fo.wegolpg.com/login.do\")",
"Bash(echo *)",
"Bash(mkdir -p /tmp/scan)",
"Bash(nohup nikto -h https://dev-fo.wegolpg.com -maxtime 300 -Tuning 123457890abc -o /tmp/scan/nikto.txt -Format txt)",
"Bash(nmap -Pn -T4 --host-timeout 120s -p 80,443,8011,8080,8443,22,3306,5432,6379,5672 -sV dev-fo.wegolpg.com)",
"Bash(sslscan --no-colour dev-fo.wegolpg.com)",
"Bash(ab -n 10000 -c 50 -k -s 30 \"https://dev-fo.wegolpg.com/login.do\")",
"Bash(ab -n 10000 -c 50 -s 30 \"https://dev-fo.wegolpg.com/login.do\")",
"Bash(break)",
"Bash(/usr/bin/curl -sS -c cookies.txt --max-time 15 \"https://dev-fo.wegolpg.com/login.do\")",
"Bash(awk '{print $6, $7}')",
"Bash(/usr/bin/curl -sS --max-time 15 \"https://dev-fo.wegolpg.com/resources/js/sas-981bf3b8ad0f002d8bb7b6c6ac55a5b2.js\")",
"Bash(docker info *)",
"Bash(.venv/bin/pip list *)",
"Bash(open -a Docker)",
"Bash(awk 'NR>=1')",
"Bash(awk 'NR>=340 && NR<=430 { print NR\": \"$0 }' app/main.py)",
"Bash(timeout 75 docker logs -f --since 1s autostock-backend)",
"Bash(wait)",
"Bash(xargs -I{} sh -c 'sed -n \"$\\(\\({}-20\\)\\),$\\(\\({}+5\\)\\)p\" app/services/trade_executor.py')",
"Bash(ping -c 3 -b 192.168.50.255)",
"Bash(ping -c 3 192.168.50.255)",
"Bash(arp -an)",
"Bash(sort -t. -k4 -n)",
"Bash(command -v curl)",
"Bash(command -v head)",
"Bash(nmap -Pn -p- -T4 --max-retries 1 --host-timeout 300s 192.168.50.1)",
"Bash(/usr/bin/head -20)",
"Bash(/usr/bin/curl -sk -D - -o /tmp/b188.html --max-time 10 \"https://192.168.50.188:15023/\")",
"Bash(/usr/bin/head -12)",
"Bash(/usr/bin/head -c 600 /tmp/b188.html)",
"Bash(/usr/bin/grep -ioE \"location\\\\.href[^;]*|block|denied|forbidden|not allow|WAN|Main_Login|cloud_sync\" /tmp/b188.html)",
"Bash(/usr/bin/head -10)",
"Bash(/usr/bin/curl -sk --max-time 10 \"https://192.168.50.188:15023/message.htm\" -o /tmp/msg188.html)",
"Bash(/usr/bin/sed -e 's/<[^>]*>//g' /tmp/msg188.html)",
"Bash(/usr/bin/grep -vE \"^\\\\s*$\")",
"Bash(/usr/bin/grep -oE \"desc[^;]{0,200}|You have no .{0,120}|not authorized.{0,80}|LAN.{0,80}\" /tmp/msg188.html)",
"Bash(/usr/bin/head -6)",
"Bash(bash -n /private/tmp/claude-501/-Users-commylife-myproject-java-workspace-auto-stock/93c4883b-04d6-4a82-ab88-849275eb0a32/scratchpad/sniff-nas.sh)",
"Bash(/usr/bin/head -4)",
"Bash(/usr/bin/head -8 /tmp/nas-sniff.txt)",
"Bash(/usr/bin/awk '{print $2}' /tmp/nas-sniff.txt)",
"Bash(/usr/bin/head -25)",
"Bash(networksetup -listallhardwareports)",
"Bash(/usr/bin/grep -A1 \"Hardware Port\")",
"Bash(/usr/bin/grep -vE \"^--\")",
"Bash(/usr/bin/xargs echo \" 고유 MAC 수:\")",
"Bash(/usr/bin/grep -v \"^192\\\\.168\\\\.50\\\\.\")",
"Bash(/usr/bin/head)",
"Bash(/usr/bin/head -5)",
"Bash(/usr/bin/curl -sI --max-time 8 http://192.168.50.197:5000/)",
"Bash(/usr/bin/grep -i \"^date:\")",
"Bash(openssl s_client -connect 192.168.50.197:5001 -servername nas.shium.net)",
"Bash(openssl s_client -connect 192.168.50.197:443 -servername nas.shium.net)",
"Bash(openssl x509 *)",
"Bash(/usr/bin/curl -skI --max-time 8 https://192.168.50.197/)",
"Bash(/usr/bin/curl -sI --max-time 8 http://192.168.50.197/)",
"Bash(openssl s_client -connect 192.168.50.197:6082 -servername nas.shium.net)",
"Bash(/usr/bin/curl -o /dev/null -w \" 검증 결과: %{http_code}\\\\n\" --max-time 8 https://192.168.50.197:6082/)",
"Bash(/usr/bin/head -3)",
"Bash(openssl s_client -connect 192.168.50.197:6082)",
"Bash(/usr/bin/curl -sk -o /dev/null -w \" https → HTTP %{http_code}\\\\n\" --max-time 8 https://192.168.50.197:6082/)",
"Bash(/usr/bin/curl -s -o /dev/null -w \" http → HTTP %{http_code}\\\\n\" --max-time 8 http://192.168.50.197:6082/)",
"Bash(openssl s_client -connect 192.168.50.198:443)",
"Bash(traceroute -I -m 5 -w 2 -q 3 8.8.8.8)",
"Bash(/usr/bin/head -8)",
"Bash(traceroute -m 5 -w 2 -q 3 1.1.1.1)",
"Bash(/usr/bin/curl -s --max-time 8 https://api.ipify.org)",
"Bash(/usr/bin/curl -s --max-time 8 http://192.168.75.1/dzs/login.asp)",
"Read(//tmp/**)",
"Bash(/usr/bin/grep -ioE \"model[^<>\\\\\"]{0,40}|DASAN[^<>\\\\\"]{0,30}|SK[ _-]?\\(broadband|telecom\\)[^<>\\\\\"]{0,20}|H[0-9]{3}[A-Z]?|GW-[A-Z0-9-]+|<title>[^<]*</title>\" /tmp/dzs.html)",
"Bash(/usr/bin/head -15)",
"Bash(/usr/bin/sed -e 's/<[^>]*>/ /g' /tmp/dzs.html)",
"Bash(/usr/bin/tr -s ' \\\\n' ' \\\\n')",
"Bash(/usr/bin/curl -s --max-time 8 http://192.168.50.1:55522/rootDesc.xml)",
"Bash(/usr/bin/grep -oE \"<\\(UDN|serialNumber|modelName|friendlyName\\)>[^<]*</[a-zA-Z]+>\" /tmp/root.xml)",
"Bash(/usr/bin/grep -oiE \"\\([0-9a-f]{2}[:-]\\){5}[0-9a-f]{2}|[0-9a-f]{12}\" /tmp/root.xml)",
"Bash(/usr/bin/grep \"192.168.50.1\\)\")",
"Bash(dig +short A nas.shium.net @1.1.1.1)",
"Bash(/usr/bin/tail -1)",
"Bash(/usr/bin/grep -nE \"^ [a-z0-9_-]+:\" docker-compose.yml)",
"Bash(/usr/bin/grep -nE \"^#{1,3} \" deploy/NAS-SETUP-GUIDE.md)",
"Bash(/usr/bin/head -30)",
"Bash(/usr/bin/grep -nE \"stage\\\\\\(|DEPLOY_DIR|sh '|sh \\\\\"\" Jenkinsfile)",
"Bash(/usr/bin/awk '/^ [a-z0-9_-]+:/{svc=$1} /ports:/{p=1;next} p&&/^ *- /{print \" \"svc\" \"$2} p&&!/^ *- /{p=0}' docker-compose.yml)",
"Bash(/usr/bin/grep -nE \"^ [a-z0-9_-]+:|ports:|^ - \\\\\"\" docker-compose.yml)",
"Bash(/usr/bin/head -40)",
"Bash(/usr/bin/grep -rn \"proxy_pass\\\\|location /api\\\\|location /\" frontend/nginx.conf frontend/default.conf docker/nginx*.conf)",
"Bash(/usr/bin/grep -nE \"server_name|location|proxy_pass|listen\" deploy/nginx-reverse-proxy.conf)",
"Bash(/usr/bin/grep -nE \"listen|server_name|location|proxy_pass|try_files|root\" frontend/nginx.conf)",
"Bash(/usr/bin/grep -A2 \"^ frontend:\" docker-compose.yml)",
"Bash(/usr/bin/head -1)",
"Bash(/usr/bin/grep -nE \"3001\" docker-compose.yml)",
"Bash(/usr/bin/grep -nE \"3001|3000|:80\\\\\"\")",
"Bash(/usr/bin/grep -E \"^[+-].*\\(ports|[0-9]{4}:\\)\")",
"Bash(/usr/bin/curl -sk -o /tmp/stock.html -w \" HTTP %{http_code} / %{size_download} bytes / %{time_total}s\\\\n\" --max-time 10 https://stock.shium.net/)",
"Bash(/usr/bin/head -c 300 /tmp/stock.html)",
"Bash(/usr/bin/curl -sk -o /dev/null -w \" /api/v1/market-data/prices → HTTP %{http_code}\\\\n\" --max-time 10 \"https://stock.shium.net/api/v1/market-data/prices?codes=005930\")",
"Bash(/usr/bin/tail -5)",
"Bash(/usr/bin/head -2)",
"Bash(/usr/bin/cat backend/Dockerfile)",
"Bash(/usr/bin/cat backend/requirements.txt)",
"Bash(docker --version)"
]
},
"enableAllProjectMcpServers": true,
"enabledMcpjsonServers": [
"auto-stock"
],
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "python3 \"$CLAUDE_PROJECT_DIR/.claude/hooks/auto-orchestrate.py\"",
"timeout": 10,
"statusMessage": "오케스트레이션 모드 판정 중..."
}
]
}
]
}
}