feat: Alpine ベースの Claude Code リモート実行 Helm チャート初版 (v2.1.259)
Helm Chart Release / release-chart (push) Successful in 12s
Build Session Image / build-push (push) Successful in 2m15s

gateway(nginx) + manager(python 標準ライブラリ) + セッションごとの使い捨て Pod +
reaper CronJob の構成。ブラウザ(PC/スマホ)からアクセスし、セッション単位で
独立した Alpine コンテナに Git リポジトリ(GitHub/Gitea など)をチェックアウトして
編集・検証・プッシュする。無操作が続いたセッションは Pod ごと自動破棄。

- セキュリティ: セッション NS 分離 / restricted PodSecurity / RBAC はセッション NS の
  pods,services のみの Role / セッション Pod は SA トークン非マウント・非 root・
  readOnlyRootFilesystem・drop ALL caps・seccomp / NetworkPolicy で egress を
  DNS+HTTPS+SSH に限定 / Git ホスト allow-list / ResourceQuota+LimitRange
- ライフサイクル: idleTimeout(Pod 内ウォッチドッグ + manager 回収) / maxLifetime
  (activeDeadlineSeconds) / maxSessions / 予備の孤児掃除 CronJob
- 認証: token(既定) / basic / forward(外部SSO) / none。WebSocket は Cookie トークン
- Claude 認証: ANTHROPIC_API_KEY または CLAUDE_CODE_OAUTH_TOKEN
- CI: helm-release.yaml(未リリース版のみ tag+release+publish) /
  image-update-and-release.yaml(週次 npm 追従) / session-image.yaml(multi-arch build)
- files/ 実体を .Files.Get で ConfigMap 化。helm lint / template 検証済み
This commit is contained in:
2026-09-03 08:10:12 +09:00
parent 457a81a17f
commit 1bd0fec23a
39 changed files with 3745 additions and 1 deletions
+100
View File
@@ -0,0 +1,100 @@
# nginx.conf (envsubst テンプレート) — claude-code gateway
# 受付・認証・WebSocket プロキシの単一入口。read-only rootfs / 非 root で動作する。
worker_processes auto;
pid /tmp/nginx/nginx.pid;
error_log /dev/stderr ${NGINX_ERROR_LEVEL};
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
client_body_temp_path /tmp/nginx/body;
proxy_temp_path /tmp/nginx/proxy;
fastcgi_temp_path /tmp/nginx/fastcgi;
uwsgi_temp_path /tmp/nginx/uwsgi;
scgi_temp_path /tmp/nginx/scgi;
sendfile on;
tcp_nopush on;
server_tokens off;
client_max_body_size 25m;
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
resolver ${NGINX_RESOLVER} valid=10s ipv6=off;
server {
listen ${GATEWAY_PORT};
listen [::]:${GATEWAY_PORT};
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options SAMEORIGIN always;
add_header Referrer-Policy no-referrer always;
# ---- HTTP Basic(auth.mode=basic のときのみ内容を持つ)----
include /tmp/nginx/auth_basic.conf;
location = /healthz {
auth_basic off;
proxy_pass http://127.0.0.1:${MANAGER_PORT}/healthz;
}
# ---- auth_request の実体(auth.mode=token|forward)----
location = /_auth {
internal;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Method $request_method;
include /tmp/nginx/auth_backend.conf;
}
# ---- 制御プレーン(UI / API)----
location / {
include /tmp/nginx/auth_request.conf;
proxy_pass http://127.0.0.1:${MANAGER_PORT};
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# UI とログインは常に到達可能にする(token モードのログイン導線のため)
location = / { proxy_pass http://127.0.0.1:${MANAGER_PORT}; proxy_set_header Host $host; }
location = /index.html { proxy_pass http://127.0.0.1:${MANAGER_PORT}; proxy_set_header Host $host; }
location = /login { proxy_pass http://127.0.0.1:${MANAGER_PORT}; proxy_set_header Host $host; }
location = /api/config {
include /tmp/nginx/auth_request.conf;
proxy_pass http://127.0.0.1:${MANAGER_PORT};
proxy_set_header Host $host;
}
# ---- セッションへのリバースプロキシ(WebSocket 対応)----
location ~ ^/s/(?<sid>[a-f0-9]{10})(?<rest>/.*)?$ {
include /tmp/nginx/auth_basic.conf;
include /tmp/nginx/auth_request.conf;
error_page 401 = @needlogin;
set $rest_path $rest;
if ($rest_path = "") { set $rest_path /; }
set $sess_backend "http://claude-sess-$sid.${SESSIONS_NS}.svc.cluster.local:${TTYD_PORT}";
proxy_pass $sess_backend$rest_path$is_args$args;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
location @needlogin {
return 302 /?next=$request_uri;
}
}
}