Files
agent-helm/deploy/DEPLOY.md
Bjorn Blomberg 98c4d13360
All checks were successful
build-and-push / build (push) Successful in 22s
release-client / build-release (push) Successful in 48s
BeforeTool-hook + kort-vy (strukturerade godkännanden) + release på master-push
Feature: strukturerade verktygsgodkännanden
- shared: protokoll för approval (daemon:approval, server:approval[-resolved],
  web:approval-decision, server:approval-decision)
- daemon: hook-läge ('agent-helm hook' — samma binär), lokal 127.0.0.1-endpoint
  som hooken POST:ar till, long-poll tills beslut; graceful default (allow) när
  ingen UI; timeout-fallback; skickar AGENT_HELM_HOOK_PORT till agentens env
- server: routar daemon:approval -> prenumeranter, beslut -> daemon + döljer kort
- web: reaktiv approvals-lista + kort-overlay (Tillåt/Neka), mobilanpassad

CI:
- release.yaml triggar nu även på master-push -> rullande 'latest'-release
  (versionerade releaser kvar på v*-taggar); install.sh hämtar 'latest'

Docs: hook-konfig (gemini settings.json) + hook-env i .env.example + DEPLOY.md.
Säkerhet: hook-endpoint binder endast 127.0.0.1; inga hemligheter i repot.

Verifierat lokalt: hook->daemon->server->kort->beslut->hook ger {"decision":"allow"};
alla paket typecheckar; web bygger.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 18:03:12 +02:00

8.9 KiB

Deploy: agent-helm på Pi5 via Gitea Actions → registry → Dockge → NPM

Flödet: git push masterGitea Actions-runnern på Pi5 bygger arm64-image:n → pushar till localhost:5000/agent-helm-server:latestDockge kör stacken → NPM exponerar https://rcai.brasse-pc.eu. Uppdatering = push + klicka Update i Dockge.

push master ──► gitea-act-runner (bygg arm64) ──► localhost:5000/agent-helm-server:latest
                                                          │
                                                   Dockge: Update (pull + up -d)
                                                          ▼
                                          container "agent-helm" :8787 (srv_default)
                                                          ▲
                                  NPM: rcai.brasse-pc.eu ─┘ (Websockets ON, TLS)

Förutsättningar som redan är på plats: DNS rcai.brasse-pc.eu → 155.4.72.51 (✓), srv_default-nätet, docker-registry och npm körs (✓). Gitea 1.24 har Actions påslaget som default.

Kataloger & ägarskap (gör FÖRE deploy)

Bind-mountade kataloger måste finnas och ägas av uid 1000 innan containern startar. Startar containern först skapar Docker katalogen som root, och appen (kör som uid 1000 node) kan då inte läsa/skriva den. Skapa som brasse (= uid 1000):

# data/config för appen (måste vara uid 1000-ägd — appen skriver hit)
mkdir -p /srv/docker/agent-helm
# runner-state
mkdir -p /srv/docker/act-runner
# stack-mappar för Dockge
mkdir -p /srv/dockge-staks/act-runner /srv/dockge-staks/agent-helm

# verifiera ägarskap (ska visa uid 1000 i andra kolumnen)
ls -ln /srv/docker | grep -E 'agent-helm|act-runner'

Om någon katalog råkat bli root-ägd (t.ex. för att en container startade först):

sudo chown -R 1000:1000 /srv/docker/agent-helm
# starta sedan om stacken så mounten läses om

Steg 1 — Registrera Gitea Actions-runnern (engång)

  1. Hämta registrerings-token i Gitea: Site Administration → Actions → Runners → Create new runner → kopiera token. (Eller repo-nivå: brasse/agent-helm → Settings → Actions → Runners.)

  2. Skapa stacken i Dockge (dockge.brasse-pc.eu):

    • Ny stack, namn act-runner.
    • Klistra in deploy/act-runner.compose.yaml.
    • Lägg deploy/act-runner.config.yaml som filen config.yaml i stacken (Dockge låter dig skapa extra filer i stack-mappen, dvs /srv/dockge-staks/act-runner/config.yaml).
    • I stackens env: GITEA_RUNNER_REGISTRATION_TOKEN=<din-token>.
    • Deploy.
  3. Verifiera: i Gitea Site Administration → Actions → Runners ska pi5-docker-runner dyka upp som Idle. Loggen: docker logs gitea-act-runner.

Runnern monterar värdens docker.sock och bygger med Pi5:ans egen Docker → arm64 nativt, och localhost:5000 (registryn) trustas automatiskt.


Steg 2 — Första bygget

.gitea/workflows/build.yaml triggas på push till master/main. Trigga det:

  • Pusha en commit till master, eller
  • Gitea repo → Actions → välj workflowen → Run workflow (manuell dispatch).

Följ körningen under repo:ts Actions-flik. När den är grön finns localhost:5000/agent-helm-server:latest i registryn.

Snabbkoll (på Pi5, eller via claude-docker):

curl -s http://localhost:5000/v2/agent-helm-server/tags/list
# -> {"name":"agent-helm-server","tags":["latest","<sha>"]}

Steg 3 — Kör stacken i Dockge

  1. Skapa host-katalogen för config/data (som brasse, uid 1000): mkdir -p /srv/docker/agent-helm Den bind-mountas till /app/data i containern (där framtida db/auth hamnar); containern kör som uid 1000 = brasse så filerna blir korrekt ägda.
  2. Ny stack i Dockge, namn agent-helm.
  3. Klistra in deploy/agent-helm.compose.yaml.
  4. I stackens env: AGENT_HELM_TOKEN=<lång slumpad hemlighet> — en stark slumpad sträng (≥ 32 byte). Förvaras bara i stackens .env på Pi5, aldrig i git. Det är denna token som skyddar åtkomsten till dina sessioner, så håll den hemlig.
  5. Deploy. Kolla i Dockge att containern agent-helm är running.

Steg 4 — NPM proxy host (manuellt i NPM-UI:t)

I Proxy.brasse-pc.euProxy Hosts → Add Proxy Host:

Fält Värde
Domain Names rcai.brasse-pc.eu
Scheme http
Forward Hostname agent-helm
Forward Port 8787
Websockets Support (viktigt — WS-kanalen)
Block Common Exploits valfritt

Under SSL: Request a new SSL Certificate (Let's Encrypt) + Force SSL + HTTP/2.

Spara. Öppna https://rcai.brasse-pc.eu → logga in med AGENT_HELM_TOKEN.


Steg 5 — Anslut en daemon (annars finns inga sessioner)

Servern är bara control-plane. En daemon kör agenten och ansluter till servern. Kör den var du vill (workstation, eller som egen container senare):

# på workstationen, i agent-helm-repot
AGENT_HELM_TOKEN=<samma-token> \
SERVER_URL=wss://rcai.brasse-pc.eu \
AGENT_CMD=gemini \
pnpm dev:daemon

Daemonen dyker upp som en session i web-UI:t. (Kräver att NPM:s Websockets är på.)


Klienten (daemon) — installera på en Linux-maskin

Klienten distribueras som självständiga binärer (Node + node-pty inbäddat, inga beroenden på målet) för linux-x64 och linux-arm64, byggda av .gitea/workflows/release.yaml och publicerade som Release-assets på Gitea.

Skapa en release (bygger båda arkitekturerna på Pi-runnern):

git tag v0.1.0 && git push origin v0.1.0
# eller: Gitea -> Actions -> release-client -> Run workflow (ange tag)

Installera på valfri Linux-maskin (Arch, Ubuntu, …) — ett kommando:

curl -fsSL https://gitea.brasse-pc.eu/brasse/agent-helm/raw/branch/main/install.sh | sh

Installern detekterar arch, hämtar rätt binär från senaste releasen, lägger agent-helm i /usr/local/bin (eller ~/.local/bin), skapar ~/.config/agent-helm/config.env och en (valfri) systemd-user-service.

Sätt token + kör:

${EDITOR:-nano} ~/.config/agent-helm/config.env     # AGENT_HELM_TOKEN, SERVER_URL, AGENT_CMD
systemctl --user daemon-reload && systemctl --user enable --now agent-helm
# eller direkt:  set -a; . ~/.config/agent-helm/config.env; agent-helm

Klienten ansluter till wss://rcai.brasse-pc.eu och dyker upp som en session i UI:t.

Strukturerade godkännanden (BeforeTool-hook + kort-vy)

Utöver fallback-tangentbordet kan agentens verktygsanrop visas som godkännande-kort i UI:t (Tillåt/Neka). Det sker via en BeforeTool-hook i Gemini som anropar agent-helm hook — samma binär, så inget extra beroende.

Aktivera genom att lägga till hooken i ~/.gemini/settings.json på maskinen där klienten kör (justera vid behov efter din Gemini-versions hook-schema):

{
  "hooks": {
    "BeforeTool": [
      { "hooks": [{ "type": "command", "command": "agent-helm hook" }] }
    ]
  }
}

Daemonen skickar automatiskt AGENT_HELM_HOOK_PORT till agentens miljö, så agent-helm hook hittar den lokala endpointen själv.

Beteende:

  • UI anslutet → verktygsanropet visas som kort, agenten väntar på ditt beslut.
  • Ingen UI / servern onåbar → AGENT_HELM_HOOK_DEFAULT (default allow — agenten fungerar som utan hook). Sätt AGENT_HELM_HOOK_DEFAULT=deny för strikt läge.
  • Inget svar inom AGENT_HELM_HOOK_TIMEOUT (ms) → default-beslutet används.

Den lokala hook-endpointen binder endast 127.0.0.1 och är aldrig nåbar utifrån.

Uppdatera till senaste

  1. git push master → runnern bygger + pushar :latest.
  2. Dockge → stacken agent-helmUpdate (kör docker compose pull && up -d).

Det var det — senaste image:n körs.


Felsökning

Symptom Trolig orsak / åtgärd
Runnern syns inte i Gitea Fel/förbrukad token. Skapa ny, uppdatera env, redeploy act-runner.
Workflow fastnar på actions/checkout Runnern når inte github för att hämta action:en, eller inte gitea-d:3000. Kolla att runnern är på srv_default.
docker: command not found i jobbet Fel job-image. Labeln ska peka på catthehacker/ubuntu:act-latest.
push nekas / http: server gave HTTP response to HTTPS client Pusha till localhost:5000 (inte 192.168.0.19:5000) från Pi-runnern — localhost trustas som insecure automatiskt.
rcai ger 502 agent-helm-containern nere, eller fel forward-namn/port i NPM.
WS ansluter inte (UI loggar in men sessioner laddar ej) Websockets Support av i NPM-hosten. Slå på.
Bygget kompilerar node-pty och failar Ska inte hända — Dockerfilen filtrerar bort daemon. Om det sker: kontrollera --filter-raderna.