diff options
| -rw-r--r-- | caddy/Caddyfile (renamed from Caddyfile) | 0 | ||||
| -rwxr-xr-x | caddy/deploy.sh | 6 | ||||
| -rw-r--r-- | caddy/docker-compose.yml (renamed from docker-compose.yml) | 0 | ||||
| -rw-r--r-- | claude/sessions.txt (renamed from claude-code-sessions.txt) | 1 | ||||
| -rwxr-xr-x | claude/sync.sh (renamed from scripts/sync-claude-services.sh) | 13 | ||||
| -rw-r--r-- | claude/systemd/claude-code@.service (renamed from systemd/user/claude-code@.service) | 0 | ||||
| -rwxr-xr-x | git/hooks/hetzner-infra/post-receive | 5 | ||||
| -rwxr-xr-x | git/hooks/tokyo-livehouse-events/post-receive (renamed from server-hooks/tokyo-livehouse-events/post-receive) | 0 | ||||
| -rwxr-xr-x | git/hooks/whois-band/post-receive (renamed from server-hooks/whois-band/post-receive) | 0 | ||||
| -rwxr-xr-x | git/install.sh (renamed from scripts/install.sh) | 8 | ||||
| -rw-r--r-- | git/repos.txt (renamed from repos.txt) | 1 | ||||
| -rwxr-xr-x | git/server-setup.sh | 30 | ||||
| -rw-r--r-- | scripts/claude-daemon-setup.sh | 63 | ||||
| -rw-r--r-- | scripts/server-setup.sh | 42 | ||||
| -rwxr-xr-x | server-hooks/hetzner-infra/post-receive | 14 |
15 files changed, 49 insertions, 134 deletions
diff --git a/Caddyfile b/caddy/Caddyfile index 7e05478..7e05478 100644 --- a/Caddyfile +++ b/caddy/Caddyfile diff --git a/caddy/deploy.sh b/caddy/deploy.sh new file mode 100755 index 0000000..698cd68 --- /dev/null +++ b/caddy/deploy.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env bash +set -euo pipefail +cd "$(dirname "$0")" +docker network create web 2>/dev/null || true +docker compose up -d +docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null || true diff --git a/docker-compose.yml b/caddy/docker-compose.yml index 3e9385d..3e9385d 100644 --- a/docker-compose.yml +++ b/caddy/docker-compose.yml diff --git a/claude-code-sessions.txt b/claude/sessions.txt index 250c3e8..6df2af0 100644 --- a/claude-code-sessions.txt +++ b/claude/sessions.txt @@ -1,6 +1,5 @@ # Claude Code セッション設定 # 形式: <user>:<repo> -# repo は /home/<user>/workspaces/repos/<repo> が存在すること yyamashita:hetzner-infra yyamashita:tokyo-livehouse-events yyamashita:whois-band diff --git a/scripts/sync-claude-services.sh b/claude/sync.sh index a9a76fb..26f3da1 100755 --- a/scripts/sync-claude-services.sh +++ b/claude/sync.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# サーバー側で root として実行し、各ユーザーの Claude Code systemd user service を同期する +# サーバー上で root として手動実行する +# 各ユーザーの Claude Code systemd user service を sessions.txt に基づいて同期する set -euo pipefail APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" -TEMPLATE_SRC="$APP_DIR/systemd/user/claude-code@.service" -SESSIONS_FILE="$APP_DIR/claude-code-sessions.txt" +TEMPLATE_SRC="$APP_DIR/claude/systemd/claude-code@.service" +SESSIONS_FILE="$APP_DIR/claude/sessions.txt" -# sessions.txt をパースして user -> repos のマップを構築 declare -A user_repos while IFS= read -r line; do @@ -24,7 +24,6 @@ for user in "${!user_repos[@]}"; do mkdir -p "$systemd_dir" chown "$user:$user" "$systemd_dir" - # テンプレートを更新(差分があれば) if ! diff -q "$TEMPLATE_SRC" "$systemd_dir/claude-code@.service" >/dev/null 2>&1; then echo "[$user] Updating claude-code@.service template" cp "$TEMPLATE_SRC" "$systemd_dir/claude-code@.service" @@ -33,7 +32,6 @@ for user in "${!user_repos[@]}"; do systemctl --user daemon-reload fi - # sessions.txt で指定されたリポジトリを enable & start desired=() for repo in ${user_repos[$user]}; do [[ -z "$repo" ]] && continue @@ -53,12 +51,11 @@ for user in "${!user_repos[@]}"; do fi done - # sessions.txt にないが enabled になっているインスタンスを無効化 while IFS= read -r unit; do instance="${unit#claude-code@}" instance="${instance%.service}" if ! printf '%s\n' "${desired[@]}" | grep -qx "$instance"; then - echo "[$user] Disabling claude-code@${instance}.service (not in sessions.txt)" + echo "[$user] Disabling claude-code@${instance}.service" runuser -u "$user" -- env XDG_RUNTIME_DIR="$runtime_dir" DBUS_SESSION_BUS_ADDRESS="unix:path=$runtime_dir/bus" \ systemctl --user disable --now "claude-code@${instance}.service" || true fi diff --git a/systemd/user/claude-code@.service b/claude/systemd/claude-code@.service index e3983b6..e3983b6 100644 --- a/systemd/user/claude-code@.service +++ b/claude/systemd/claude-code@.service diff --git a/git/hooks/hetzner-infra/post-receive b/git/hooks/hetzner-infra/post-receive new file mode 100755 index 0000000..d41659b --- /dev/null +++ b/git/hooks/hetzner-infra/post-receive @@ -0,0 +1,5 @@ +#!/bin/bash +set -e +GIT_WORK_TREE=/app/infra git checkout -f +bash /app/infra/caddy/deploy.sh +echo "Deploy complete: hetzner-infra" diff --git a/server-hooks/tokyo-livehouse-events/post-receive b/git/hooks/tokyo-livehouse-events/post-receive index ca64767..ca64767 100755 --- a/server-hooks/tokyo-livehouse-events/post-receive +++ b/git/hooks/tokyo-livehouse-events/post-receive diff --git a/server-hooks/whois-band/post-receive b/git/hooks/whois-band/post-receive index 60b368f..60b368f 100755 --- a/server-hooks/whois-band/post-receive +++ b/git/hooks/whois-band/post-receive diff --git a/scripts/install.sh b/git/install.sh index 9f06489..12f561c 100755 --- a/scripts/install.sh +++ b/git/install.sh @@ -1,19 +1,18 @@ #!/usr/bin/env bash # サーバー上で root として手動実行する # repos.txt に基づいてベアリポジトリとワークツリーを作成し、 -# server-hooks/ のフックを /var/git/*/hooks/ に展開する +# git/hooks/ のフックを /var/git/*/hooks/ に展開する set -euo pipefail APP_DIR="$(cd "$(dirname "$0")/.." && pwd)" -REPOS_FILE="$APP_DIR/repos.txt" -HOOKS_SRC="$APP_DIR/server-hooks" +REPOS_FILE="$APP_DIR/git/repos.txt" +HOOKS_SRC="$APP_DIR/git/hooks" if [[ "$(id -u)" -ne 0 ]]; then echo "ERROR: root として実行してください" >&2 exit 1 fi -# ベアリポジトリ・ワークツリー作成 echo "=== Repositories ===" while IFS=: read -r repo_name work_tree; do [[ "$repo_name" =~ ^#.*$ || -z "$repo_name" ]] && continue @@ -33,7 +32,6 @@ while IFS=: read -r repo_name work_tree; do fi done < "$REPOS_FILE" -# フック展開 echo "" echo "=== Hooks ===" for repo_src in "$HOOKS_SRC"/*/; do diff --git a/repos.txt b/git/repos.txt index e7cd697..58ab877 100644 --- a/repos.txt +++ b/git/repos.txt @@ -1,6 +1,5 @@ # リポジトリ定義 # 形式: <repo-name>:<work-tree-path> -# /var/git/<repo-name>.git が bare repo、<work-tree-path> が checkout 先 hetzner-infra:/app/infra tokyo-livehouse-events:/app/tokyo-livehouse-events whois-band:/app/whois-band diff --git a/git/server-setup.sh b/git/server-setup.sh new file mode 100755 index 0000000..a575628 --- /dev/null +++ b/git/server-setup.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Run once on a fresh Hetzner VPS (as root). +# hetzner-infra のみブートストラップとして作成する。 +# 他のリポジトリは最初の push 後に git/install.sh が作成する。 +set -e + +REPO_DIR=/var/git/hetzner-infra.git +APP_DIR=/app/infra + +curl -fsSL https://get.docker.com | sh +docker network create web || true + +mkdir -p "$REPO_DIR" "$APP_DIR" +git init --bare "$REPO_DIR" + +# 最初の push を受け取るための最小限のフック(git/install.sh 実行後に上書きされる) +cat > "$REPO_DIR/hooks/post-receive" << 'HOOK' +#!/bin/bash +set -e +GIT_WORK_TREE=/app/infra git checkout -f +bash /app/infra/caddy/deploy.sh +echo "Deploy complete: hetzner-infra" +HOOK +chmod +x "$REPO_DIR/hooks/post-receive" + +echo "" +echo "Next steps:" +echo " 1. git remote add origin root@<server-ip>:$REPO_DIR" +echo " 2. git push origin master" +echo " 3. ssh root@<server-ip> 'bash $APP_DIR/git/install.sh'" diff --git a/scripts/claude-daemon-setup.sh b/scripts/claude-daemon-setup.sh deleted file mode 100644 index 0652e27..0000000 --- a/scripts/claude-daemon-setup.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/bin/bash -# Set up Claude Code remote-control daemons for each app repo (run as root on Hetzner VPS). -set -e - -# Install Claude Code if not present -if ! command -v claude &>/dev/null; then - npm install -g @anthropic-ai/claude-code -fi - -# Create non-root user for claude sessions (root is blocked by claude security policy) -if ! id claude-agent &>/dev/null; then - useradd -r -m -s /bin/bash claude-agent -fi -usermod -aG docker claude-agent -chown -R claude-agent:claude-agent /app - -# Copy credentials from root to claude-agent -cp /root/.claude.json /home/claude-agent/.claude.json -chown claude-agent:claude-agent /home/claude-agent/.claude.json - -declare -A REPOS=( - ["infra"]="/app/infra" - ["tokyo"]="/app" - ["whoisband"]="/app/whois-band" -) - -for NAME in "${!REPOS[@]}"; do - DIR="${REPOS[$NAME]}" - SERVICE="claude-${NAME}.service" - - cat > "/etc/systemd/system/${SERVICE}" << EOF -[Unit] -Description=Claude Code Remote Session - ${NAME} -After=network.target - -[Service] -Type=simple -User=claude-agent -WorkingDirectory=${DIR} -ExecStart=/usr/bin/script -q -c "claude --remote-control ${NAME}" /dev/null -Restart=always -RestartSec=15 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=multi-user.target -EOF - - systemctl daemon-reload - systemctl enable "${SERVICE}" - systemctl restart "${SERVICE}" - echo "Started: ${SERVICE} (WorkingDirectory: ${DIR})" -done - -echo "" -echo "All Claude Code daemons running. Connect via https://claude.ai/code" -echo "" -echo "Useful commands:" -echo " systemctl status claude-infra" -echo " systemctl status claude-tokyo" -echo " systemctl status claude-whoisband" -echo " journalctl -u claude-tokyo -f" diff --git a/scripts/server-setup.sh b/scripts/server-setup.sh deleted file mode 100644 index ca9a3f9..0000000 --- a/scripts/server-setup.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/bash -# Run once on a fresh Hetzner VPS (as root). -# hetzner-infra のみブートストラップとして作成する。 -# 他のリポジトリは最初の push 後に install.sh が作成する。 -set -e - -REPO_DIR=/var/git/hetzner-infra.git -APP_DIR=/app/infra - -# Install Docker -curl -fsSL https://get.docker.com | sh - -# Create shared Docker network -docker network create web || true - -# hetzner-infra bare repo をブートストラップ -mkdir -p "$REPO_DIR" "$APP_DIR" -git init --bare "$REPO_DIR" - -# 最初の push を受け取るための最小限のフック(install.sh 実行後に上書きされる) -cat > "$REPO_DIR/hooks/post-receive" << 'HOOK' -#!/bin/bash -set -e -APP_DIR=/app/infra -GIT_WORK_TREE=$APP_DIR git checkout -f -cd $APP_DIR -docker network create web 2>/dev/null || true -docker compose up -d -docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null || true -echo "Deploy complete: hetzner-infra" -if [ -f "$APP_DIR/scripts/sync-claude-services.sh" ]; then - bash "$APP_DIR/scripts/sync-claude-services.sh" -fi -HOOK -chmod +x "$REPO_DIR/hooks/post-receive" - -echo "" -echo "Next steps:" -echo " 1. git remote add origin root@<server-ip>:$REPO_DIR" -echo " 2. git push origin master" -echo " 3. ssh root@<server-ip> 'bash $APP_DIR/scripts/install.sh'" -echo " (他のリポジトリ作成 + 全フックの正式インストール)" diff --git a/server-hooks/hetzner-infra/post-receive b/server-hooks/hetzner-infra/post-receive deleted file mode 100755 index cc3fa8e..0000000 --- a/server-hooks/hetzner-infra/post-receive +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash -set -e -APP_DIR=/app/infra -GIT_WORK_TREE=$APP_DIR git checkout -f -cd $APP_DIR -docker network create web 2>/dev/null || true -docker compose up -d -docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile 2>/dev/null || true -echo "Deploy complete: hetzner-infra" - -# Claude Code セッション同期 -if [ -f "$APP_DIR/scripts/sync-claude-services.sh" ]; then - bash "$APP_DIR/scripts/sync-claude-services.sh" -fi |
