{
  "manifest_version": "1.0.0",
  "template": {
    "id": "d0256297-2053-482b-a361-dc5eee690fc7",
    "slug": "utopia-v01-rc9-enterprise-world-model",
    "name": "Utopia Enterprise World Model",
    "description": "Bitemporal knowledge graph from your documents: search, chat, review, MCP",
    "url": "https://railway.com/deploy/utopia-v01-rc9-enterprise-world-model",
    "upstream": {
      "repo_url": "https://github.com/baranberkay96/utopia-railway"
    }
  },
  "status": "unvalidated",
  "validated_at": null,
  "success_rate_30d": null,
  "services": [
    {
      "name": "Utopia",
      "source": {
        "repo": "https://github.com/baranberkay96/utopia-railway"
      },
      "needs_volume": true,
      "volume_mount_path": "/app/data",
      "http": true
    },
    {
      "name": "Postgres",
      "source": {
        "image": "ghcr.io/railwayapp-templates/postgres-ssl:18"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "Utopia",
      "description": "Port utopia-server listens on ([::], dual stack): public domain target and healthcheck port.",
      "secret": false,
      "strategy": "default",
      "default": "1516"
    },
    {
      "key": "RUST_LOG",
      "service": "Utopia",
      "description": "Log level (tracing EnvFilter syntax, e.g. info or info,utopia_server=debug).",
      "secret": false,
      "strategy": "default",
      "default": "info"
    },
    {
      "key": "ADMIN_NAME",
      "service": "Utopia",
      "description": "Display name of the administrator account (1-64 characters). First boot only.",
      "secret": false,
      "strategy": "default",
      "default": "Administrator"
    },
    {
      "key": "CHAT_MODEL",
      "service": "Utopia",
      "description": "Chat model for extraction, adjudication and answers (upstream's OpenAI preset). First boot only.",
      "secret": false,
      "strategy": "default",
      "default": "gpt-4o-mini"
    },
    {
      "key": "ADMIN_EMAIL",
      "service": "Utopia",
      "description": "Login email of the administrator account created on the first boot (upstream makes the first account the system administrator). Change it to yours before deploying; you sign in with exactly this value.",
      "secret": false,
      "strategy": "default",
      "default": "admin@example.com"
    },
    {
      "key": "UTOPIA_IMAGE",
      "service": "Utopia",
      "description": "Upstream image the build starts FROM (Docker build argument): v0.1.0-rc9, a pre-release. Upgrade by changing tag and digest together; migrations are forward-only, back up first.",
      "secret": false,
      "strategy": "default",
      "default": "ghcr.io/deeplethe/utopia:0.1.0-rc9@sha256:9bba072bf510519425c141e71642cdfaf085c2b8dfde2b9c35bb8c6a31b95755"
    },
    {
      "key": "ADMIN_PASSWORD",
      "service": "Utopia",
      "description": "Password of that account, generated at deploy (min. 8 characters). Used on the first boot only: change it later in the app, not here.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "MODEL_BASE_URL",
      "service": "Utopia",
      "description": "OpenAI-compatible endpoint for chat (and embeddings unless EMBEDDING_BASE_URL is set), e.g. https://api.deepseek.com/v1. First boot only.",
      "secret": false,
      "strategy": "default",
      "default": "https://api.openai.com/v1"
    },
    {
      "key": "EMBEDDING_MODEL",
      "service": "Utopia",
      "description": "Embedding model for search and entity matching (upstream's OpenAI preset). Keep it once documents are in; empty = no embedding model (documents wait). First boot only.",
      "secret": false,
      "strategy": "default",
      "default": "text-embedding-3-small"
    },
    {
      "key": "RUNTIME_THREADS",
      "service": "Utopia",
      "description": "Async runtime threads (TOKIO_WORKER_THREADS). auto = the service's CPU quota, 2 to 8; or a number.",
      "secret": false,
      "strategy": "default",
      "default": "auto"
    },
    {
      "key": "UTOPIA_DATA_DIR",
      "service": "Utopia",
      "description": "Uploaded originals (files/) and the full-text index (index/), on this service's volume. Back it up together with the database.",
      "secret": false,
      "strategy": "default",
      "default": "/app/data"
    },
    {
      "key": "OPEN_REGISTRATION",
      "service": "Utopia",
      "description": "First boot: false = only administrators add people (Administration -> Users); true = anyone who can open the URL may sign up as a viewer. Changeable later in Administration -> Deployment.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "UTOPIA_SECRET_KEY",
      "service": "Utopia",
      "description": "AES-256-GCM key (64 hex characters) that seals model API keys, connection strings and source tokens in the database. Keep it: without it those values cannot be read.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "DB_LEAST_PRIVILEGE",
      "service": "Utopia",
      "description": "true = run the app as utopia_app; false = as the Postgres owner (upstream default). A database first started as the owner stays on the owner (logged).",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "UTOPIA_DATABASE_URL",
      "service": "Utopia",
      "description": "Runtime connection as utopia_app: business tables read/write, the audit ledger append-only (upstream's optional hardening).",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "UTOPIA_COOKIE_SECURE",
      "service": "Utopia",
      "description": "Mark session cookies Secure (Railway serves HTTPS).",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "UTOPIA_MIGRATION_URL",
      "service": "Utopia",
      "description": "Owner connection (Postgres superuser): applies the schema migrations at startup, builds vector indexes and creates the utopia_app role.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "UTOPIA_APP_DB_PASSWORD",
      "service": "Utopia",
      "description": "Password of the least-privilege runtime role utopia_app, created by the start wrapper and re-applied on every start (letters and digits only).",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "UTOPIA_OIDC_REDIRECT_URI",
      "service": "Utopia",
      "description": "Callback URL to register at your identity provider (update it if you add a custom domain).",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "UTOPIA_DB_MAX_CONNECTIONS",
      "service": "Utopia",
      "description": "Database connection pool size (upstream default; matches the default job concurrency).",
      "secret": false,
      "strategy": "default",
      "default": "32"
    },
    {
      "key": "PGDATA",
      "service": "Postgres",
      "description": "Data directory inside the volume (Railway base layout; the image refuses anything outside /var/lib/postgresql/data).",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "PGHOST",
      "service": "Postgres",
      "description": "Private hostname of this database (postgres.railway.internal), used by the Data panel and the other services.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PGPORT",
      "service": "Postgres",
      "description": "Postgres port.",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "PGUSER",
      "service": "Postgres",
      "description": "User for the Data panel and the other services.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGDATABASE",
      "service": "Postgres",
      "description": "Database for the Data panel and the other services.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "PGPASSWORD",
      "service": "Postgres",
      "description": "Password for the Data panel and the other services.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "POSTGRES_DB",
      "service": "Postgres",
      "description": "Database created on first boot; the vector and pg_stat_statements extensions are created in it, and Utopia's migrations use it.",
      "secret": false,
      "strategy": "default",
      "default": "railway"
    },
    {
      "key": "DATABASE_URL",
      "service": "Postgres",
      "description": "Private connection string (Railway convention).",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PG_CPU_LIMIT",
      "service": "Postgres",
      "description": "CPUs the tuning plans for. auto = the container CPU quota capped at 8.",
      "secret": false,
      "strategy": "default",
      "default": "auto"
    },
    {
      "key": "POSTGRES_USER",
      "service": "Postgres",
      "description": "Superuser created on first boot.",
      "secret": false,
      "strategy": "default",
      "default": "postgres"
    },
    {
      "key": "SSL_CERT_DAYS",
      "service": "Postgres",
      "description": "Validity of the self-signed TLS certificate.",
      "secret": false,
      "strategy": "default",
      "default": "820"
    },
    {
      "key": "PGVECTOR_TUNING",
      "service": "Postgres",
      "description": "auto = size memory and parallelism from the container limits at every boot; off = Postgres defaults.",
      "secret": false,
      "strategy": "default",
      "default": "auto"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "Postgres",
      "description": "Superuser password, generated at deploy (letters only, so it is URL-safe). Changing it later needs ALTER USER too.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PG_MEMORY_LIMIT_MB",
      "service": "Postgres",
      "description": "RAM the tuning plans for. auto = the container limit capped at 8192 MB.",
      "secret": false,
      "strategy": "default",
      "default": "auto"
    },
    {
      "key": "RAILWAY_SHM_SIZE_BYTES",
      "service": "Postgres",
      "description": "Size of /dev/shm (1 GiB; Railway default 64 MB) for parallel HNSW index builds and parallel queries; only memory in use is billed.",
      "secret": false,
      "strategy": "default",
      "default": "1073741824"
    },
    {
      "key": "RAILWAY_DEPLOYMENT_DRAINING_SECONDS",
      "service": "Postgres",
      "description": "Time Postgres gets to shut down cleanly on redeploy.",
      "secret": false,
      "strategy": "default",
      "default": "60"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "utopia-v01-rc9-enterprise-world-model"
      }
    },
    "cli": "railway deploy --template utopia-v01-rc9-enterprise-world-model",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "d0256297-2053-482b-a361-dc5eee690fc7",
            "serializedConfig": {
              "buckets": {},
              "services": {
                "c5cb1ea9-3fc1-5238-9987-65c100be5646": {
                  "icon": "https://cdn.jsdelivr.net/npm/lucide-static@1.59.0/icons/orbit.svg",
                  "name": "Utopia",
                  "build": {
                    "builder": "DOCKERFILE"
                  },
                  "deploy": {
                    "healthcheckPath": "/api/v1/health",
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 1200
                  },
                  "source": {
                    "repo": "baranberkay96/utopia-railway",
                    "branch": "main",
                    "rootDirectory": "/services/utopia"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Port utopia-server listens on ([::], dual stack): public domain target and healthcheck port.",
                      "defaultValue": "1516"
                    },
                    "RUST_LOG": {
                      "isOptional": true,
                      "description": "Log level (tracing EnvFilter syntax, e.g. info or info,utopia_server=debug).",
                      "defaultValue": "info"
                    },
                    "ADMIN_NAME": {
                      "isOptional": true,
                      "description": "Display name of the administrator account (1-64 characters). First boot only.",
                      "defaultValue": "Administrator"
                    },
                    "CHAT_MODEL": {
                      "isOptional": true,
                      "description": "Chat model for extraction, adjudication and answers (upstream's OpenAI preset). First boot only.",
                      "defaultValue": "gpt-4o-mini"
                    },
                    "ADMIN_EMAIL": {
                      "isOptional": false,
                      "description": "Login email of the administrator account created on the first boot (upstream makes the first account the system administrator). Change it to yours before deploying; you sign in with exactly this value.",
                      "defaultValue": "admin@example.com"
                    },
                    "UTOPIA_IMAGE": {
                      "isOptional": false,
                      "description": "Upstream image the build starts FROM (Docker build argument): v0.1.0-rc9, a pre-release. Upgrade by changing tag and digest together; migrations are forward-only, back up first.",
                      "defaultValue": "ghcr.io/deeplethe/utopia:0.1.0-rc9@sha256:9bba072bf510519425c141e71642cdfaf085c2b8dfde2b9c35bb8c6a31b95755"
                    },
                    "MODEL_API_KEY": {
                      "isOptional": true,
                      "description": "Optional. API key of an OpenAI-compatible provider; on the first boot it is stored, encrypted, as the default workspace's chat and embedding key. Empty = set models later in Administration -> Models (Utopia still boots).",
                      "defaultValue": ""
                    },
                    "ADMIN_PASSWORD": {
                      "isOptional": false,
                      "description": "Password of that account, generated at deploy (min. 8 characters). Used on the first boot only: change it later in the app, not here.",
                      "defaultValue": "{{ADMIN_PASSWORD}}"
                    },
                    "MODEL_BASE_URL": {
                      "isOptional": true,
                      "description": "OpenAI-compatible endpoint for chat (and embeddings unless EMBEDDING_BASE_URL is set), e.g. https://api.deepseek.com/v1. First boot only.",
                      "defaultValue": "https://api.openai.com/v1"
                    },
                    "EMBEDDING_MODEL": {
                      "isOptional": true,
                      "description": "Embedding model for search and entity matching (upstream's OpenAI preset). Keep it once documents are in; empty = no embedding model (documents wait). First boot only.",
                      "defaultValue": "text-embedding-3-small"
                    },
                    "RUNTIME_THREADS": {
                      "isOptional": true,
                      "description": "Async runtime threads (TOKIO_WORKER_THREADS). auto = the service's CPU quota, 2 to 8; or a number.",
                      "defaultValue": "auto"
                    },
                    "UTOPIA_DATA_DIR": {
                      "isOptional": false,
                      "description": "Uploaded originals (files/) and the full-text index (index/), on this service's volume. Back it up together with the database.",
                      "defaultValue": "/app/data"
                    },
                    "EMBEDDING_API_KEY": {
                      "isOptional": true,
                      "description": "Optional key for EMBEDDING_BASE_URL; empty = MODEL_API_KEY. First boot only.",
                      "defaultValue": ""
                    },
                    "OPEN_REGISTRATION": {
                      "isOptional": true,
                      "description": "First boot: false = only administrators add people (Administration -> Users); true = anyone who can open the URL may sign up as a viewer. Changeable later in Administration -> Deployment.",
                      "defaultValue": "false"
                    },
                    "UTOPIA_SECRET_KEY": {
                      "isOptional": false,
                      "description": "AES-256-GCM key (64 hex characters) that seals model API keys, connection strings and source tokens in the database. Keep it: without it those values cannot be read.",
                      "defaultValue": "{{UTOPIA_SECRET_KEY}}"
                    },
                    "DB_LEAST_PRIVILEGE": {
                      "isOptional": true,
                      "description": "true = run the app as utopia_app; false = as the Postgres owner (upstream default). A database first started as the owner stays on the owner (logged).",
                      "defaultValue": "true"
                    },
                    "EMBEDDING_BASE_URL": {
                      "isOptional": true,
                      "description": "Optional embedding endpoint when it differs from MODEL_BASE_URL (DeepSeek, for example, has no embeddings). First boot only.",
                      "defaultValue": ""
                    },
                    "UTOPIA_OIDC_ISSUER": {
                      "isOptional": true,
                      "description": "Optional single sign-on: OIDC issuer URL (https). SSO is on when issuer, client id and redirect URI are all set; people link their identity from their account page.",
                      "defaultValue": ""
                    },
                    "UTOPIA_DATABASE_URL": {
                      "isOptional": false,
                      "description": "Runtime connection as utopia_app: business tables read/write, the audit ledger append-only (upstream's optional hardening).",
                      "defaultValue": "postgresql://utopia_app:${{UTOPIA_APP_DB_PASSWORD}}@${{Postgres.PGHOST}}:${{Postgres.PGPORT}}/${{Postgres.PGDATABASE}}"
                    },
                    "UTOPIA_COOKIE_SECURE": {
                      "isOptional": true,
                      "description": "Mark session cookies Secure (Railway serves HTTPS).",
                      "defaultValue": "true"
                    },
                    "UTOPIA_MIGRATION_URL": {
                      "isOptional": false,
                      "description": "Owner connection (Postgres superuser): applies the schema migrations at startup, builds vector indexes and creates the utopia_app role.",
                      "defaultValue": "${{Postgres.DATABASE_URL}}"
                    },
                    "UTOPIA_OIDC_CLIENT_ID": {
                      "isOptional": true,
                      "description": "Optional single sign-on: OIDC client id.",
                      "defaultValue": ""
                    },
                    "UTOPIA_APP_DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Password of the least-privilege runtime role utopia_app, created by the start wrapper and re-applied on every start (letters and digits only).",
                      "defaultValue": "{{UTOPIA_APP_DB_PASSWORD}}"
                    },
                    "UTOPIA_OIDC_REDIRECT_URI": {
                      "isOptional": true,
                      "description": "Callback URL to register at your identity provider (update it if you add a custom domain).",
                      "defaultValue": "https://${{RAILWAY_PUBLIC_DOMAIN}}/api/v1/auth/oidc/callback"
                    },
                    "UTOPIA_DB_MAX_CONNECTIONS": {
                      "isOptional": true,
                      "description": "Database connection pool size (upstream default; matches the default job concurrency).",
                      "defaultValue": "32"
                    },
                    "UTOPIA_OIDC_CLIENT_SECRET": {
                      "isOptional": true,
                      "description": "Optional single sign-on: OIDC client secret, if your identity provider requires one.",
                      "defaultValue": ""
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {
                      "<hasDomain>:1516": {
                        "port": 1516
                      }
                    }
                  },
                  "volumeMounts": {
                    "051c8eb7-5db3-50f6-8497-d041588adf78": {
                      "mountPath": "/app/data"
                    }
                  }
                },
                "dcf7983b-00b8-5bc8-9136-929672a58157": {
                  "icon": "https://devicons.railway.app/i/postgresql.svg",
                  "name": "Postgres",
                  "deploy": {
                    "startCommand": "/usr/bin/tini -g -- /bin/bash -c 'set -e; D=\"${PGDATA%/}\"; F=\"$D/pgvector-tuning.conf\"; C=\"$D/postgresql.conf\"; I=/docker-entrypoint-initdb.d; X=/tmp/pgvector-tuning.conf; echo \"CREATE EXTENSION IF NOT EXISTS vector; CREATE EXTENSION IF NOT EXISTS pg_stat_statements;\" > $I/zz-pgvector-extensions.sql; k() { v=$1; if [ $v -lt $2 ]; then v=$2; fi; if [ $v -gt $3 ]; then v=$3; fi; echo $v; }; n() { case \"$1\" in \"\"|*[!0-9]*) echo $2 ;; *) echo $1 ;; esac; }; w() { echo \"$1 = $2\" >> $X; }; if [ \"${PGVECTOR_TUNING:-auto}\" = off ]; then rm -f $F $I/zz-pgvector-conf.sh; echo \"pgvector-tune: PGVECTOR_TUNING=off, Postgres defaults apply\"; else H=$(( $(n \"$(grep -m 1 MemTotal /proc/meminfo | tr -s \" \" | cut -d \" \" -f 2)\" 1048576) / 1024 )); M=$(( $(n \"$(cat /sys/fs/cgroup/memory.max 2>/dev/null)\" $((H * 1048576))) / 1048576 )); if [ $M -gt $H ]; then M=$H; fi; B=$(k $(n \"$PG_MEMORY_LIMIT_MB\" $(k $M 256 8192)) 256 4194304); N=$(nproc); read -r Q P 2>/dev/null < /sys/fs/cgroup/cpu.max || Q=max; case \"$Q\" in \"\"|*[!0-9]*) ;; *) N=$(k $(( (Q + P - 1) / P )) 1 $N) ;; esac; N=$(k $(n \"$PG_CPU_LIMIT\" $(k $N 1 8)) 1 256); S=$(( $(n \"$(df -Pk /dev/shm 2>/dev/null | tail -n 1 | tr -s \" \" | cut -d \" \" -f 2)\" 65536) / 1024 )); SB=$(k $((B / 4)) 128 1048576); MW=$(k $((B / 4)) 64 2048); PM=$(k $((N - 1)) 0 4); PW=$(k $N 2 256); PG=$(k $((N / 2)) 0 2); FIT=$((S * 3 / 4)); if [ $FIT -lt 128 ]; then PM=0; fi; if [ $PM -gt 0 ]; then MW=$(k $MW 64 $FIT); fi; if [ $S -lt 256 ]; then PG=0; fi; echo \"# pgvector template: rewritten at every boot from budget ${B}MB (container ${M}MB), ${N} cpus, /dev/shm ${S}MB; ALTER SYSTEM overrides it\" > $X; w shared_buffers ${SB}MB; w effective_cache_size $((B * 3 / 4))MB; w maintenance_work_mem ${MW}MB; w autovacuum_work_mem $(k $((B / 16)) 64 $MW)MB; w work_mem $(k $((B / 512)) 4 64)MB; w max_worker_processes $(k $((PW + 4)) 8 512); w max_parallel_workers $PW; w max_parallel_workers_per_gather $PG; w max_parallel_maintenance_workers $PM; w random_page_cost 1.1; w effective_io_concurrency 200; w track_io_timing on; chmod 644 $X; if [ -f $D/PG_VERSION ] && [ -f $C ]; then install -o postgres -g postgres -m 600 $X $F; grep -qsF \"include_if_exists = pgvector-tuning.conf\" $C || echo \"include_if_exists = pgvector-tuning.conf\" >> $C; sync $F $C 2>/dev/null || true; else echo \"cp $X $F && chmod 600 $F && { grep -qsF pgvector-tuning.conf $C || echo include_if_exists = pgvector-tuning.conf >> $C; }\" > $I/zz-pgvector-conf.sh; fi; echo \"pgvector-tune: $(paste -sd \" \" $X)\"; fi; exec /usr/local/bin/wrapper.sh \"$@\"' pgvector-start postgres -p 5432 -c listen_addresses=*",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/railwayapp-templates/postgres-ssl:18"
                  },
                  "variables": {
                    "PGDATA": {
                      "isOptional": false,
                      "description": "Data directory inside the volume (Railway base layout; the image refuses anything outside /var/lib/postgresql/data).",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "PGHOST": {
                      "isOptional": false,
                      "description": "Private hostname of this database (postgres.railway.internal), used by the Data panel and the other services.",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "PGPORT": {
                      "isOptional": false,
                      "description": "Postgres port.",
                      "defaultValue": "5432"
                    },
                    "PGUSER": {
                      "isOptional": false,
                      "description": "User for the Data panel and the other services.",
                      "defaultValue": "${{POSTGRES_USER}}"
                    },
                    "PGDATABASE": {
                      "isOptional": false,
                      "description": "Database for the Data panel and the other services.",
                      "defaultValue": "${{POSTGRES_DB}}"
                    },
                    "PGPASSWORD": {
                      "isOptional": false,
                      "description": "Password for the Data panel and the other services.",
                      "defaultValue": "${{POSTGRES_PASSWORD}}"
                    },
                    "POSTGRES_DB": {
                      "isOptional": false,
                      "description": "Database created on first boot; the vector and pg_stat_statements extensions are created in it, and Utopia's migrations use it.",
                      "defaultValue": "railway"
                    },
                    "DATABASE_URL": {
                      "isOptional": true,
                      "description": "Private connection string (Railway convention).",
                      "defaultValue": "postgresql://${{PGUSER}}:${{POSTGRES_PASSWORD}}@${{RAILWAY_PRIVATE_DOMAIN}}:5432/${{PGDATABASE}}"
                    },
                    "PG_CPU_LIMIT": {
                      "isOptional": true,
                      "description": "CPUs the tuning plans for. auto = the container CPU quota capped at 8.",
                      "defaultValue": "auto"
                    },
                    "POSTGRES_USER": {
                      "isOptional": false,
                      "description": "Superuser created on first boot.",
                      "defaultValue": "postgres"
                    },
                    "SSL_CERT_DAYS": {
                      "isOptional": true,
                      "description": "Validity of the self-signed TLS certificate.",
                      "defaultValue": "820"
                    },
                    "PGVECTOR_TUNING": {
                      "isOptional": true,
                      "description": "auto = size memory and parallelism from the container limits at every boot; off = Postgres defaults.",
                      "defaultValue": "auto"
                    },
                    "POSTGRES_PASSWORD": {
                      "isOptional": false,
                      "description": "Superuser password, generated at deploy (letters only, so it is URL-safe). Changing it later needs ALTER USER too.",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    },
                    "PG_MEMORY_LIMIT_MB": {
                      "isOptional": true,
                      "description": "RAM the tuning plans for. auto = the container limit capped at 8192 MB.",
                      "defaultValue": "auto"
                    },
                    "RAILWAY_SHM_SIZE_BYTES": {
                      "isOptional": true,
                      "description": "Size of /dev/shm (1 GiB; Railway default 64 MB) for parallel HNSW index builds and parallel queries; only memory in use is billed.",
                      "defaultValue": "1073741824"
                    },
                    "RAILWAY_DEPLOYMENT_DRAINING_SECONDS": {
                      "isOptional": true,
                      "description": "Time Postgres gets to shut down cleanly on redeploy.",
                      "defaultValue": "60"
                    }
                  },
                  "networking": {
                    "tcpProxies": {},
                    "serviceDomains": {}
                  },
                  "volumeMounts": {
                    "e349dfbc-1d89-514d-b10b-edcedaee1c61": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "Utopia",
      "method": "GET",
      "path": "/api/v1/health",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 2,
    "needs_volume": true
  },
  "generated_at": "2026-11-11T04:15:11.344Z",
  "generator_version": "0.1.0"
}
