glam/.opencode/DEPLOYMENT_RULES.md
2025-12-21 00:01:54 +01:00

7.9 KiB

Deployment Rules for AI Agents

Last Updated: 2025-12-19
Status: MANDATORY for all deployment operations


🚨 CRITICAL: Deployment Method

This project uses LOCAL DEPLOYMENT, NOT GitHub Actions.

All deployments are executed from the developer's local machine via SSH/rsync to the Hetzner Cloud server.


🚨 CRITICAL: Monorepo Frontend Structure

This project contains TWO separate frontend applications:

Domain Local Directory Server Path
bronhouder.nl /frontend/ /var/www/glam-frontend/
archief.support /apps/archief-assistent/ /var/www/archief-assistent/

When debugging issues, ALWAYS verify which domain is affected before editing code!


Server Information

Property Value
Provider Hetzner Cloud
Server Name glam-sparql
IP Address 91.98.224.44
SSH User root
Main Frontend Path /var/www/glam-frontend/
Archief Assistent Path /var/www/archief-assistent/
Data Path /mnt/data/

Deployment Script

Location: infrastructure/deploy.sh

Usage

# Deploy frontend only (most common)
./infrastructure/deploy.sh --frontend

# Deploy schema/ontology data only
./infrastructure/deploy.sh --data

# Check server status
./infrastructure/deploy.sh --status

# Deploy everything (infrastructure + data + frontend + reload)
./infrastructure/deploy.sh --all

Options Reference

Option Description
--frontend Build and deploy React frontend
--data Deploy ontology/schema files
--infra Deploy infrastructure via Terraform
--reload Reload data into Oxigraph SPARQL server
--status Check server and service status
--all Execute all deployment steps

Frontend Deployment Process

When --frontend is executed:

  1. Build Step (frontend/ directory):

    npm ci              # Install dependencies
    npm run build       # Vite production build
    
  2. Schema Sync (automated in build):

    # Copies LinkML schemas to public directory
    rsync schemas/20251121/linkml/ → frontend/public/schemas/20251121/linkml/
    
  3. Manifest Generation (automated in build):

    node scripts/generate-schema-manifest.cjs
    # Creates: frontend/public/schemas/20251121/linkml/manifest.json
    
  4. Deploy to Server:

    rsync -avz --progress --delete \
      frontend/dist/ \
      root@91.98.224.44:/var/www/glam-frontend/
    

Archief Assistent Deployment Process

NOTE: The deploy.sh script does NOT handle archief-assistent. Use manual commands.

  1. Build Step (apps/archief-assistent/ directory):

    cd apps/archief-assistent
    npm ci              # Install dependencies
    npm run build       # Vite production build
    
  2. Deploy to Server:

    rsync -avz --progress --delete \
      dist/ \
      root@91.98.224.44:/var/www/archief-assistent/
    

Quick One-Liner

cd apps/archief-assistent && npm run build && rsync -avz --delete dist/ root@91.98.224.44:/var/www/archief-assistent/

Prerequisites

Environment Variables

Required in .env file at project root:

# Hetzner Cloud API Token (required for all deployments)
HETZNER_HC_API_TOKEN=your_token_here

# Optional - domain configuration
GLAM_DOMAIN=sparql.glam-ontology.org
ADMIN_EMAIL=admin@glam-ontology.org

SSH Access

  • SSH key must be added to Hetzner server
  • Test connection: ssh root@91.98.224.44 "echo connected"

Local Dependencies

  • rsync (file synchronization)
  • jq (JSON parsing for status checks)
  • npm (for frontend builds)
  • terraform (only for --infra option)

Common Deployment Scenarios

1. After Frontend Code Changes (bronhouder.nl)

./infrastructure/deploy.sh --frontend

What happens:

  • Builds React app with Vite
  • Syncs LinkML schemas to public directory
  • Generates schema manifest
  • Deploys to /var/www/glam-frontend/

2. After Archief Assistent Changes (archief.support)

cd apps/archief-assistent && npm run build && rsync -avz --delete dist/ root@91.98.224.44:/var/www/archief-assistent/

What happens:

  • Builds React app with Vite
  • Deploys to /var/www/archief-assistent/

3. After Schema Changes

./infrastructure/deploy.sh --data --reload

What happens:

  • Syncs ontology files (.ttl, .rdf, .owl, .jsonld)
  • Syncs RDF schemas
  • Syncs LinkML schemas
  • Syncs UML diagrams (.mmd)
  • Reloads Oxigraph with new data

4. Full Deployment

./infrastructure/deploy.sh --all

Use sparingly - this runs Terraform and may modify infrastructure.

5. Verify Deployment

./infrastructure/deploy.sh --status

Shows:

  • Server status (IP, type, location)
  • Service status (Oxigraph, Caddy)
  • SPARQL triple count

AI Agent Deployment Rules

DO

  • Use ./infrastructure/deploy.sh --frontend after bronhouder.nl frontend changes
  • Use manual rsync for archief.support changes (see Archief Assistent Deployment section)
  • Identify which domain is affected BEFORE editing code
  • Verify build succeeds locally before deploying
  • Run --status to confirm deployment success
  • Document what was deployed in session summary

DO NOT

  • Push to main branch expecting CI/CD (there is none)
  • Manually rsync without using the deploy script (for main frontend)
  • Modify server files directly via SSH
  • Use --all without explicit user confirmation
  • Deploy without testing locally first
  • Edit /frontend/ when issue is on archief.support
  • Edit /apps/archief-assistent/ when issue is on bronhouder.nl
  • Deploy to wrong server path

Troubleshooting

Build Fails

cd frontend
rm -rf node_modules
npm ci
npm run build

SSH Connection Refused

# Check server is running
./infrastructure/deploy.sh --status

# Test SSH directly
ssh -o ConnectTimeout=5 root@91.98.224.44 "echo connected"

Schema Manifest Missing

cd frontend
node scripts/generate-schema-manifest.cjs
# Should create: public/schemas/20251121/linkml/manifest.json

Deployment Stuck

# Check if rsync is running
ps aux | grep rsync

# Force kill and retry
pkill rsync
./infrastructure/deploy.sh --frontend

Post-Deployment Verification

After any deployment, verify:

  1. Server Status:

    ./infrastructure/deploy.sh --status
    
  2. Main Frontend Accessible (bronhouder.nl):

    • Open http://91.98.224.44 in browser
    • Check browser console for errors
  3. Archief Assistent Accessible (archief.support):

    • Open https://archief.support in browser
    • Test map page: https://archief.support/map
    • Check browser console for errors (ignore MapLibre GL warnings)
  4. SPARQL Endpoint (if --data deployed):

    curl -X POST -H "Content-Type: application/sparql-query" \
      -d "SELECT (COUNT(*) AS ?c) WHERE { ?s ?p ?o }" \
      http://91.98.224.44:7878/query
    

Harmless Console Warnings

These warnings can be ignored (MapLibre GL cosmetic issues):

Warning Cause
Error in parsing value for 'user-select'. Declaration dropped. MapLibre CSS parsing
WebGL warning: texImage: Alpha-premult and y-flip are deprecated WebGL deprecation notice

  • Monorepo Frontend Apps: .opencode/MONOREPO_FRONTEND_APPS.md
  • Full Deployment Guide: docs/DEPLOYMENT_GUIDE.md
  • Infrastructure Setup: infrastructure/README.md
  • Terraform Config: infrastructure/terraform/
  • Server Scripts: infrastructure/scripts/

Version History

Date Change
2025-12-19 Added monorepo structure, archief-assistent deployment, harmless warnings
2025-12-01 Initial documentation