Files
docs/services/arcane.md
T
fkrebs 0d83f83bc0 docs: MCP gateway git/gitlab/paper-search; CT 109 plan; new backrest/db/arcane docs
- mcp-gateway.md: 26 servers (added git, gitlab, paper-search catalog bridge);
  document --pass-environment requirement for env var passthrough in DinD bridges
- ct-inventory.md + homelab-architecture.md: CT 109 IP conflict, CT 113 live
- proxmox-state.md §16: Loki, sshwifty, Alloy, IP conflict note, sidecar table
  expanded to CT 103/111/113; build order updated
- infra/portmap.md: CT 113 db section; QNAP TS-251D (Klipper/Mainsail)
- services/backrest.md: full backup strategy doc (new)
- services/databases.md: CT 113 postgres/WAL-G/pgAdmin doc (new)
- services/arcane.md: Docker management IDE doc (new)
- CHANGELOG.md: 2026-05-22 entry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 09:35:07 +02:00

4.6 KiB

Arcane

Web-based Docker management IDE. Main instance on CT 104 (192.168.1.40:10002, arcane.nuclide.systems). Manages containers on the local Docker host plus remote CTs via edge agents.

Stack: /opt/stacks/arcane/docker-compose.yml on CT 104. Image: ghcr.io/getarcaneapp/arcane:latest Auth: OIDC via Pocket ID, admin: fkrebs@nucli.de


Edge agents

An edge agent (ghcr.io/getarcaneapp/arcane-headless:latest) runs inside each remote CT and connects outbound to the main Arcane server via gRPC poll. The main server then manages that CT's Docker.

Currently deployed agents

CT Hostname Compose path Status
CT 104 docker (built-in NUC environment) online
CT 113 db /opt/stacks/db/docker-compose.yml online (2026-05-21)

Adding an edge agent to a new CT

Step 1 — Create the environment in Arcane (requires Arcane API or UI access)

With the admin CLI API key (stored in Arcane DB, regenerate if needed):

# Get or create an admin API key — see "Admin API key" section below
API_KEY="arc_..."
curl -s -X POST -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" \
  "http://192.168.1.40:10002/api/environments" \
  -d '{"name":"<ctname>","apiUrl":"edge://<ctname>","isEdge":true}'
# Note the environment id from the response

Step 2 — Generate and wire the AGENT_TOKEN

Arcane stores the raw AGENT_TOKEN in environments.access_token. Insert it via:

# On PVE host, run: python3 /tmp/arcane-bootstrap.py
import argon2, secrets, sqlite3, uuid
from datetime import datetime, timezone

db_path = "/rpool/data/subvol-104-disk-0/opt/stacks/arcane/data/arcane.db"
env_id  = "<id from step 1>"          # paste the environment UUID here

conn = sqlite3.connect(db_path)
raw_token = "arc_" + secrets.token_hex(32)
key_prefix = "arc_" + raw_token[4:12]
ph = argon2.PasswordHasher(memory_cost=65536, time_cost=3, parallelism=2)
key_hash = ph.hash(raw_token)
key_id = str(uuid.uuid4())
now = datetime.now(timezone.utc).isoformat()

conn.execute(
    "INSERT INTO api_keys (id, name, description, key_hash, key_prefix, environment_id, managed_by, created_at, updated_at)"
    " VALUES (?,?,?,?,?,?,?,?,?)",
    (key_id, f"Environment Bootstrap Key - {env_id[:8]}",
     "Auto-generated key for environment pairing",
     key_hash, key_prefix, env_id, "system", now, now))
conn.execute("UPDATE environments SET access_token=? WHERE id=?", (raw_token, env_id))
conn.commit()
conn.close()
print("AGENT_TOKEN:", raw_token)

Step 3 — Add the agent to the CT's compose

  arcane-agent:
    image: ghcr.io/getarcaneapp/arcane-headless:latest
    container_name: arcane-agent
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./arcane-agent:/app/data
    environment:
      EDGE_AGENT: "true"
      EDGE_TRANSPORT: poll
      AGENT_TOKEN: ${ARCANE_AGENT_TOKEN}
      MANAGER_API_URL: http://192.168.1.40:10002
    deploy:
      resources:
        limits:
          cpus: "0.5"
          memory: 256M

Add ARCANE_AGENT_TOKEN=<raw_token> to the CT's .env.

Step 4 — Start and verify

docker compose up -d arcane-agent
docker logs arcane-agent 2>&1 | grep "Edge gRPC tunnel"
# Expected: Edge gRPC tunnel connected to manager  environment_id=<uuid>

The environment should flip to online in environments.status within ~5 seconds.


When Arcane moves to CT 109

When Arcane migrates from CT 104 to CT 109 (the planned "observe" LXC):

  1. Update MANAGER_API_URL in every edge agent's .env to the new CT 109 LAN IP
  2. Update the Arcane compose APP_URL and network bindings
  3. Update Zoraxy route for arcane.nuclide.systems to point to CT 109
  4. Migrate the SQLite DB: cp -a /opt/stacks/arcane/data/ <ct109-path>/
  5. Regenerate the admin API key (stored in memory, not config) since the DB port changes
  6. Restart all edge agents with the new MANAGER_API_URL

Arcane environments (NUC, db, shepard) will reconnect automatically once MANAGER_API_URL is updated.


Admin API key (non-OIDC access)

Arcane doesn't store plaintext API keys — use the DB-insert method above when a new admin key is needed. The python3-argon2 package must be installed on the PVE host (apt install python3-argon2).

The key inserted for CLI use during CT 113 provisioning (arc_a9695182...) is linked to fkrebs user in the api_keys table. Rotate it after provisioning work is complete by deleting the row:

sqlite3 /rpool/data/subvol-104-disk-0/opt/stacks/arcane/data/arcane.db \
  "DELETE FROM api_keys WHERE name='admin-cli';"