{
  "manifest_version": "1.0.0",
  "template": {
    "id": "7738e62c-dcec-4559-957d-52823b2b655b",
    "slug": "dexter-with-web-ui",
    "name": "Dexter with Web UI",
    "description": "Dexter : autonomous financial research agent with a secure web dashboard.",
    "url": "https://railway.com/deploy/dexter-with-web-ui",
    "upstream": {
      "repo_url": "https://github.com/XavTo/dexter"
    }
  },
  "services": [
    {
      "name": "Dexter",
      "source": {
        "repo": "https://github.com/XavTo/dexter"
      },
      "needs_volume": true,
      "volume_mount_path": "/app/.dexter",
      "http": true
    },
    {
      "name": "Cron",
      "source": {
        "image": "ghcr.io/railwayapp/function-bun:1.3.0"
      },
      "needs_volume": false,
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "Dexter",
      "description": "Web server port (Railway injects PORT if unset)",
      "secret": false,
      "strategy": "default",
      "default": "3000"
    },
    {
      "key": "DEXTER_MODEL",
      "service": "Dexter",
      "description": "LLM model ID used by the agent",
      "secret": false,
      "strategy": "default",
      "default": "gpt-5.2"
    },
    {
      "key": "DASHBOARD_USER",
      "service": "Dexter",
      "description": "Dashboard username (optional if empty)",
      "secret": false,
      "strategy": "default",
      "default": "admin"
    },
    {
      "key": "OPENAI_API_KEY",
      "service": "Dexter",
      "description": "OpenAI API key (or use another provider key)",
      "secret": true,
      "strategy": "default",
      "default": "your-api-key"
    },
    {
      "key": "DEXTER_PROVIDER",
      "service": "Dexter",
      "description": "LLM provider (openai, anthropic, google, etc.)",
      "secret": false,
      "strategy": "default",
      "default": "openai"
    },
    {
      "key": "EXASEARCH_API_KEY",
      "service": "Dexter",
      "description": "Web search (Exa) API key (optional)",
      "secret": true,
      "strategy": "default",
      "default": "your-api-key"
    },
    {
      "key": "DASHBOARD_PASSWORD",
      "service": "Dexter",
      "description": "Dashboard password (required)",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "DEXTER_MAX_ITERATIONS",
      "service": "Dexter",
      "description": "Max agent loop iterations per run",
      "secret": false,
      "strategy": "default",
      "default": "10"
    },
    {
      "key": "FINANCIAL_DATASETS_API_KEY",
      "service": "Dexter",
      "description": "Market data provider key",
      "secret": true,
      "strategy": "default",
      "default": "your-api-key"
    },
    {
      "key": "DEXTER_QUERY",
      "service": "Cron",
      "description": "Query to run (required by the cron function)",
      "secret": false,
      "strategy": "default",
      "default": "Analyze NVDA: growth, margins, valuation, key risks, and a bull/base/bear conclusion with sources."
    },
    {
      "key": "DASHBOARD_USER",
      "service": "Cron",
      "description": "Dashboard username (optional if empty)",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DASHBOARD_PASSWORD",
      "service": "Cron",
      "description": "Dashboard password (required)",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DEXTER_DASHBOARD_URL",
      "service": "Cron",
      "description": "Public URL of the web service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "DASHBOARD_AUTH_SCHEME",
      "service": "Cron",
      "description": "Auth scheme: basic or bearer",
      "secret": false,
      "strategy": "default",
      "default": "bearer"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "dexter-with-web-ui"
      }
    },
    "cli": "railway deploy --template dexter-with-web-ui",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "7738e62c-dcec-4559-957d-52823b2b655b",
            "serializedConfig": {
              "buckets": {},
              "services": {
                "a58bb2c3-c113-4ac7-8ad6-7ae4a74499dd": {
                  "icon": "https://i.pinimg.com/originals/3c/e1/f5/3ce1f5010548d49360fbda7849976f75.gif",
                  "name": "Dexter",
                  "deploy": {
                    "startCommand": "bash scripts/railway-job.sh",
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/XavTo/dexter",
                    "rootDirectory": null
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Web server port (Railway injects PORT if unset)",
                      "defaultValue": "3000"
                    },
                    "DEXTER_MODEL": {
                      "isOptional": false,
                      "description": "LLM model ID used by the agent",
                      "defaultValue": "gpt-5.2"
                    },
                    "DASHBOARD_USER": {
                      "isOptional": false,
                      "description": "Dashboard username (optional if empty)",
                      "defaultValue": "admin"
                    },
                    "OPENAI_API_KEY": {
                      "isOptional": false,
                      "description": "OpenAI API key (or use another provider key)",
                      "defaultValue": "your-api-key"
                    },
                    "DEXTER_PROVIDER": {
                      "isOptional": false,
                      "description": "LLM provider (openai, anthropic, google, etc.)",
                      "defaultValue": "openai"
                    },
                    "EXASEARCH_API_KEY": {
                      "isOptional": false,
                      "description": "Web search (Exa) API key (optional)",
                      "defaultValue": "your-api-key"
                    },
                    "DASHBOARD_PASSWORD": {
                      "isOptional": false,
                      "description": "Dashboard password (required)",
                      "defaultValue": "{{DASHBOARD_PASSWORD}}"
                    },
                    "DEXTER_MAX_ITERATIONS": {
                      "isOptional": false,
                      "description": "Max agent loop iterations per run",
                      "defaultValue": "10"
                    },
                    "FINANCIAL_DATASETS_API_KEY": {
                      "isOptional": false,
                      "description": "Market data provider key",
                      "defaultValue": "your-api-key"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:3000": {
                        "port": 3000
                      }
                    }
                  },
                  "volumeMounts": {
                    "a58bb2c3-c113-4ac7-8ad6-7ae4a74499dd": {
                      "mountPath": "/app/.dexter"
                    }
                  }
                },
                "a64bf419-0108-4714-aa0d-8f459135bbb7": {
                  "icon": "https://bun.com/logo.svg",
                  "name": "Cron",
                  "deploy": {
                    "cronSchedule": "0 0 * * *",
                    "startCommand": "./run.sh Ly8gUmFpbHdheSBDcm9uIChCdW4gcnVudGltZSk6IHRyaWdnZXIgRGV4dGVyIGRhc2hib2FyZCBydW4KaW1wb3J0IHsgeiB9IGZyb20gInpvZEAzIjsKCmNvbnN0IGVudiA9IHoKICAub2JqZWN0KHsKICAgIERFWFRFUl9EQVNIQk9BUkRfVVJMOiB6LnN0cmluZygpLnVybCgpLAogICAgREFTSEJPQVJEX1BBU1NXT1JEOiB6LnN0cmluZygpLm1pbigxKSwKICAgIERFWFRFUl9RVUVSWTogei5zdHJpbmcoKS5taW4oMSksCiAgICBEQVNIQk9BUkRfVVNFUjogei5zdHJpbmcoKS5vcHRpb25hbCgpLAogICAgREFTSEJPQVJEX0FVVEhfU0NIRU1FOiB6LmVudW0oWyJiYXNpYyIsICJiZWFyZXIiXSkub3B0aW9uYWwoKSwKICB9KQogIC5wYXJzZShwcm9jZXNzLmVudik7Cgpjb25zdCBiYXNlVXJsID0gZW52LkRFWFRFUl9EQVNIQk9BUkRfVVJMLnJlcGxhY2UoL1wvJC8sICIiKTsKY29uc3QgZW5kcG9pbnQgPSBgJHtiYXNlVXJsfS9hcGkvcnVuYDsKY29uc3QgYXV0aFNjaGVtZSA9IGVudi5EQVNIQk9BUkRfQVVUSF9TQ0hFTUUgPz8gImJhc2ljIjsKY29uc3QgdXNlciA9CiAgZW52LkRBU0hCT0FSRF9VU0VSICYmIGVudi5EQVNIQk9BUkRfVVNFUi5sZW5ndGggPiAwCiAgICA/IGVudi5EQVNIQk9BUkRfVVNFUgogICAgOiAiYWRtaW4iOwoKY29uc3QgYXV0aEhlYWRlciA9CiAgYXV0aFNjaGVtZSA9PT0gImJlYXJlciIKICAgID8gYEJlYXJlciAke2Vudi5EQVNIQk9BUkRfUEFTU1dPUkR9YAogICAgOiBgQmFzaWMgJHtCdWZmZXIuZnJvbShgJHt1c2VyfToke2Vudi5EQVNIQk9BUkRfUEFTU1dPUkR9YCkudG9TdHJpbmcoCiAgICAgICAgImJhc2U2NCIKICAgICAgKX1gOwoKY29uc3QgcmVzID0gYXdhaXQgZmV0Y2goZW5kcG9pbnQsIHsKICBtZXRob2Q6ICJQT1NUIiwKICBoZWFkZXJzOiB7CiAgICAiY29udGVudC10eXBlIjogImFwcGxpY2F0aW9uL2pzb24iLAogICAgYXV0aG9yaXphdGlvbjogYXV0aEhlYWRlciwKICB9LAogIGJvZHk6IEpTT04uc3RyaW5naWZ5KHsgcXVlcnk6IGVudi5ERVhURVJfUVVFUlkgfSksCn0pOwoKaWYgKCFyZXMub2spIHsKICBjb25zdCBlcnJvclRleHQgPSBhd2FpdCByZXMudGV4dCgpLmNhdGNoKCgpID0+ICIiKTsKICB0aHJvdyBuZXcgRXJyb3IoYERleHRlciBjcm9uIGZhaWxlZCAoJHtyZXMuc3RhdHVzfSk6ICR7ZXJyb3JUZXh0fWApOwp9Cgpjb25zdCBwYXlsb2FkID0gYXdhaXQgcmVzLmpzb24oKS5jYXRjaCgoKSA9PiAoe30pKTsKY29uc3QgcGF5bG9hZFNjaGVtYSA9IHoKICAub2JqZWN0KHsKICAgIHJ1bklkOiB6LnN0cmluZygpLm9wdGlvbmFsKCksCiAgfSkKICAucGFzc3Rocm91Z2goKTsKY29uc3QgcGFyc2VkID0gcGF5bG9hZFNjaGVtYS5zYWZlUGFyc2UocGF5bG9hZCk7CmNvbnN0IHJ1bklkID0gcGFyc2VkLnN1Y2Nlc3MgPyBwYXJzZWQuZGF0YS5ydW5JZCA6IHVuZGVmaW5lZDsKY29uc29sZS5sb2coYERleHRlciBydW4gc3RhcnRlZDogJHtydW5JZCA/PyAidW5rbm93biJ9YCk7Cg==",
                    "healthcheckPath": null
                  },
                  "source": {
                    "image": "ghcr.io/railwayapp/function-bun:1.3.0"
                  },
                  "variables": {
                    "DEXTER_QUERY": {
                      "isOptional": false,
                      "description": "Query to run (required by the cron function)",
                      "defaultValue": "Analyze NVDA: growth, margins, valuation, key risks, and a bull/base/bear conclusion with sources."
                    },
                    "DASHBOARD_USER": {
                      "isOptional": false,
                      "description": "Dashboard username (optional if empty)",
                      "defaultValue": "${{Dexter.DASHBOARD_USER}}"
                    },
                    "DASHBOARD_PASSWORD": {
                      "isOptional": false,
                      "description": "Dashboard password (required)",
                      "defaultValue": "${{Dexter.DASHBOARD_PASSWORD}}"
                    },
                    "DEXTER_DASHBOARD_URL": {
                      "isOptional": false,
                      "description": "Public URL of the web service",
                      "defaultValue": "https://${{Dexter.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "DASHBOARD_AUTH_SCHEME": {
                      "isOptional": false,
                      "description": "Auth scheme: basic or bearer",
                      "defaultValue": "bearer"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {},
  "resources": {
    "expected_services": 2,
    "needs_volume": true
  },
  "generated_at": "2026-09-20T10:14:37.339Z",
  "generator_version": "0.1.0",
  "status": "validated",
  "validated_at": "2026-09-18T12:12:57.243Z",
  "success_rate_30d": 1,
  "validation": {
    "last_run_id": "run_61b6f3db66be45afa8c4",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": true
      },
      {
        "name": "stays_up",
        "passed": true
      }
    ],
    "typical_ready_seconds": 118,
    "typical_build_seconds": 0,
    "typical_start_seconds": 10,
    "slowest_service": "Cron"
  }
}
