{
  "manifest_version": "1.0.0",
  "template": {
    "id": "6b4d001d-4b30-42fd-bd7d-e179c4c91758",
    "slug": "openreplay",
    "name": "OpenReplay | Open-Source Session Replay, FullStory and LogRocket Alternative",
    "description": "Self-hosted session replay, product analytics and DevTools for your web app",
    "url": "https://railway.com/deploy/openreplay",
    "upstream": {
      "repo_url": "https://github.com/nomideusz/openreplay-railway"
    }
  },
  "services": [
    {
      "name": "Redis",
      "source": {
        "image": "redis:8.10.2-alpine"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    },
    {
      "name": "OpenReplay",
      "source": {
        "repo": "https://github.com/nomideusz/openreplay-railway"
      },
      "needs_volume": false,
      "http": true
    },
    {
      "name": "API",
      "source": {
        "repo": "https://github.com/nomideusz/openreplay-railway"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "ClickHouse",
      "source": {
        "repo": "https://github.com/nomideusz/openreplay-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/clickhouse",
      "http": false
    },
    {
      "name": "Storage",
      "source": {
        "repo": "https://github.com/nomideusz/openreplay-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    },
    {
      "name": "Postgres",
      "source": {
        "image": "ghcr.io/railwayapp-templates/postgres-ssl:17"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    },
    {
      "name": "Backend",
      "source": {
        "repo": "https://github.com/nomideusz/openreplay-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/mnt/efs",
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "REDIS_PASSWORD",
      "service": "Redis",
      "description": "Auto-generated Redis password",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PORT",
      "service": "OpenReplay",
      "description": "Port the gateway listens on - leave as is",
      "secret": false,
      "strategy": "default",
      "default": "8080"
    },
    {
      "key": "BACKEND_HOST",
      "service": "OpenReplay",
      "description": "Go services (ingest, Go API, canvases) on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CHALICE_HOST",
      "service": "OpenReplay",
      "description": "Python API on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "STORAGE_HOST",
      "service": "OpenReplay",
      "description": "Object storage on the private network, for signed recording downloads",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "S3_KEY",
      "service": "API",
      "description": "Object storage access key",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_HOST",
      "service": "API",
      "description": "Public URL that signed recording links point at - routed to object storage by the gateway",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "ch_host",
      "service": "API",
      "description": "ClickHouse on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "ch_user",
      "service": "API",
      "description": "ClickHouse user",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "pg_host",
      "service": "API",
      "description": "Postgres on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "pg_user",
      "service": "API",
      "description": "Postgres user",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "SITE_URL",
      "service": "API",
      "description": "Public dashboard URL, used in emails and links - set it to your custom domain after adding one",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "S3_SECRET",
      "service": "API",
      "description": "Object storage secret key",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "pg_dbname",
      "service": "API",
      "description": "Postgres database",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "ASSIST_KEY",
      "service": "API",
      "description": "Same key as the Backend service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "JWT_SECRET",
      "service": "API",
      "description": "Same secret as the Backend service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "ch_password",
      "service": "API",
      "description": "ClickHouse password",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "pg_password",
      "service": "API",
      "description": "Postgres password",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_STRING",
      "service": "API",
      "description": "Redis on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "JWT_SPOT_SECRET",
      "service": "API",
      "description": "Same secret as the Backend service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "ASSIST_JWT_SECRET",
      "service": "API",
      "description": "Same secret as the Backend service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "JWT_REFRESH_SECRET",
      "service": "API",
      "description": "Signs refresh tokens",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "JWT_SPOT_REFRESH_SECRET",
      "service": "API",
      "description": "Signs Spot refresh tokens",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "CLICKHOUSE_USER",
      "service": "ClickHouse",
      "description": "ClickHouse user",
      "secret": false,
      "strategy": "default",
      "default": "openreplay"
    },
    {
      "key": "CLICKHOUSE_PASSWORD",
      "service": "ClickHouse",
      "description": "Auto-generated ClickHouse password",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "ClickHouse",
      "description": "Time for ClickHouse to flush and shut down cleanly on redeploy",
      "secret": false,
      "strategy": "default",
      "default": "30"
    },
    {
      "key": "RUSTFS_ACCESS_KEY",
      "service": "Storage",
      "description": "Auto-generated S3 access key",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "RUSTFS_SECRET_KEY",
      "service": "Storage",
      "description": "Auto-generated S3 secret key",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "PGDATA",
      "service": "Postgres",
      "description": "Data subdirectory - keeps Postgres happy on Railway volumes",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "POSTGRES_DB",
      "service": "Postgres",
      "description": "Database name",
      "secret": false,
      "strategy": "default",
      "default": "openreplay"
    },
    {
      "key": "POSTGRES_USER",
      "service": "Postgres",
      "description": "Database user - a superuser, which the schema needs for the pg_trgm and pgcrypto extensions",
      "secret": false,
      "strategy": "default",
      "default": "openreplay"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "Postgres",
      "description": "Auto-generated database password",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Postgres",
      "description": "Time for Postgres to shut down cleanly on redeploy",
      "secret": false,
      "strategy": "default",
      "default": "60"
    },
    {
      "key": "S3_PUBLIC",
      "service": "Backend",
      "description": "Public URL that signed download links point at - the gateway routes them to object storage",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "ASSIST_KEY",
      "service": "Backend",
      "description": "Assist key - shared with the API service",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "JWT_SECRET",
      "service": "Backend",
      "description": "Signs dashboard sessions - shared with the API service",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "CH_PASSWORD",
      "service": "Backend",
      "description": "ClickHouse password (legacy name some services read)",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CH_USERNAME",
      "service": "Backend",
      "description": "ClickHouse user (legacy name some services read)",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "S3_INTERNAL",
      "service": "Backend",
      "description": "Object storage on the private network - recordings are uploaded here",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "pg_password",
      "service": "Backend",
      "description": "Postgres password (read separately by some services)",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "REDIS_STRING",
      "service": "Backend",
      "description": "Redis on the private network - carries the ingest queues as Redis streams",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "TOKEN_SECRET",
      "service": "Backend",
      "description": "Signs tracker session tokens",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "ASSETS_ORIGIN",
      "service": "Backend",
      "description": "Public URL of the cached page assets (CSS, fonts, images) the player loads",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "JWT_SPOT_SECRET",
      "service": "Backend",
      "description": "Signs Spot sessions - shared with the API service",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "POSTGRES_STRING",
      "service": "Backend",
      "description": "Postgres on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "ASSIST_JWT_SECRET",
      "service": "Backend",
      "description": "Assist token secret - shared with the API service",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "AWS_ACCESS_KEY_ID",
      "service": "Backend",
      "description": "Object storage access key",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CLICKHOUSE_STRING",
      "service": "Backend",
      "description": "ClickHouse native protocol on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CLICKHOUSE_PASSWORD",
      "service": "Backend",
      "description": "ClickHouse password",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CLICKHOUSE_USERNAME",
      "service": "Backend",
      "description": "ClickHouse user",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "AWS_SECRET_ACCESS_KEY",
      "service": "Backend",
      "description": "Object storage secret key",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CLICKHOUSE_HTTP_STRING",
      "service": "Backend",
      "description": "ClickHouse HTTP interface on the private network",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "openreplay"
      }
    },
    "cli": "railway deploy --template openreplay",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "6b4d001d-4b30-42fd-bd7d-e179c4c91758",
            "serializedConfig": {
              "services": {
                "2999b64f-a340-4704-ae20-e15823b41409": {
                  "icon": "https://devicons.railway.app/i/redis.svg",
                  "name": "Redis",
                  "build": {},
                  "deploy": {
                    "startCommand": "/bin/sh -c \"rm -rf /data/lost+found && exec docker-entrypoint.sh redis-server --requirepass $REDIS_PASSWORD --maxmemory-policy noeviction --appendonly yes --dir /data\"",
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "redis:8.10.2-alpine"
                  },
                  "variables": {
                    "REDIS_PASSWORD": {
                      "isOptional": false,
                      "description": "Auto-generated Redis password",
                      "defaultValue": "{{REDIS_PASSWORD}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "06ec715e-b7a5-4629-8512-75e4cfe31730": {
                      "mountPath": "/data"
                    }
                  }
                },
                "547c49a2-5351-47f0-9998-c16927e5681b": {
                  "icon": "https://cdn.jsdelivr.net/gh/nomideusz/openreplay-railway/icon.svg",
                  "name": "OpenReplay",
                  "build": {},
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/openreplay-railway",
                    "rootDirectory": "/gateway"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the gateway listens on - leave as is",
                      "defaultValue": "8080"
                    },
                    "BACKEND_HOST": {
                      "isOptional": false,
                      "description": "Go services (ingest, Go API, canvases) on the private network",
                      "defaultValue": "${{Backend.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "CHALICE_HOST": {
                      "isOptional": false,
                      "description": "Python API on the private network",
                      "defaultValue": "${{API.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "STORAGE_HOST": {
                      "isOptional": false,
                      "description": "Object storage on the private network, for signed recording downloads",
                      "defaultValue": "${{Storage.RAILWAY_PRIVATE_DOMAIN}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>": {}
                    }
                  }
                },
                "b2e772fa-68d7-4925-8dbc-3fe7cb70c48e": {
                  "icon": "https://cdn.jsdelivr.net/gh/nomideusz/openreplay-railway/icon.svg",
                  "name": "API",
                  "build": {},
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/openreplay-railway",
                    "rootDirectory": "/chalice"
                  },
                  "variables": {
                    "S3_KEY": {
                      "isOptional": false,
                      "description": "Object storage access key",
                      "defaultValue": "${{Storage.RUSTFS_ACCESS_KEY}}"
                    },
                    "S3_HOST": {
                      "isOptional": false,
                      "description": "Public URL that signed recording links point at - routed to object storage by the gateway",
                      "defaultValue": "https://${{OpenReplay.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "ch_host": {
                      "isOptional": false,
                      "description": "ClickHouse on the private network",
                      "defaultValue": "${{ClickHouse.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "ch_user": {
                      "isOptional": false,
                      "description": "ClickHouse user",
                      "defaultValue": "${{ClickHouse.CLICKHOUSE_USER}}"
                    },
                    "pg_host": {
                      "isOptional": false,
                      "description": "Postgres on the private network",
                      "defaultValue": "${{Postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "pg_user": {
                      "isOptional": false,
                      "description": "Postgres user",
                      "defaultValue": "${{Postgres.POSTGRES_USER}}"
                    },
                    "SITE_URL": {
                      "isOptional": false,
                      "description": "Public dashboard URL, used in emails and links - set it to your custom domain after adding one",
                      "defaultValue": "https://${{OpenReplay.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "S3_SECRET": {
                      "isOptional": false,
                      "description": "Object storage secret key",
                      "defaultValue": "${{Storage.RUSTFS_SECRET_KEY}}"
                    },
                    "pg_dbname": {
                      "isOptional": false,
                      "description": "Postgres database",
                      "defaultValue": "${{Postgres.POSTGRES_DB}}"
                    },
                    "ASSIST_KEY": {
                      "isOptional": false,
                      "description": "Same key as the Backend service",
                      "defaultValue": "${{Backend.ASSIST_KEY}}"
                    },
                    "EMAIL_HOST": {
                      "isOptional": true,
                      "description": "SMTP host for invitations and password resets (Railway allows outbound SMTP on Pro only)",
                      "defaultValue": ""
                    },
                    "EMAIL_USER": {
                      "isOptional": true,
                      "description": "SMTP user",
                      "defaultValue": ""
                    },
                    "JWT_SECRET": {
                      "isOptional": false,
                      "description": "Same secret as the Backend service",
                      "defaultValue": "${{Backend.JWT_SECRET}}"
                    },
                    "ch_password": {
                      "isOptional": false,
                      "description": "ClickHouse password",
                      "defaultValue": "${{ClickHouse.CLICKHOUSE_PASSWORD}}"
                    },
                    "pg_password": {
                      "isOptional": false,
                      "description": "Postgres password",
                      "defaultValue": "${{Postgres.POSTGRES_PASSWORD}}"
                    },
                    "REDIS_STRING": {
                      "isOptional": false,
                      "description": "Redis on the private network",
                      "defaultValue": "redis://default:${{Redis.REDIS_PASSWORD}}@${{Redis.RAILWAY_PRIVATE_DOMAIN}}:6379"
                    },
                    "EMAIL_PASSWORD": {
                      "isOptional": true,
                      "description": "SMTP password",
                      "defaultValue": ""
                    },
                    "JWT_SPOT_SECRET": {
                      "isOptional": false,
                      "description": "Same secret as the Backend service",
                      "defaultValue": "${{Backend.JWT_SPOT_SECRET}}"
                    },
                    "ASSIST_JWT_SECRET": {
                      "isOptional": false,
                      "description": "Same secret as the Backend service",
                      "defaultValue": "${{Backend.ASSIST_JWT_SECRET}}"
                    },
                    "JWT_REFRESH_SECRET": {
                      "isOptional": false,
                      "description": "Signs refresh tokens",
                      "defaultValue": "{{JWT_REFRESH_SECRET}}"
                    },
                    "JWT_SPOT_REFRESH_SECRET": {
                      "isOptional": false,
                      "description": "Signs Spot refresh tokens",
                      "defaultValue": "{{JWT_SPOT_REFRESH_SECRET}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {}
                  }
                },
                "c72898c2-c994-400e-a1c8-f246ea7ded10": {
                  "icon": "https://devicons.railway.app/i/clickhouse.svg",
                  "name": "ClickHouse",
                  "build": {},
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/openreplay-railway",
                    "rootDirectory": "/clickhouse"
                  },
                  "variables": {
                    "CLICKHOUSE_USER": {
                      "isOptional": false,
                      "description": "ClickHouse user",
                      "defaultValue": "openreplay"
                    },
                    "CLICKHOUSE_PASSWORD": {
                      "isOptional": false,
                      "description": "Auto-generated ClickHouse password",
                      "defaultValue": "{{CLICKHOUSE_PASSWORD}}"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": false,
                      "description": "Time for ClickHouse to flush and shut down cleanly on redeploy",
                      "defaultValue": "30"
                    }
                  },
                  "networking": {
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "f94cc262-d2af-4544-9b23-5b114a6a7ef9": {
                      "mountPath": "/var/lib/clickhouse"
                    }
                  }
                },
                "dc8a733e-7daa-4005-8eb8-7c02ffb2584f": {
                  "icon": "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons/svg/rustfs.svg",
                  "name": "Storage",
                  "build": {},
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/openreplay-railway",
                    "rootDirectory": "/storage"
                  },
                  "variables": {
                    "RUSTFS_ACCESS_KEY": {
                      "isOptional": false,
                      "description": "Auto-generated S3 access key",
                      "defaultValue": "{{RUSTFS_ACCESS_KEY}}"
                    },
                    "RUSTFS_SECRET_KEY": {
                      "isOptional": false,
                      "description": "Auto-generated S3 secret key",
                      "defaultValue": "{{RUSTFS_SECRET_KEY}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "a67a7f0a-9513-4d49-8606-5e9dd113e6fe": {
                      "mountPath": "/data"
                    }
                  }
                },
                "f93266ea-9898-43a3-9ba0-03f13288c37f": {
                  "icon": "https://devicons.railway.app/i/postgresql.svg",
                  "name": "Postgres",
                  "build": {},
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/railwayapp-templates/postgres-ssl:17"
                  },
                  "variables": {
                    "PGDATA": {
                      "isOptional": false,
                      "description": "Data subdirectory - keeps Postgres happy on Railway volumes",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "POSTGRES_DB": {
                      "isOptional": false,
                      "description": "Database name",
                      "defaultValue": "openreplay"
                    },
                    "POSTGRES_USER": {
                      "isOptional": false,
                      "description": "Database user - a superuser, which the schema needs for the pg_trgm and pgcrypto extensions",
                      "defaultValue": "openreplay"
                    },
                    "POSTGRES_PASSWORD": {
                      "isOptional": false,
                      "description": "Auto-generated database password",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": false,
                      "description": "Time for Postgres to shut down cleanly on redeploy",
                      "defaultValue": "60"
                    }
                  },
                  "networking": {
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "c1893f75-7027-4a82-9ebe-05dd1608877f": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                },
                "fe96504c-c6a9-459d-afa7-506450eb0ac0": {
                  "icon": "https://cdn.jsdelivr.net/gh/nomideusz/openreplay-railway/icon.svg",
                  "name": "Backend",
                  "build": {},
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "restartPolicyType": "ALWAYS",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "https://github.com/nomideusz/openreplay-railway",
                    "rootDirectory": "/backend"
                  },
                  "variables": {
                    "S3_PUBLIC": {
                      "isOptional": false,
                      "description": "Public URL that signed download links point at - the gateway routes them to object storage",
                      "defaultValue": "https://${{OpenReplay.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "ASSIST_KEY": {
                      "isOptional": false,
                      "description": "Assist key - shared with the API service",
                      "defaultValue": "{{ASSIST_KEY}}"
                    },
                    "JWT_SECRET": {
                      "isOptional": false,
                      "description": "Signs dashboard sessions - shared with the API service",
                      "defaultValue": "{{JWT_SECRET}}"
                    },
                    "CH_PASSWORD": {
                      "isOptional": false,
                      "description": "ClickHouse password (legacy name some services read)",
                      "defaultValue": "${{ClickHouse.CLICKHOUSE_PASSWORD}}"
                    },
                    "CH_USERNAME": {
                      "isOptional": false,
                      "description": "ClickHouse user (legacy name some services read)",
                      "defaultValue": "${{ClickHouse.CLICKHOUSE_USER}}"
                    },
                    "S3_INTERNAL": {
                      "isOptional": false,
                      "description": "Object storage on the private network - recordings are uploaded here",
                      "defaultValue": "http://${{Storage.RAILWAY_PRIVATE_DOMAIN}}:9000"
                    },
                    "pg_password": {
                      "isOptional": false,
                      "description": "Postgres password (read separately by some services)",
                      "defaultValue": "${{Postgres.POSTGRES_PASSWORD}}"
                    },
                    "REDIS_STRING": {
                      "isOptional": false,
                      "description": "Redis on the private network - carries the ingest queues as Redis streams",
                      "defaultValue": "redis://default:${{Redis.REDIS_PASSWORD}}@${{Redis.RAILWAY_PRIVATE_DOMAIN}}:6379"
                    },
                    "TOKEN_SECRET": {
                      "isOptional": false,
                      "description": "Signs tracker session tokens",
                      "defaultValue": "{{TOKEN_SECRET}}"
                    },
                    "ASSETS_ORIGIN": {
                      "isOptional": false,
                      "description": "Public URL of the cached page assets (CSS, fonts, images) the player loads",
                      "defaultValue": "https://${{OpenReplay.RAILWAY_PUBLIC_DOMAIN}}/sessions-assets"
                    },
                    "JWT_SPOT_SECRET": {
                      "isOptional": false,
                      "description": "Signs Spot sessions - shared with the API service",
                      "defaultValue": "{{JWT_SPOT_SECRET}}"
                    },
                    "POSTGRES_STRING": {
                      "isOptional": false,
                      "description": "Postgres on the private network",
                      "defaultValue": "postgres://${{Postgres.POSTGRES_USER}}:${{Postgres.POSTGRES_PASSWORD}}@${{Postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/${{Postgres.POSTGRES_DB}}?sslmode=disable"
                    },
                    "ASSIST_JWT_SECRET": {
                      "isOptional": false,
                      "description": "Assist token secret - shared with the API service",
                      "defaultValue": "{{ASSIST_JWT_SECRET}}"
                    },
                    "AWS_ACCESS_KEY_ID": {
                      "isOptional": false,
                      "description": "Object storage access key",
                      "defaultValue": "${{Storage.RUSTFS_ACCESS_KEY}}"
                    },
                    "CLICKHOUSE_STRING": {
                      "isOptional": false,
                      "description": "ClickHouse native protocol on the private network",
                      "defaultValue": "${{ClickHouse.RAILWAY_PRIVATE_DOMAIN}}:9000/default"
                    },
                    "CLICKHOUSE_PASSWORD": {
                      "isOptional": false,
                      "description": "ClickHouse password",
                      "defaultValue": "${{ClickHouse.CLICKHOUSE_PASSWORD}}"
                    },
                    "CLICKHOUSE_USERNAME": {
                      "isOptional": false,
                      "description": "ClickHouse user",
                      "defaultValue": "${{ClickHouse.CLICKHOUSE_USER}}"
                    },
                    "AWS_SECRET_ACCESS_KEY": {
                      "isOptional": false,
                      "description": "Object storage secret key",
                      "defaultValue": "${{Storage.RUSTFS_SECRET_KEY}}"
                    },
                    "CLICKHOUSE_HTTP_STRING": {
                      "isOptional": false,
                      "description": "ClickHouse HTTP interface on the private network",
                      "defaultValue": "${{ClickHouse.RAILWAY_PRIVATE_DOMAIN}}:8123/default"
                    }
                  },
                  "networking": {
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "1a701e0a-2079-4db8-a8ec-340aa6a3d628": {
                      "mountPath": "/mnt/efs"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "OpenReplay",
      "method": "GET",
      "path": "/",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 7,
    "needs_volume": true
  },
  "generated_at": "2026-10-14T10:14:43.564Z",
  "generator_version": "0.1.0",
  "status": "degraded",
  "validated_at": "2026-10-11T20:00:28.025Z",
  "success_rate_30d": 0.3333,
  "validation": {
    "last_run_id": "run_7aa581582dad42418515",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": false,
        "detail": "BUILDING,FAILED,BUILDING,BUILDING,BUILDING,SUCCESS,SUCCESS"
      }
    ],
    "typical_ready_seconds": 99,
    "typical_build_seconds": 60,
    "typical_start_seconds": 10,
    "slowest_service": "Backend"
  }
}
