{
  "manifest_version": "1.0.0",
  "template": {
    "id": "0738c9dd-2834-45a4-b573-8ca00e4d7ed3",
    "slug": "dify-production",
    "name": "Dify Production",
    "description": "Open-source LLM app platform — workflows, agents, RAG. 10-service stack",
    "url": "https://railway.com/deploy/dify-production",
    "upstream": {
      "repo_url": "https://github.com/nomideusz/dify-railway"
    }
  },
  "services": [
    {
      "name": "api",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "gateway",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": true
    },
    {
      "name": "postgres",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    },
    {
      "name": "sandbox",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "ssrf-proxy",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "worker-beat",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "plugin-daemon",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/app/storage",
      "http": false
    },
    {
      "name": "worker",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "redis",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "web",
      "source": {
        "repo": "https://github.com/nomideusz/dify-railway"
      },
      "needs_volume": false,
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "api",
      "description": "API listen port for Railway's healthcheck. Must stay 5001.",
      "secret": false,
      "strategy": "default",
      "default": "5001"
    },
    {
      "key": "DB_HOST",
      "service": "api",
      "description": "Postgres private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FILES_URL",
      "service": "api",
      "description": "Private API URL the plugin daemon fetches files from. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_REGION",
      "service": "api",
      "description": "Bundled Railway bucket region. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_HOST",
      "service": "api",
      "description": "Redis private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SECRET_KEY",
      "service": "api",
      "description": "Signs sessions and tokens. Must match on api, worker and worker-beat (they reference this value).",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "APP_API_URL",
      "service": "api",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "APP_WEB_URL",
      "service": "api",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "DB_PASSWORD",
      "service": "api",
      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_ENDPOINT",
      "service": "api",
      "description": "Bundled Railway bucket endpoint. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGVECTOR_HOST",
      "service": "api",
      "description": "Vector store host — same Postgres instance. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_ACCESS_KEY",
      "service": "api",
      "description": "Bundled Railway bucket access key. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_SECRET_KEY",
      "service": "api",
      "description": "Bundled Railway bucket secret key. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_PASSWORD",
      "service": "api",
      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_BUCKET_NAME",
      "service": "api",
      "description": "Bundled Railway bucket name. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CONSOLE_API_URL",
      "service": "api",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CONSOLE_WEB_URL",
      "service": "api",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "SERVICE_API_URL",
      "service": "api",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CELERY_BROKER_URL",
      "service": "api",
      "description": "Celery broker (Redis DB 1). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGVECTOR_PASSWORD",
      "service": "api",
      "description": "Vector store password — same as the main database. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PLUGIN_DAEMON_KEY",
      "service": "api",
      "description": "Shared key for the plugin daemon. Referenced by the plugin-daemon service.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "PLUGIN_DAEMON_URL",
      "service": "api",
      "description": "Private URL of the plugin daemon. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SSRF_PROXY_HTTP_URL",
      "service": "api",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SSRF_PROXY_HTTPS_URL",
      "service": "api",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CODE_EXECUTION_API_KEY",
      "service": "api",
      "description": "Sandbox auth key, shared from the sandbox service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CODE_EXECUTION_ENDPOINT",
      "service": "api",
      "description": "Private URL of the code-execution sandbox. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "INNER_API_KEY_FOR_PLUGIN",
      "service": "api",
      "description": "Inner API key the plugin daemon uses to call back into the Dify API.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "API_HOST",
      "service": "gateway",
      "description": "Gateway upstream: the Dify API. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "WEB_HOST",
      "service": "gateway",
      "description": "Gateway upstream: the web console. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PLUGIN_DAEMON_HOST",
      "service": "gateway",
      "description": "Gateway upstream: the plugin daemon. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "postgres",
      "description": "Auto-generated database password.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PORT",
      "service": "sandbox",
      "description": "Sandbox port for Railway's healthcheck. Must stay 8194.",
      "secret": false,
      "strategy": "default",
      "default": "8194"
    },
    {
      "key": "API_KEY",
      "service": "sandbox",
      "description": "Auth key between the Dify API and the code-execution sandbox.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "HTTP_PROXY",
      "service": "sandbox",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HTTPS_PROXY",
      "service": "sandbox",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "DB_HOST",
      "service": "worker-beat",
      "description": "Postgres private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FILES_URL",
      "service": "worker-beat",
      "description": "Private API URL the plugin daemon fetches files from. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_REGION",
      "service": "worker-beat",
      "description": "Bundled Railway bucket region. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_HOST",
      "service": "worker-beat",
      "description": "Redis private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SECRET_KEY",
      "service": "worker-beat",
      "description": "Session-signing key, shared from the api service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "APP_API_URL",
      "service": "worker-beat",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "APP_WEB_URL",
      "service": "worker-beat",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "DB_PASSWORD",
      "service": "worker-beat",
      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_ENDPOINT",
      "service": "worker-beat",
      "description": "Bundled Railway bucket endpoint. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGVECTOR_HOST",
      "service": "worker-beat",
      "description": "Vector store host — same Postgres instance. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_ACCESS_KEY",
      "service": "worker-beat",
      "description": "Bundled Railway bucket access key. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_SECRET_KEY",
      "service": "worker-beat",
      "description": "Bundled Railway bucket secret key. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_PASSWORD",
      "service": "worker-beat",
      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_BUCKET_NAME",
      "service": "worker-beat",
      "description": "Bundled Railway bucket name. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CONSOLE_API_URL",
      "service": "worker-beat",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CONSOLE_WEB_URL",
      "service": "worker-beat",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "SERVICE_API_URL",
      "service": "worker-beat",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CELERY_BROKER_URL",
      "service": "worker-beat",
      "description": "Celery broker (Redis DB 1). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGVECTOR_PASSWORD",
      "service": "worker-beat",
      "description": "Vector store password — same as the main database. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PLUGIN_DAEMON_KEY",
      "service": "worker-beat",
      "description": "Shared key for the plugin daemon. Referenced by the plugin-daemon service.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PLUGIN_DAEMON_URL",
      "service": "worker-beat",
      "description": "Private URL of the plugin daemon. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SSRF_PROXY_HTTP_URL",
      "service": "worker-beat",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SSRF_PROXY_HTTPS_URL",
      "service": "worker-beat",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CODE_EXECUTION_API_KEY",
      "service": "worker-beat",
      "description": "Sandbox auth key, shared from the sandbox service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CODE_EXECUTION_ENDPOINT",
      "service": "worker-beat",
      "description": "Private URL of the code-execution sandbox. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "INNER_API_KEY_FOR_PLUGIN",
      "service": "worker-beat",
      "description": "Inner API key the plugin daemon uses to call back into the Dify API.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DB_HOST",
      "service": "plugin-daemon",
      "description": "Postgres private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "REDIS_HOST",
      "service": "plugin-daemon",
      "description": "Redis private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SERVER_KEY",
      "service": "plugin-daemon",
      "description": "Plugin daemon key, shared from the api service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DB_PASSWORD",
      "service": "plugin-daemon",
      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_PASSWORD",
      "service": "plugin-daemon",
      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DIFY_INNER_API_KEY",
      "service": "plugin-daemon",
      "description": "Inner API key, shared from the api service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DIFY_INNER_API_URL",
      "service": "plugin-daemon",
      "description": "Private URL of the Dify API. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "DB_HOST",
      "service": "worker",
      "description": "Postgres private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FILES_URL",
      "service": "worker",
      "description": "Private API URL the plugin daemon fetches files from. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_REGION",
      "service": "worker",
      "description": "Bundled Railway bucket region. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_HOST",
      "service": "worker",
      "description": "Redis private hostname. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SECRET_KEY",
      "service": "worker",
      "description": "Session-signing key, shared from the api service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "APP_API_URL",
      "service": "worker",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "APP_WEB_URL",
      "service": "worker",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "DB_PASSWORD",
      "service": "worker",
      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_ENDPOINT",
      "service": "worker",
      "description": "Bundled Railway bucket endpoint. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGVECTOR_HOST",
      "service": "worker",
      "description": "Vector store host — same Postgres instance. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_ACCESS_KEY",
      "service": "worker",
      "description": "Bundled Railway bucket access key. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_SECRET_KEY",
      "service": "worker",
      "description": "Bundled Railway bucket secret key. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_PASSWORD",
      "service": "worker",
      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_BUCKET_NAME",
      "service": "worker",
      "description": "Bundled Railway bucket name. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CONSOLE_API_URL",
      "service": "worker",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CONSOLE_WEB_URL",
      "service": "worker",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "SERVICE_API_URL",
      "service": "worker",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CELERY_BROKER_URL",
      "service": "worker",
      "description": "Celery broker (Redis DB 1). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGVECTOR_PASSWORD",
      "service": "worker",
      "description": "Vector store password — same as the main database. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PLUGIN_DAEMON_KEY",
      "service": "worker",
      "description": "Shared key for the plugin daemon. Referenced by the plugin-daemon service.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PLUGIN_DAEMON_URL",
      "service": "worker",
      "description": "Private URL of the plugin daemon. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SSRF_PROXY_HTTP_URL",
      "service": "worker",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SSRF_PROXY_HTTPS_URL",
      "service": "worker",
      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CODE_EXECUTION_API_KEY",
      "service": "worker",
      "description": "Sandbox auth key, shared from the sandbox service. Wired automatically — don't change.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CODE_EXECUTION_ENDPOINT",
      "service": "worker",
      "description": "Private URL of the code-execution sandbox. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "INNER_API_KEY_FOR_PLUGIN",
      "service": "worker",
      "description": "Inner API key the plugin daemon uses to call back into the Dify API.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_PASSWORD",
      "service": "redis",
      "description": "Auto-generated Redis password.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PORT",
      "service": "web",
      "description": "Web console port. Must stay 3000 — the gateway targets web:3000.",
      "secret": false,
      "strategy": "default",
      "default": "3000"
    },
    {
      "key": "APP_API_URL",
      "service": "web",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "CONSOLE_API_URL",
      "service": "web",
      "description": "Public gateway URL. Wired automatically — don't change.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "dify-production"
      }
    },
    "cli": "railway deploy --template dify-production",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "0738c9dd-2834-45a4-b573-8ca00e4d7ed3",
            "serializedConfig": {
              "buckets": {
                "ae7ab286-6c29-427b-9559-4a0bb831c935": {
                  "name": "dify-storage"
                }
              },
              "services": {
                "011e243c-9523-40e4-829e-94f392fce5a2": {
                  "icon": "https://cdn.zeabur.com/dify-icon.png",
                  "name": "api",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/health",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/api"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "API listen port for Railway's healthcheck. Must stay 5001.",
                      "defaultValue": "5001"
                    },
                    "DB_HOST": {
                      "isOptional": false,
                      "description": "Postgres private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "FILES_URL": {
                      "isOptional": false,
                      "description": "Private API URL the plugin daemon fetches files from. Wired automatically — don't change.",
                      "defaultValue": "http://${{api.RAILWAY_PRIVATE_DOMAIN}}:5001"
                    },
                    "S3_REGION": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket region. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.REGION}}"
                    },
                    "REDIS_HOST": {
                      "isOptional": false,
                      "description": "Redis private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "SECRET_KEY": {
                      "isOptional": false,
                      "description": "Signs sessions and tokens. Must match on api, worker and worker-beat (they reference this value).",
                      "defaultValue": "{{SECRET_KEY}}"
                    },
                    "APP_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "APP_WEB_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "S3_ENDPOINT": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket endpoint. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.ENDPOINT}}"
                    },
                    "PGVECTOR_HOST": {
                      "isOptional": false,
                      "description": "Vector store host — same Postgres instance. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "S3_ACCESS_KEY": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket access key. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.ACCESS_KEY_ID}}"
                    },
                    "S3_SECRET_KEY": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket secret key. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.SECRET_ACCESS_KEY}}"
                    },
                    "REDIS_PASSWORD": {
                      "isOptional": false,
                      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
                      "defaultValue": "${{redis.REDIS_PASSWORD}}"
                    },
                    "S3_BUCKET_NAME": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket name. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.BUCKET}}"
                    },
                    "CONSOLE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CONSOLE_WEB_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "SERVICE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CELERY_BROKER_URL": {
                      "isOptional": false,
                      "description": "Celery broker (Redis DB 1). Wired automatically — don't change.",
                      "defaultValue": "redis://:${{redis.REDIS_PASSWORD}}@${{redis.RAILWAY_PRIVATE_DOMAIN}}:6379/1"
                    },
                    "PGVECTOR_PASSWORD": {
                      "isOptional": false,
                      "description": "Vector store password — same as the main database. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "PLUGIN_DAEMON_KEY": {
                      "isOptional": false,
                      "description": "Shared key for the plugin daemon. Referenced by the plugin-daemon service.",
                      "defaultValue": "{{PLUGIN_DAEMON_KEY}}"
                    },
                    "PLUGIN_DAEMON_URL": {
                      "isOptional": false,
                      "description": "Private URL of the plugin daemon. Wired automatically — don't change.",
                      "defaultValue": "http://${{plugin-daemon.RAILWAY_PRIVATE_DOMAIN}}:5002"
                    },
                    "SSRF_PROXY_HTTP_URL": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "SSRF_PROXY_HTTPS_URL": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "CODE_EXECUTION_API_KEY": {
                      "isOptional": false,
                      "description": "Sandbox auth key, shared from the sandbox service. Wired automatically — don't change.",
                      "defaultValue": "${{sandbox.API_KEY}}"
                    },
                    "CODE_EXECUTION_ENDPOINT": {
                      "isOptional": false,
                      "description": "Private URL of the code-execution sandbox. Wired automatically — don't change.",
                      "defaultValue": "http://${{sandbox.RAILWAY_PRIVATE_DOMAIN}}:8194"
                    },
                    "INNER_API_KEY_FOR_PLUGIN": {
                      "isOptional": false,
                      "description": "Inner API key the plugin daemon uses to call back into the Dify API.",
                      "defaultValue": "{{INNER_API_KEY_FOR_PLUGIN}}"
                    }
                  }
                },
                "2c42f362-8af3-4d77-9ab2-1e5f06728cdd": {
                  "icon": "https://devicons.railway.app/i/nginx.svg",
                  "name": "gateway",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/gateway-health",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/gateway"
                  },
                  "variables": {
                    "API_HOST": {
                      "isOptional": false,
                      "description": "Gateway upstream: the Dify API. Wired automatically — don't change.",
                      "defaultValue": "${{api.RAILWAY_PRIVATE_DOMAIN}}:5001"
                    },
                    "WEB_HOST": {
                      "isOptional": false,
                      "description": "Gateway upstream: the web console. Wired automatically — don't change.",
                      "defaultValue": "${{web.RAILWAY_PRIVATE_DOMAIN}}:3000"
                    },
                    "PLUGIN_DAEMON_HOST": {
                      "isOptional": false,
                      "description": "Gateway upstream: the plugin daemon. Wired automatically — don't change.",
                      "defaultValue": "${{plugin-daemon.RAILWAY_PRIVATE_DOMAIN}}:5002"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  }
                },
                "308ffaf6-58c0-4b56-912b-d6c0597f8102": {
                  "icon": "https://devicons.railway.app/i/postgresql.svg",
                  "name": "postgres",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/postgres"
                  },
                  "variables": {
                    "POSTGRES_PASSWORD": {
                      "isOptional": false,
                      "description": "Auto-generated database password.",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    }
                  },
                  "volumeMounts": {
                    "308ffaf6-58c0-4b56-912b-d6c0597f8102": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                },
                "3d8a79d0-fed1-48a0-aa14-ae695d85542b": {
                  "icon": "https://cdn.zeabur.com/dify-icon.png",
                  "name": "sandbox",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/health",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/sandbox"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Sandbox port for Railway's healthcheck. Must stay 8194.",
                      "defaultValue": "8194"
                    },
                    "API_KEY": {
                      "isOptional": false,
                      "description": "Auth key between the Dify API and the code-execution sandbox.",
                      "defaultValue": "{{API_KEY}}"
                    },
                    "HTTP_PROXY": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "HTTPS_PROXY": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    }
                  }
                },
                "5a24bd5e-a9e3-4a3f-b98a-bdb07dbcdfa0": {
                  "icon": "http://www.squid-cache.org/Artwork/SN.png",
                  "name": "ssrf-proxy",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/ssrf-proxy"
                  },
                  "variables": {}
                },
                "759cb383-37b8-4869-995a-96508aa3c325": {
                  "icon": "https://cdn.zeabur.com/dify-icon.png",
                  "name": "worker-beat",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/worker-beat"
                  },
                  "variables": {
                    "DB_HOST": {
                      "isOptional": false,
                      "description": "Postgres private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "FILES_URL": {
                      "isOptional": false,
                      "description": "Private API URL the plugin daemon fetches files from. Wired automatically — don't change.",
                      "defaultValue": "http://${{api.RAILWAY_PRIVATE_DOMAIN}}:5001"
                    },
                    "S3_REGION": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket region. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.REGION}}"
                    },
                    "REDIS_HOST": {
                      "isOptional": false,
                      "description": "Redis private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "SECRET_KEY": {
                      "isOptional": false,
                      "description": "Session-signing key, shared from the api service. Wired automatically — don't change.",
                      "defaultValue": "${{api.SECRET_KEY}}"
                    },
                    "APP_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "APP_WEB_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "S3_ENDPOINT": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket endpoint. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.ENDPOINT}}"
                    },
                    "PGVECTOR_HOST": {
                      "isOptional": false,
                      "description": "Vector store host — same Postgres instance. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "S3_ACCESS_KEY": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket access key. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.ACCESS_KEY_ID}}"
                    },
                    "S3_SECRET_KEY": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket secret key. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.SECRET_ACCESS_KEY}}"
                    },
                    "REDIS_PASSWORD": {
                      "isOptional": false,
                      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
                      "defaultValue": "${{redis.REDIS_PASSWORD}}"
                    },
                    "S3_BUCKET_NAME": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket name. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.BUCKET}}"
                    },
                    "CONSOLE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CONSOLE_WEB_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "SERVICE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CELERY_BROKER_URL": {
                      "isOptional": false,
                      "description": "Celery broker (Redis DB 1). Wired automatically — don't change.",
                      "defaultValue": "redis://:${{redis.REDIS_PASSWORD}}@${{redis.RAILWAY_PRIVATE_DOMAIN}}:6379/1"
                    },
                    "PGVECTOR_PASSWORD": {
                      "isOptional": false,
                      "description": "Vector store password — same as the main database. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "PLUGIN_DAEMON_KEY": {
                      "isOptional": false,
                      "description": "Shared key for the plugin daemon. Referenced by the plugin-daemon service.",
                      "defaultValue": "${{api.PLUGIN_DAEMON_KEY}}"
                    },
                    "PLUGIN_DAEMON_URL": {
                      "isOptional": false,
                      "description": "Private URL of the plugin daemon. Wired automatically — don't change.",
                      "defaultValue": "http://${{plugin-daemon.RAILWAY_PRIVATE_DOMAIN}}:5002"
                    },
                    "SSRF_PROXY_HTTP_URL": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "SSRF_PROXY_HTTPS_URL": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "CODE_EXECUTION_API_KEY": {
                      "isOptional": false,
                      "description": "Sandbox auth key, shared from the sandbox service. Wired automatically — don't change.",
                      "defaultValue": "${{sandbox.API_KEY}}"
                    },
                    "CODE_EXECUTION_ENDPOINT": {
                      "isOptional": false,
                      "description": "Private URL of the code-execution sandbox. Wired automatically — don't change.",
                      "defaultValue": "http://${{sandbox.RAILWAY_PRIVATE_DOMAIN}}:8194"
                    },
                    "INNER_API_KEY_FOR_PLUGIN": {
                      "isOptional": false,
                      "description": "Inner API key the plugin daemon uses to call back into the Dify API.",
                      "defaultValue": "${{api.INNER_API_KEY_FOR_PLUGIN}}"
                    }
                  }
                },
                "808b3fb7-54d4-4773-8faa-dad7440218f9": {
                  "icon": "https://cdn.zeabur.com/dify-icon.png",
                  "name": "plugin-daemon",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/plugin-daemon"
                  },
                  "variables": {
                    "DB_HOST": {
                      "isOptional": false,
                      "description": "Postgres private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "REDIS_HOST": {
                      "isOptional": false,
                      "description": "Redis private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "SERVER_KEY": {
                      "isOptional": false,
                      "description": "Plugin daemon key, shared from the api service. Wired automatically — don't change.",
                      "defaultValue": "${{api.PLUGIN_DAEMON_KEY}}"
                    },
                    "DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "REDIS_PASSWORD": {
                      "isOptional": false,
                      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
                      "defaultValue": "${{redis.REDIS_PASSWORD}}"
                    },
                    "DIFY_INNER_API_KEY": {
                      "isOptional": false,
                      "description": "Inner API key, shared from the api service. Wired automatically — don't change.",
                      "defaultValue": "${{api.INNER_API_KEY_FOR_PLUGIN}}"
                    },
                    "DIFY_INNER_API_URL": {
                      "isOptional": false,
                      "description": "Private URL of the Dify API. Wired automatically — don't change.",
                      "defaultValue": "http://${{api.RAILWAY_PRIVATE_DOMAIN}}:5001"
                    }
                  },
                  "volumeMounts": {
                    "808b3fb7-54d4-4773-8faa-dad7440218f9": {
                      "mountPath": "/app/storage"
                    }
                  }
                },
                "95ca6b73-90a8-4f7a-be3f-c55d3288e679": {
                  "icon": "https://cdn.zeabur.com/dify-icon.png",
                  "name": "worker",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/worker"
                  },
                  "variables": {
                    "DB_HOST": {
                      "isOptional": false,
                      "description": "Postgres private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "FILES_URL": {
                      "isOptional": false,
                      "description": "Private API URL the plugin daemon fetches files from. Wired automatically — don't change.",
                      "defaultValue": "http://${{api.RAILWAY_PRIVATE_DOMAIN}}:5001"
                    },
                    "S3_REGION": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket region. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.REGION}}"
                    },
                    "REDIS_HOST": {
                      "isOptional": false,
                      "description": "Redis private hostname. Wired automatically — don't change.",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "SECRET_KEY": {
                      "isOptional": false,
                      "description": "Session-signing key, shared from the api service. Wired automatically — don't change.",
                      "defaultValue": "${{api.SECRET_KEY}}"
                    },
                    "APP_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "APP_WEB_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres password, shared from the postgres service. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "S3_ENDPOINT": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket endpoint. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.ENDPOINT}}"
                    },
                    "PGVECTOR_HOST": {
                      "isOptional": false,
                      "description": "Vector store host — same Postgres instance. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "S3_ACCESS_KEY": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket access key. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.ACCESS_KEY_ID}}"
                    },
                    "S3_SECRET_KEY": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket secret key. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.SECRET_ACCESS_KEY}}"
                    },
                    "REDIS_PASSWORD": {
                      "isOptional": false,
                      "description": "Redis password, shared from the redis service. Wired automatically — don't change.",
                      "defaultValue": "${{redis.REDIS_PASSWORD}}"
                    },
                    "S3_BUCKET_NAME": {
                      "isOptional": false,
                      "description": "Bundled Railway bucket name. Wired automatically — don't change.",
                      "defaultValue": "${{dify-storage.BUCKET}}"
                    },
                    "CONSOLE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CONSOLE_WEB_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "SERVICE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CELERY_BROKER_URL": {
                      "isOptional": false,
                      "description": "Celery broker (Redis DB 1). Wired automatically — don't change.",
                      "defaultValue": "redis://:${{redis.REDIS_PASSWORD}}@${{redis.RAILWAY_PRIVATE_DOMAIN}}:6379/1"
                    },
                    "PGVECTOR_PASSWORD": {
                      "isOptional": false,
                      "description": "Vector store password — same as the main database. Wired automatically — don't change.",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "PLUGIN_DAEMON_KEY": {
                      "isOptional": false,
                      "description": "Shared key for the plugin daemon. Referenced by the plugin-daemon service.",
                      "defaultValue": "${{api.PLUGIN_DAEMON_KEY}}"
                    },
                    "PLUGIN_DAEMON_URL": {
                      "isOptional": false,
                      "description": "Private URL of the plugin daemon. Wired automatically — don't change.",
                      "defaultValue": "http://${{plugin-daemon.RAILWAY_PRIVATE_DOMAIN}}:5002"
                    },
                    "SSRF_PROXY_HTTP_URL": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "SSRF_PROXY_HTTPS_URL": {
                      "isOptional": false,
                      "description": "Egress proxy for sandboxed code (SSRF protection). Wired automatically — don't change.",
                      "defaultValue": "http://${{ssrf-proxy.RAILWAY_PRIVATE_DOMAIN}}:3128"
                    },
                    "CODE_EXECUTION_API_KEY": {
                      "isOptional": false,
                      "description": "Sandbox auth key, shared from the sandbox service. Wired automatically — don't change.",
                      "defaultValue": "${{sandbox.API_KEY}}"
                    },
                    "CODE_EXECUTION_ENDPOINT": {
                      "isOptional": false,
                      "description": "Private URL of the code-execution sandbox. Wired automatically — don't change.",
                      "defaultValue": "http://${{sandbox.RAILWAY_PRIVATE_DOMAIN}}:8194"
                    },
                    "INNER_API_KEY_FOR_PLUGIN": {
                      "isOptional": false,
                      "description": "Inner API key the plugin daemon uses to call back into the Dify API.",
                      "defaultValue": "${{api.INNER_API_KEY_FOR_PLUGIN}}"
                    }
                  }
                },
                "a18a7990-b86e-4316-ad7b-c87cc2228372": {
                  "icon": "https://devicons.railway.app/i/redis.svg",
                  "name": "redis",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/redis"
                  },
                  "variables": {
                    "REDIS_PASSWORD": {
                      "isOptional": false,
                      "description": "Auto-generated Redis password.",
                      "defaultValue": "{{REDIS_PASSWORD}}"
                    }
                  }
                },
                "fe1b98b3-a77e-4535-8f0d-838b81c38aad": {
                  "icon": "https://cdn.zeabur.com/dify-icon.png",
                  "name": "web",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/dify-railway",
                    "rootDirectory": "/web"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Web console port. Must stay 3000 — the gateway targets web:3000.",
                      "defaultValue": "3000"
                    },
                    "APP_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "CONSOLE_API_URL": {
                      "isOptional": false,
                      "description": "Public gateway URL. Wired automatically — don't change.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "gateway",
      "method": "GET",
      "path": "/gateway-health",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 10,
    "needs_volume": true
  },
  "generated_at": "2026-09-22T10:14:47.278Z",
  "generator_version": "0.1.0",
  "status": "degraded",
  "validated_at": "2026-09-20T07:21:06.458Z",
  "success_rate_30d": 0.1667,
  "validation": {
    "last_run_id": "run_594cd516bc304ef2878d",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": false,
        "detail": "Your workspace has been restricted. Please contact support to resolve this."
      }
    ],
    "typical_ready_seconds": 192,
    "typical_build_seconds": 61,
    "typical_start_seconds": 30,
    "slowest_service": "worker-beat"
  }
}
