{
  "manifest_version": "1.0.0",
  "template": {
    "id": "2b753d8b-b7a8-4eaa-a381-0c44d3de52d8",
    "slug": "helix-foundry-01-ontology-and-knowledge-",
    "name": "Helix Foundry Ontology and Knowledge Graph from Your Data",
    "description": "Connect databases and documents; an AI agent maps them into one graph.",
    "url": "https://railway.com/deploy/helix-foundry-01-ontology-and-knowledge-",
    "upstream": {
      "repo_url": "https://github.com/baranberkay96/helix-foundry-railway"
    }
  },
  "status": "unvalidated",
  "validated_at": null,
  "success_rate_30d": null,
  "services": [
    {
      "name": "Site",
      "source": {
        "repo": "https://github.com/baranberkay96/helix-foundry-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "HelixDB",
      "source": {
        "image": "ghcr.io/helixdb/helixdb:v0.0.14@sha256:1470a3bce07866367f1d2a5b250ec9c3244d62356ac27d537023ef5492a8f62a"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/helix",
      "http": false
    },
    {
      "name": "Acme DB",
      "source": {
        "repo": "https://github.com/baranberkay96/helix-foundry-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    },
    {
      "name": "Foundry",
      "source": {
        "repo": "https://github.com/baranberkay96/helix-foundry-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/work",
      "http": false
    },
    {
      "name": "MySQL",
      "source": {
        "image": "mysql:8.0.46@sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/mysql",
      "http": false
    },
    {
      "name": "Storage",
      "source": {
        "repo": "https://github.com/baranberkay96/helix-foundry-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": true
    },
    {
      "name": "Gateway",
      "source": {
        "repo": "https://github.com/baranberkay96/helix-foundry-railway"
      },
      "needs_volume": false,
      "http": true
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "Site",
      "description": "Port the web app listens on (healthcheck).",
      "secret": false,
      "strategy": "default",
      "default": "3000"
    },
    {
      "key": "HOSTNAME",
      "service": "Site",
      "description": "Bind address of the Next.js server (:: = IPv4 and IPv6 on the private network).",
      "secret": false,
      "strategy": "default",
      "default": "::"
    },
    {
      "key": "FOUNDRY_ORIGIN",
      "service": "Site",
      "description": "The origin the web app believes it is served at. Keep it: the local build accepts only loopback origins, and the Gateway presents every request as localhost:3000.",
      "secret": false,
      "strategy": "default",
      "default": "http://localhost:3000"
    },
    {
      "key": "HELIX_WFE_ORIGIN",
      "service": "Site",
      "description": "Foundry API on the private network; the web app's /papi forwards to it with the owner token.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FOUNDRY_SITE_IMAGE",
      "service": "Site",
      "description": "Foundry web app image this service's Docker build starts FROM (HelixDB's release image, unchanged). Upgrade it together with FOUNDRY_IMAGE and FOUNDRY_AGENT_IMAGE on Foundry.",
      "secret": false,
      "strategy": "default",
      "default": "ghcr.io/helixdb/foundry-site:0.1.3@sha256:ac69e52df43e99b5c49879399f1f20f475a8fcdf7f43e66f27ca6b6b11da74ae"
    },
    {
      "key": "FOUNDRY_LOCAL_TOKEN",
      "service": "Site",
      "description": "Owner token the web app sends to Foundry (set on Foundry).",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "FOUNDRY_SAMPLE_DB_HOST",
      "service": "Site",
      "description": "Host that Use the sample connects to (the Acme DB service), written into the web app at start in place of upstream's acme-db.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "NEXT_TELEMETRY_DISABLED",
      "service": "Site",
      "description": "No Next.js telemetry.",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Site",
      "description": "Seconds between SIGTERM and SIGKILL on redeploy.",
      "secret": false,
      "strategy": "default",
      "default": "15"
    },
    {
      "key": "PORT",
      "service": "HelixDB",
      "description": "Port Railway health-checks (HelixDB's HTTP API).",
      "secret": false,
      "strategy": "default",
      "default": "8080"
    },
    {
      "key": "HELIX_DATA_DIR",
      "service": "HelixDB",
      "description": "Where HelixDB keeps its database (the volume).",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/helix"
    },
    {
      "key": "HELIX_HTTP_ADDR",
      "service": "HelixDB",
      "description": "HelixDB's HTTP listener (IPv4 and IPv6 on the private network). It checks no key: never add a public domain or TCP proxy.",
      "secret": false,
      "strategy": "default",
      "default": "[::]:8080"
    },
    {
      "key": "RAILWAY_RUN_UID",
      "service": "HelixDB",
      "description": "Run as root so HelixDB can write the root-owned Railway volume (the image's user is 65532 and has no shell to change it).",
      "secret": false,
      "strategy": "default",
      "default": "0"
    },
    {
      "key": "HELIX_TELEMETRY_LEVEL",
      "service": "HelixDB",
      "description": "No telemetry, as upstream's compose file runs it.",
      "secret": false,
      "strategy": "default",
      "default": "off"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "HelixDB",
      "description": "Time HelixDB gets to drain and close its storage on redeploy.",
      "secret": false,
      "strategy": "default",
      "default": "30"
    },
    {
      "key": "PGDATA",
      "service": "Acme DB",
      "description": "Location where the database will be initialized.",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "PGHOST",
      "service": "Acme DB",
      "description": "Railway Private Domain Name (the Site writes it into Use the sample).",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGPORT",
      "service": "Acme DB",
      "description": "Port to connect to Postgres (the sample expects 5432).",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "PGUSER",
      "service": "Acme DB",
      "description": "Required variable for Data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGDATABASE",
      "service": "Acme DB",
      "description": "Required variable for the data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGPASSWORD",
      "service": "Acme DB",
      "description": "Required variable for Data panel.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "POSTGRES_DB",
      "service": "Acme DB",
      "description": "Database holding Acme Corp's sample tables. Keep acme: Foundry's Use the sample connects to it by that name.",
      "secret": false,
      "strategy": "default",
      "default": "acme"
    },
    {
      "key": "DATABASE_URL",
      "service": "Acme DB",
      "description": "Superuser connection string (private network).",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "ACME_DB_IMAGE",
      "service": "Acme DB",
      "description": "Railway Postgres image this service's Docker build starts FROM.",
      "secret": false,
      "strategy": "default",
      "default": "ghcr.io/railwayapp-templates/postgres-ssl:18@sha256:4fc833b43d2aaf6ecc9b18615f5533602b723a32d0e2efe2dae8ca0f7217c863"
    },
    {
      "key": "POSTGRES_USER",
      "service": "Acme DB",
      "description": "Superuser created on first boot.",
      "secret": false,
      "strategy": "default",
      "default": "postgres"
    },
    {
      "key": "SSL_CERT_DAYS",
      "service": "Acme DB",
      "description": "SSL certificate expiry in days.",
      "secret": false,
      "strategy": "default",
      "default": "820"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "Acme DB",
      "description": "Superuser password, generated at deploy. Foundry uses the read-only login acme_reader instead (password acme, built into the web app; made-up data, private network only).",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Acme DB",
      "description": "Allow Postgres to cleanly shut down.",
      "secret": false,
      "strategy": "default",
      "default": "30"
    },
    {
      "key": "PORT",
      "service": "Foundry",
      "description": "Port of Foundry's health listener, which Railway health-checks (/readyz). The API listens on 8081 (private).",
      "secret": false,
      "strategy": "default",
      "default": "8083"
    },
    {
      "key": "HELIX_DB_DSN",
      "service": "Foundry",
      "description": "Foundry's MySQL database (Go DSN). Foundry migrates it at every start.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "FOUNDRY_IMAGE",
      "service": "Foundry",
      "description": "Foundry backend image the foundry binary and its config are copied from at build (HelixDB's release, unchanged).",
      "secret": false,
      "strategy": "default",
      "default": "ghcr.io/helixdb/foundry:0.1.2@sha256:5adf4ca93c2b53661275ff3b9a4c5054d8ee42acfa569c4dcbfd2c8b6b27ba62"
    },
    {
      "key": "FOUNDRY_S3_SECRET",
      "service": "Foundry",
      "description": "Secret of the store's foundry identity (set on Storage).",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "FOUNDRY_AGENT_IMAGE",
      "service": "Foundry",
      "description": "Ontology agent image this service's Docker build starts FROM (HelixDB's release, unchanged).",
      "secret": false,
      "strategy": "default",
      "default": "ghcr.io/helixdb/ontology-agent:0.1.1@sha256:d5a543bee8d9f403fa898ad5773b9a3d95b394f31396b36ec2b13448af07faa8"
    },
    {
      "key": "FOUNDRY_LOCAL_TOKEN",
      "service": "Foundry",
      "description": "Owner token, generated at deploy: the web app sends it to Foundry, and MCP clients send it as Authorization: Bearer. Whoever has it controls this install; at least 32 characters.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "FOUNDRY_WORK_MAX_GB",
      "service": "Foundry",
      "description": "GiB of snapshots one draft or one load may unpack into the /work volume (upstream: 6). Keep two of them below the volume size.",
      "secret": false,
      "strategy": "default",
      "default": "2"
    },
    {
      "key": "FOUNDRY_CONNECTOR_KEY",
      "service": "Foundry",
      "description": "Key that seals every database password and API key given to Foundry, generated at deploy. Never change it: credentials sealed with it become unreadable. Back it up with your data.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "HELIX_LOCAL__HELIX_URL",
      "service": "Foundry",
      "description": "HelixDB on the private network: every ontology's loads share it.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HELIX_LOCAL__SITE_ORIGIN",
      "service": "Foundry",
      "description": "Public URL of Foundry (the Gateway): links given to agents start here, and MCP and HTTP Ask answer only for this host. Change it when you add a custom domain.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "HELIX_LOCAL__S3__ENDPOINT",
      "service": "Foundry",
      "description": "The S3 store's public URL. Browsers upload documents to URLs Foundry signs for it, so Foundry uses the same public address.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "FOUNDRY_STARTUP_WAIT_SECONDS",
      "service": "Foundry",
      "description": "Seconds the start waits for MySQL and the store before starting Foundry anyway (keep it below the healthcheck timeout).",
      "secret": false,
      "strategy": "default",
      "default": "600"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Foundry",
      "description": "Seconds between SIGTERM and SIGKILL on redeploy: a load or question in flight finishes or is handed back (the agent drains for 100 s).",
      "secret": false,
      "strategy": "default",
      "default": "120"
    },
    {
      "key": "MYSQLHOST",
      "service": "MySQL",
      "description": "Railway Private Domain Name.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MYSQLPORT",
      "service": "MySQL",
      "description": "MySQL port.",
      "secret": false,
      "strategy": "default",
      "default": "3306"
    },
    {
      "key": "MYSQLUSER",
      "service": "MySQL",
      "description": "MySQL user, used for the Data panel.",
      "secret": false,
      "strategy": "default",
      "default": "root"
    },
    {
      "key": "MYSQL_URL",
      "service": "MySQL",
      "description": "URL to connect to MySQL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MYSQLDATABASE",
      "service": "MySQL",
      "description": "Default database, used for Data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MYSQLPASSWORD",
      "service": "MySQL",
      "description": "Root password, used for Data panel.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MYSQL_DATABASE",
      "service": "MySQL",
      "description": "Database to be created on image startup (Foundry's tables).",
      "secret": false,
      "strategy": "default",
      "default": "railway"
    },
    {
      "key": "MYSQL_ROOT_PASSWORD",
      "service": "MySQL",
      "description": "Root password for MySQL DB, generated at deploy (letters only: it sits in Foundry's DSN unescaped).",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "MySQL",
      "description": "Time MySQL gets to shut down cleanly on redeploy.",
      "secret": false,
      "strategy": "default",
      "default": "30"
    },
    {
      "key": "PORT",
      "service": "Storage",
      "description": "Port of the S3 API (public domain target and healthcheck).",
      "secret": false,
      "strategy": "default",
      "default": "8333"
    },
    {
      "key": "FOUNDRY_S3_SECRET",
      "service": "Storage",
      "description": "Secret of the store's one S3 identity, foundry, generated at deploy. Foundry references it.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "FOUNDRY_STORAGE_IMAGE",
      "service": "Storage",
      "description": "SeaweedFS image this service's Docker build starts FROM (the version upstream's compose file pins).",
      "secret": false,
      "strategy": "default",
      "default": "chrislusf/seaweedfs:4.47@sha256:ce9e796f1fe6f06968f4c04bdaf8f678dad9c8acdfef3d244133d71bfa6bf882"
    },
    {
      "key": "STORAGE_VOLUME_SIZE_MB",
      "service": "Storage",
      "description": "Size of each SeaweedFS volume file. Small files fit a 5 GB Railway volume; raise it on large volumes.",
      "secret": false,
      "strategy": "default",
      "default": "256"
    },
    {
      "key": "STORAGE_ALLOWED_ORIGINS",
      "service": "Storage",
      "description": "Comma-separated origins whose pages may upload (CORS). Add your custom domain here if you give the Gateway one.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Storage",
      "description": "Time SeaweedFS gets to stop cleanly on redeploy (it takes about 20 s).",
      "secret": false,
      "strategy": "default",
      "default": "60"
    },
    {
      "key": "PORT",
      "service": "Gateway",
      "description": "Port the gateway listens on (public domain target and healthcheck).",
      "secret": false,
      "strategy": "default",
      "default": "8080"
    },
    {
      "key": "BASIC_AUTH_PASSWORD",
      "service": "Gateway",
      "description": "Password for the browser's sign-in prompt, generated at deploy. Foundry has no sign-in of its own, so this protects the whole install; at least 12 characters or the gateway refuses to start.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "BASIC_AUTH_USERNAME",
      "service": "Gateway",
      "description": "User name for the browser's sign-in prompt. Letters, digits and . _ @ - (anything else falls back to admin).",
      "secret": false,
      "strategy": "default",
      "default": "admin"
    },
    {
      "key": "FOUNDRY_API_UPSTREAM",
      "service": "Gateway",
      "description": "Foundry API (MCP and HTTP Ask) on the private network.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FOUNDRY_GATEWAY_IMAGE",
      "service": "Gateway",
      "description": "Caddy image this service's Docker build starts FROM (Railway passes it as a build argument).",
      "secret": false,
      "strategy": "default",
      "default": "caddy:2.11.9-alpine@sha256:0bbb055bda6793c999bde78b1b5ce3e89f829fb031af2cf50056ea1246559fee"
    },
    {
      "key": "FOUNDRY_SITE_UPSTREAM",
      "service": "Gateway",
      "description": "Foundry web app on the private network.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FOUNDRY_AGENT_ENDPOINTS",
      "service": "Gateway",
      "description": "on: /mcp and /v1/ontologies/... go straight to Foundry, which requires FOUNDRY_LOCAL_TOKEN as a bearer token (for Claude Code, Cursor and other MCP clients). off: they stay behind the password like the rest.",
      "secret": false,
      "strategy": "default",
      "default": "on"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Gateway",
      "description": "Seconds between SIGTERM and SIGKILL on redeploy.",
      "secret": false,
      "strategy": "default",
      "default": "15"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "helix-foundry-01-ontology-and-knowledge-"
      }
    },
    "cli": "railway deploy --template helix-foundry-01-ontology-and-knowledge-",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "2b753d8b-b7a8-4eaa-a381-0c44d3de52d8",
            "serializedConfig": {
              "buckets": {},
              "services": {
                "33b259fe-a4d9-594f-b025-bf25e415a6a4": {
                  "icon": "https://cdn.jsdelivr.net/npm/lucide-static@1.59.0/icons/app-window.svg",
                  "name": "Site",
                  "build": {
                    "builder": "DOCKERFILE"
                  },
                  "deploy": {
                    "healthcheckPath": "/ask",
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 300
                  },
                  "source": {
                    "repo": "baranberkay96/helix-foundry-railway",
                    "branch": "main",
                    "rootDirectory": "/services/site"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": true,
                      "description": "Port the web app listens on (healthcheck).",
                      "defaultValue": "3000"
                    },
                    "HOSTNAME": {
                      "isOptional": true,
                      "description": "Bind address of the Next.js server (:: = IPv4 and IPv6 on the private network).",
                      "defaultValue": "::"
                    },
                    "FOUNDRY_ORIGIN": {
                      "isOptional": true,
                      "description": "The origin the web app believes it is served at. Keep it: the local build accepts only loopback origins, and the Gateway presents every request as localhost:3000.",
                      "defaultValue": "http://localhost:3000"
                    },
                    "HELIX_WFE_ORIGIN": {
                      "isOptional": true,
                      "description": "Foundry API on the private network; the web app's /papi forwards to it with the owner token.",
                      "defaultValue": "http://${{Foundry.RAILWAY_PRIVATE_DOMAIN}}:8081"
                    },
                    "FOUNDRY_SITE_IMAGE": {
                      "isOptional": true,
                      "description": "Foundry web app image this service's Docker build starts FROM (HelixDB's release image, unchanged). Upgrade it together with FOUNDRY_IMAGE and FOUNDRY_AGENT_IMAGE on Foundry.",
                      "defaultValue": "ghcr.io/helixdb/foundry-site:0.1.3@sha256:ac69e52df43e99b5c49879399f1f20f475a8fcdf7f43e66f27ca6b6b11da74ae"
                    },
                    "FOUNDRY_LOCAL_TOKEN": {
                      "isOptional": true,
                      "description": "Owner token the web app sends to Foundry (set on Foundry).",
                      "defaultValue": "${{Foundry.FOUNDRY_LOCAL_TOKEN}}"
                    },
                    "FOUNDRY_SAMPLE_DB_HOST": {
                      "isOptional": true,
                      "description": "Host that Use the sample connects to (the Acme DB service), written into the web app at start in place of upstream's acme-db.",
                      "defaultValue": "${{Acme DB.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "NEXT_TELEMETRY_DISABLED": {
                      "isOptional": true,
                      "description": "No Next.js telemetry.",
                      "defaultValue": "1"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Seconds between SIGTERM and SIGKILL on redeploy.",
                      "defaultValue": "15"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {}
                  }
                },
                "34754253-3b54-5f5b-ad14-ca05263b6e9c": {
                  "icon": "https://cdn.jsdelivr.net/npm/lucide-static@1.59.0/icons/share-2.svg",
                  "name": "HelixDB",
                  "deploy": {
                    "healthcheckPath": "/readyz",
                    "restartPolicyType": "ON_FAILURE",
                    "healthcheckTimeout": 300,
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/helixdb/helixdb:v0.0.14@sha256:1470a3bce07866367f1d2a5b250ec9c3244d62356ac27d537023ef5492a8f62a"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": true,
                      "description": "Port Railway health-checks (HelixDB's HTTP API).",
                      "defaultValue": "8080"
                    },
                    "HELIX_DATA_DIR": {
                      "isOptional": true,
                      "description": "Where HelixDB keeps its database (the volume).",
                      "defaultValue": "/var/lib/helix"
                    },
                    "HELIX_HTTP_ADDR": {
                      "isOptional": true,
                      "description": "HelixDB's HTTP listener (IPv4 and IPv6 on the private network). It checks no key: never add a public domain or TCP proxy.",
                      "defaultValue": "[::]:8080"
                    },
                    "RAILWAY_RUN_UID": {
                      "isOptional": true,
                      "description": "Run as root so HelixDB can write the root-owned Railway volume (the image's user is 65532 and has no shell to change it).",
                      "defaultValue": "0"
                    },
                    "HELIX_TELEMETRY_LEVEL": {
                      "isOptional": true,
                      "description": "No telemetry, as upstream's compose file runs it.",
                      "defaultValue": "off"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Time HelixDB gets to drain and close its storage on redeploy.",
                      "defaultValue": "30"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "006d67be-8c33-5402-afcd-15cb973dcefc": {
                      "mountPath": "/var/lib/helix"
                    }
                  }
                },
                "840a50d2-2a0d-5896-ac0a-aee68e3470d5": {
                  "icon": "https://devicons.railway.com/i/postgresql.svg",
                  "name": "Acme DB",
                  "build": {
                    "builder": "DOCKERFILE"
                  },
                  "deploy": {
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "baranberkay96/helix-foundry-railway",
                    "branch": "main",
                    "rootDirectory": "/services/acme-db"
                  },
                  "variables": {
                    "PGDATA": {
                      "isOptional": true,
                      "description": "Location where the database will be initialized.",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "PGHOST": {
                      "isOptional": true,
                      "description": "Railway Private Domain Name (the Site writes it into Use the sample).",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "PGPORT": {
                      "isOptional": true,
                      "description": "Port to connect to Postgres (the sample expects 5432).",
                      "defaultValue": "5432"
                    },
                    "PGUSER": {
                      "isOptional": true,
                      "description": "Required variable for Data panel.",
                      "defaultValue": "${{ POSTGRES_USER }}"
                    },
                    "PGDATABASE": {
                      "isOptional": true,
                      "description": "Required variable for the data panel.",
                      "defaultValue": "${{POSTGRES_DB}}"
                    },
                    "PGPASSWORD": {
                      "isOptional": true,
                      "description": "Required variable for Data panel.",
                      "defaultValue": "${{POSTGRES_PASSWORD}}"
                    },
                    "POSTGRES_DB": {
                      "isOptional": true,
                      "description": "Database holding Acme Corp's sample tables. Keep acme: Foundry's Use the sample connects to it by that name.",
                      "defaultValue": "acme"
                    },
                    "DATABASE_URL": {
                      "isOptional": true,
                      "description": "Superuser connection string (private network).",
                      "defaultValue": "postgresql://${{PGUSER}}:${{POSTGRES_PASSWORD}}@${{RAILWAY_PRIVATE_DOMAIN}}:5432/${{PGDATABASE}}"
                    },
                    "ACME_DB_IMAGE": {
                      "isOptional": true,
                      "description": "Railway Postgres image this service's Docker build starts FROM.",
                      "defaultValue": "ghcr.io/railwayapp-templates/postgres-ssl:18@sha256:4fc833b43d2aaf6ecc9b18615f5533602b723a32d0e2efe2dae8ca0f7217c863"
                    },
                    "POSTGRES_USER": {
                      "isOptional": true,
                      "description": "Superuser created on first boot.",
                      "defaultValue": "postgres"
                    },
                    "SSL_CERT_DAYS": {
                      "isOptional": true,
                      "description": "SSL certificate expiry in days.",
                      "defaultValue": "820"
                    },
                    "POSTGRES_PASSWORD": {
                      "isOptional": true,
                      "description": "Superuser password, generated at deploy. Foundry uses the read-only login acme_reader instead (password acme, built into the web app; made-up data, private network only).",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Allow Postgres to cleanly shut down.",
                      "defaultValue": "30"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "ca0606eb-4bce-56ae-93b3-0eaf91d76063": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                },
                "a4e1d2d5-d58f-5dd1-a22e-b60c33c62d68": {
                  "icon": "https://cdn.jsdelivr.net/npm/lucide-static@1.59.0/icons/workflow.svg",
                  "name": "Foundry",
                  "build": {
                    "builder": "DOCKERFILE"
                  },
                  "deploy": {
                    "healthcheckPath": "/readyz",
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 1200
                  },
                  "source": {
                    "repo": "baranberkay96/helix-foundry-railway",
                    "branch": "main",
                    "rootDirectory": "/services/foundry"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": true,
                      "description": "Port of Foundry's health listener, which Railway health-checks (/readyz). The API listens on 8081 (private).",
                      "defaultValue": "8083"
                    },
                    "HELIX_DB_DSN": {
                      "isOptional": true,
                      "description": "Foundry's MySQL database (Go DSN). Foundry migrates it at every start.",
                      "defaultValue": "root:${{MySQL.MYSQL_ROOT_PASSWORD}}@tcp(${{MySQL.MYSQLHOST}}:${{MySQL.MYSQLPORT}})/${{MySQL.MYSQL_DATABASE}}?parseTime=true&multiStatements=true"
                    },
                    "FOUNDRY_IMAGE": {
                      "isOptional": true,
                      "description": "Foundry backend image the foundry binary and its config are copied from at build (HelixDB's release, unchanged).",
                      "defaultValue": "ghcr.io/helixdb/foundry:0.1.2@sha256:5adf4ca93c2b53661275ff3b9a4c5054d8ee42acfa569c4dcbfd2c8b6b27ba62"
                    },
                    "OPENAI_API_KEY": {
                      "isOptional": true,
                      "description": "Optional. An OpenAI API key, used when ANTHROPIC_API_KEY is empty. Leave empty to choose in Settings > AI models.",
                      "defaultValue": ""
                    },
                    "ANTHROPIC_API_KEY": {
                      "isOptional": true,
                      "description": "Optional. A Claude API key: Foundry then drafts, reads documents and answers with Claude. Leave empty to choose a provider and enter its key in Settings > AI models instead (stored sealed).",
                      "defaultValue": ""
                    },
                    "FOUNDRY_S3_SECRET": {
                      "isOptional": true,
                      "description": "Secret of the store's foundry identity (set on Storage).",
                      "defaultValue": "${{Storage.FOUNDRY_S3_SECRET}}"
                    },
                    "FOUNDRY_AGENT_IMAGE": {
                      "isOptional": true,
                      "description": "Ontology agent image this service's Docker build starts FROM (HelixDB's release, unchanged).",
                      "defaultValue": "ghcr.io/helixdb/ontology-agent:0.1.1@sha256:d5a543bee8d9f403fa898ad5773b9a3d95b394f31396b36ec2b13448af07faa8"
                    },
                    "FOUNDRY_LOCAL_TOKEN": {
                      "isOptional": true,
                      "description": "Owner token, generated at deploy: the web app sends it to Foundry, and MCP clients send it as Authorization: Bearer. Whoever has it controls this install; at least 32 characters.",
                      "defaultValue": "{{FOUNDRY_LOCAL_TOKEN}}"
                    },
                    "FOUNDRY_WORK_MAX_GB": {
                      "isOptional": true,
                      "description": "GiB of snapshots one draft or one load may unpack into the /work volume (upstream: 6). Keep two of them below the volume size.",
                      "defaultValue": "2"
                    },
                    "FOUNDRY_CONNECTOR_KEY": {
                      "isOptional": true,
                      "description": "Key that seals every database password and API key given to Foundry, generated at deploy. Never change it: credentials sealed with it become unreadable. Back it up with your data.",
                      "defaultValue": "{{FOUNDRY_CONNECTOR_KEY}}"
                    },
                    "HELIX_LOCAL__HELIX_URL": {
                      "isOptional": true,
                      "description": "HelixDB on the private network: every ontology's loads share it.",
                      "defaultValue": "http://${{HelixDB.RAILWAY_PRIVATE_DOMAIN}}:8080"
                    },
                    "HELIX_LOCAL__SITE_ORIGIN": {
                      "isOptional": true,
                      "description": "Public URL of Foundry (the Gateway): links given to agents start here, and MCP and HTTP Ask answer only for this host. Change it when you add a custom domain.",
                      "defaultValue": "https://${{Gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "HELIX_LOCAL__S3__ENDPOINT": {
                      "isOptional": true,
                      "description": "The S3 store's public URL. Browsers upload documents to URLs Foundry signs for it, so Foundry uses the same public address.",
                      "defaultValue": "https://${{Storage.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "FOUNDRY_STARTUP_WAIT_SECONDS": {
                      "isOptional": true,
                      "description": "Seconds the start waits for MySQL and the store before starting Foundry anyway (keep it below the healthcheck timeout).",
                      "defaultValue": "600"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Seconds between SIGTERM and SIGKILL on redeploy: a load or question in flight finishes or is handed back (the agent drains for 100 s).",
                      "defaultValue": "120"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "ed8226ab-e86e-597a-a1f5-56873ed6c6ac": {
                      "mountPath": "/work"
                    }
                  }
                },
                "b2465506-890b-51ac-822b-1f5e4e81f0fe": {
                  "icon": "https://devicons.railway.com/i/mysql.svg",
                  "name": "MySQL",
                  "deploy": {
                    "startCommand": "docker-entrypoint.sh mysqld --innodb-use-native-aio=0 --disable-log-bin --performance_schema=0 --innodb-buffer-pool-size=256M --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "mysql:8.0.46@sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b"
                  },
                  "variables": {
                    "MYSQLHOST": {
                      "isOptional": true,
                      "description": "Railway Private Domain Name.",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "MYSQLPORT": {
                      "isOptional": true,
                      "description": "MySQL port.",
                      "defaultValue": "3306"
                    },
                    "MYSQLUSER": {
                      "isOptional": true,
                      "description": "MySQL user, used for the Data panel.",
                      "defaultValue": "root"
                    },
                    "MYSQL_URL": {
                      "isOptional": true,
                      "description": "URL to connect to MySQL.",
                      "defaultValue": "mysql://${{ MYSQLUSER }}:${{ MYSQL_ROOT_PASSWORD }}@${{ RAILWAY_PRIVATE_DOMAIN }}:3306/${{ MYSQL_DATABASE }}"
                    },
                    "MYSQLDATABASE": {
                      "isOptional": true,
                      "description": "Default database, used for Data panel.",
                      "defaultValue": "${{ MYSQL_DATABASE }}"
                    },
                    "MYSQLPASSWORD": {
                      "isOptional": true,
                      "description": "Root password, used for Data panel.",
                      "defaultValue": "${{ MYSQL_ROOT_PASSWORD }}"
                    },
                    "MYSQL_DATABASE": {
                      "isOptional": true,
                      "description": "Database to be created on image startup (Foundry's tables).",
                      "defaultValue": "railway"
                    },
                    "MYSQL_ROOT_PASSWORD": {
                      "isOptional": true,
                      "description": "Root password for MySQL DB, generated at deploy (letters only: it sits in Foundry's DSN unescaped).",
                      "defaultValue": "{{MYSQL_ROOT_PASSWORD}}"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Time MySQL gets to shut down cleanly on redeploy.",
                      "defaultValue": "30"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "0a78c9ed-5067-5e44-bffd-e3f26dedcddf": {
                      "mountPath": "/var/lib/mysql"
                    }
                  }
                },
                "b898adae-48c3-591e-affd-24d3339d72f7": {
                  "icon": "https://cdn.jsdelivr.net/npm/lucide-static@1.59.0/icons/hard-drive.svg",
                  "name": "Storage",
                  "build": {
                    "builder": "DOCKERFILE"
                  },
                  "deploy": {
                    "healthcheckPath": "/healthz",
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 300
                  },
                  "source": {
                    "repo": "baranberkay96/helix-foundry-railway",
                    "branch": "main",
                    "rootDirectory": "/services/storage"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": true,
                      "description": "Port of the S3 API (public domain target and healthcheck).",
                      "defaultValue": "8333"
                    },
                    "FOUNDRY_S3_SECRET": {
                      "isOptional": true,
                      "description": "Secret of the store's one S3 identity, foundry, generated at deploy. Foundry references it.",
                      "defaultValue": "{{FOUNDRY_S3_SECRET}}"
                    },
                    "FOUNDRY_STORAGE_IMAGE": {
                      "isOptional": true,
                      "description": "SeaweedFS image this service's Docker build starts FROM (the version upstream's compose file pins).",
                      "defaultValue": "chrislusf/seaweedfs:4.47@sha256:ce9e796f1fe6f06968f4c04bdaf8f678dad9c8acdfef3d244133d71bfa6bf882"
                    },
                    "STORAGE_VOLUME_SIZE_MB": {
                      "isOptional": true,
                      "description": "Size of each SeaweedFS volume file. Small files fit a 5 GB Railway volume; raise it on large volumes.",
                      "defaultValue": "256"
                    },
                    "STORAGE_ALLOWED_ORIGINS": {
                      "isOptional": true,
                      "description": "Comma-separated origins whose pages may upload (CORS). Add your custom domain here if you give the Gateway one.",
                      "defaultValue": "https://${{Gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Time SeaweedFS gets to stop cleanly on redeploy (it takes about 20 s).",
                      "defaultValue": "60"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {
                      "<hasDomain>:8333": {
                        "port": 8333
                      }
                    }
                  },
                  "volumeMounts": {
                    "06fde5dd-4c3e-5e1e-ae6e-519c36139188": {
                      "mountPath": "/data"
                    }
                  }
                },
                "eafe2475-6f2d-5332-ada6-4e05746b4e88": {
                  "icon": "https://cdn.jsdelivr.net/npm/lucide-static@1.59.0/icons/shield-check.svg",
                  "name": "Gateway",
                  "build": {
                    "builder": "DOCKERFILE"
                  },
                  "deploy": {
                    "healthcheckPath": "/_gateway/health",
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 300
                  },
                  "source": {
                    "repo": "baranberkay96/helix-foundry-railway",
                    "branch": "main",
                    "rootDirectory": "/services/gateway"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": true,
                      "description": "Port the gateway listens on (public domain target and healthcheck).",
                      "defaultValue": "8080"
                    },
                    "BASIC_AUTH_PASSWORD": {
                      "isOptional": true,
                      "description": "Password for the browser's sign-in prompt, generated at deploy. Foundry has no sign-in of its own, so this protects the whole install; at least 12 characters or the gateway refuses to start.",
                      "defaultValue": "{{BASIC_AUTH_PASSWORD}}"
                    },
                    "BASIC_AUTH_USERNAME": {
                      "isOptional": true,
                      "description": "User name for the browser's sign-in prompt. Letters, digits and . _ @ - (anything else falls back to admin).",
                      "defaultValue": "admin"
                    },
                    "FOUNDRY_API_UPSTREAM": {
                      "isOptional": true,
                      "description": "Foundry API (MCP and HTTP Ask) on the private network.",
                      "defaultValue": "${{Foundry.RAILWAY_PRIVATE_DOMAIN}}:8081"
                    },
                    "FOUNDRY_GATEWAY_IMAGE": {
                      "isOptional": true,
                      "description": "Caddy image this service's Docker build starts FROM (Railway passes it as a build argument).",
                      "defaultValue": "caddy:2.11.9-alpine@sha256:0bbb055bda6793c999bde78b1b5ce3e89f829fb031af2cf50056ea1246559fee"
                    },
                    "FOUNDRY_SITE_UPSTREAM": {
                      "isOptional": true,
                      "description": "Foundry web app on the private network.",
                      "defaultValue": "${{Site.RAILWAY_PRIVATE_DOMAIN}}:3000"
                    },
                    "FOUNDRY_AGENT_ENDPOINTS": {
                      "isOptional": true,
                      "description": "on: /mcp and /v1/ontologies/... go straight to Foundry, which requires FOUNDRY_LOCAL_TOKEN as a bearer token (for Claude Code, Cursor and other MCP clients). off: they stay behind the password like the rest.",
                      "defaultValue": "on"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Seconds between SIGTERM and SIGKILL on redeploy.",
                      "defaultValue": "15"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {
                      "<hasDomain>:8080": {
                        "port": 8080
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "Storage",
      "method": "GET",
      "path": "/healthz",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 7,
    "needs_volume": true
  },
  "generated_at": "2026-11-11T04:15:11.344Z",
  "generator_version": "0.1.0"
}
