Haystack Deploy Runbook
Hosting (2026-06-04): Dev: Railway today (managed via
rag/railway.toml). Staging/Prod: AWS ECS Fargate via thehumanwork-ragservice. Cutover via #1455 (Railway-only) was reverted; #1527 (humanwork-ragECS service + RAGFlow cleanup ininfra/terraform/) + #1541 (rag-deploy.ymlworkflow) establishes ECS as canonical for staging/prod. Cloud Map service URL:humanwork-rag.humanwork.internal:1416. See ADR-024, ADR-025, ADR-026.
Railway (dev)โ
Railway autodeploys from the dev branch on push, per rag/railway.toml. Private networking only โ humanwork-rag.railway.internal:1416. No public ingress.
ECS Fargate (staging + prod)โ
Staging and prod humanwork-rag run on ECS Fargate in the shared humanwork cluster, registered in Cloud Map at humanwork-rag.humanwork.internal:1416. Terraform source of truth: infra/terraform/modules/stack/main.tf (sets rag_internal_url = "http://humanwork-rag.${local.cloud_map_namespace}:1416").
Deploys are automatic on merge โ .github/workflows/rag-deploy.yml triggers on pushes to staging and main that touch rag/** (mirroring the API and Agent pipelines):
- Push to
staging(touchingrag/**) โ auto-deploy to staging. - Push to
main(touchingrag/**) โ auto-deploy to production. devtargets Railway (see below) and is ignored by the ECS pipeline.
Manual override is still available via workflow_dispatch:
- GitHub โ Actions โ Deploy Rag โ Run workflow.
- Select
environment: stagingorenvironment: prod. - Optionally pin an image tag (defaults to
sha-<short>from the chosen branch). - Workflow renders the task-def,
aws ecs update-service, waits for stability, runs the smoke check below.
Container health check (per #1586): curl -fsS http://localhost:1416/status from the task definition.
Downstream callers (notably humanwork-api) must send X-API-Key: $HAYSTACK_API_KEY (#1588) โ not Authorization: Bearer.
Schema bootstrapโ
Run:
cd api && npm run migrations:run
This applies the CreateHaystackSchema migration (api/migrations/1780500000001-CreateHaystackSchema.ts).
Per ADR-027, humanwork-api ECS task definitions opt into RUN_MIGRATIONS_ON_BOOT=true on first prod boot. Manual migrations:run is only needed for out-of-band application.
OpenRouter smoke testโ
Run this against a known org with seed data:
curl -X POST $HAYHOOKS_URL/retrieval/run \
-H "X-API-Key: $HAYSTACK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "...", "org_id": "<seed-org>"}'
Expect HTTP 200 and a non-empty results array.
For staging/prod, HAYHOOKS_URL is http://humanwork-rag.humanwork.internal:1416 (reachable only from inside the VPC โ exec into an ECS task or use the bastion).
Rollback procedureโ
ECS (staging + prod)โ
Roll back to the previous task-def revision:
# Find the previous revision
aws ecs describe-task-definition --task-definition humanwork-rag-<env> --query 'taskDefinition.revision'
# Update the service to the previous revision
aws ecs update-service \
--cluster humanwork-<env> \
--service humanwork-rag \
--task-definition humanwork-rag-<env>:<prev-rev>
Wait for aws ecs wait services-stable. Mirrors the rollback section in incident-response.md.
Railway (dev only)โ
Railway keeps prior deployments. Roll back with the Railway UI by selecting the previous deployment and choosing rollback.
To roll back from the CLI, first find the deployment ID to restore:
railway deployment list
Then redeploy that specific deployment:
railway deployment redeploy <previous-deployment-id>
Relatedโ
- ADR-024 Haystack Migration
- ADR-025 pgvector Document Store
- ADR-026 OpenRouter for Embed/Chat/Rerank
- ADR-027 TypeORM Migrations Only
- humanwork-rag-deploys.md
- kb-pause-reactivate.md
- haystack-eval-bakeoff.md
- PRs: #1527 (ECS service + RAGFlow cleanup), #1541 (
rag-deploy.yml), #1586 (curl health check), #1588 (X-API-Key).