#cloud-config # ------------------------------------------------------------------ # Deploy-time cloud-init for Vultr Marketplace # # The snapshot already has Hermes Agent, Docker, Caddy, ttyd, code-server # installed. This script: # 1. Fetches per-instance metadata from the Vultr metadata service # 2. Configures Hermes Agent with Vultr Inference provider # 3. Configures code-server with password # 4. Starts ttyd and code-server services # 5. Configures Caddy as a TLS reverse proxy # - / → ttyd (Hermes terminal) # - /code/* → code-server # ------------------------------------------------------------------ runcmd: # ── Fetch Vultr metadata and persist ── - | APP_PASSWORD=$(curl -sf -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-password) APP_INF_API_KEY=$(curl -sf -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-inf_api_key) APP_DOMAIN=$(curl -sf -H "METADATA-TOKEN: vultr" http://169.254.169.254/v1/internal/app-domain) printf 'APP_PASSWORD="%s"\nAPP_INF_API_KEY="%s"\nAPP_DOMAIN="%s"\n' \ "$APP_PASSWORD" "$APP_INF_API_KEY" "$APP_DOMAIN" \ > /etc/hermes-deploy.env chmod 600 /etc/hermes-deploy.env # ── Configure Hermes Agent with Vultr Inference provider ── - | . /etc/hermes-deploy.env # Create .env with API keys cat > /home/hermes/.hermes/.env << ENV_EOF # ============================================================================= # VULTR INFERENCE PROVIDER (Pre-configured) # ============================================================================= VULTR_API_KEY=${APP_INF_API_KEY} VULTR_BASE_URL=https://api.vultrinference.com/v1 # For OpenAI-compatible custom endpoint mode: OPENAI_API_KEY=${APP_INF_API_KEY} OPENAI_BASE_URL=https://api.vultrinference.com/v1 ENV_EOF chown hermes:hermes /home/hermes/.hermes/.env chmod 600 /home/hermes/.hermes/.env # Create config.yaml cat > /home/hermes/.hermes/config.yaml << 'CONFIG_EOF' # Hermes Agent Configuration - Vultr Inference # ============================================================================= # Pre-configured for Vultr Inference API (OpenAI-compatible) model: # Default model (GLM-5-FP8 - 200K context, reasoning-capable) default: "zai-org/GLM-5-FP8" # Use custom provider for Vultr Inference (OpenAI-compatible) provider: "custom" base_url: "https://api.vultrinference.com/v1" # api_key will be substituted from .env # Terminal backend (local execution) terminal: backend: "local" cwd: "." timeout: 180 lifetime_seconds: 300 # Enable persistent memory memory: memory_enabled: true user_profile_enabled: true memory_char_limit: 2200 user_char_limit: 1375 nudge_interval: 10 # Context compression for long conversations compression: enabled: true threshold: 0.50 target_ratio: 0.20 protect_last_n: 20 summary_model: "zai-org/GLM-5-FP8" # Agent settings agent: max_turns: 60 verbose: false reasoning_effort: "medium" # Toolsets for CLI platform_toolsets: cli: [hermes-cli] # Display settings display: compact: false tool_progress: all streaming: true CONFIG_EOF chown hermes:hermes /home/hermes/.hermes/config.yaml chmod 600 /home/hermes/.hermes/config.yaml # ── Configure and start code-server ── - | . /etc/hermes-deploy.env cat > /home/hermes/.config/code-server/config.yaml << CSCFG bind-addr: 127.0.0.1:8080 auth: password password: ${APP_PASSWORD} cert: false CSCFG chown hermes:hermes /home/hermes/.config/code-server/config.yaml chmod 600 /home/hermes/.config/code-server/config.yaml # ── Start ttyd and code-server services ── - systemctl enable ttyd-hermes code-server-hermes - systemctl start ttyd-hermes code-server-hermes # ── Write Caddyfile ── # ttyd at root, code-server at /code/ # ZeroSSL primary (avoids LE rate limits), Let's Encrypt fallback - | . /etc/hermes-deploy.env HASHED=$(caddy hash-password --plaintext "$APP_PASSWORD") cat > /etc/caddy/Caddyfile << CADDY ${APP_DOMAIN} { tls { issuer acme { dir https://acme.zerossl.com/v2/DV90 eab ur6CkPWFhPtp8af1SASQEA dRKaIDk9u4tn7MYrHNczzl_tnKSJ8Hipb2IFVui3oxEHCj_3wkGBA-zG93X7NXaROh-pzDJOugrtn1nxxGasxw } issuer acme { dir https://acme-v02.api.letsencrypt.org/directory } } basic_auth { hermes ${HASHED} } # code-server at /code/ handle_path /code/* { reverse_proxy 127.0.0.1:8080 } # Default: Hermes terminal (ttyd) at root handle { reverse_proxy 127.0.0.1:7681 } } CADDY # ── Start Caddy and wait for cert issuance ── # ZeroSSL can take 30-60s; wait up to 90s for cert before proceeding - systemctl enable caddy - systemctl restart caddy - | echo "Waiting for TLS certificate issuance (up to 90s)..." for i in $(seq 1 90); do if find /var/lib/caddy -name '*.crt' 2>/dev/null | grep -q .; then echo "Certificate obtained!" break fi sleep 1 done # ── Clean up secrets from disk ── - rm -f /etc/hermes-deploy.env