{
  "manifest_version": "1.0.0",
  "template": {
    "id": "f764c82d-aaa4-460a-923b-0f01fa0b8b94",
    "slug": "alexandrie",
    "name": "Alexandrie",
    "description": "Alexandrie notes with private MySQL, RustFS, and one HTTPS gateway.",
    "url": "https://railway.com/deploy/alexandrie",
    "upstream": {
      "image": "caddy:2.11.4-alpine@sha256:5f5c8640aae01df9654968d946d8f1a56c497f1dd5c5cda4cf95ab7c14d58648"
    }
  },
  "services": [
    {
      "name": "MySQL",
      "source": {
        "image": "mysql:8.0.46@sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/mysql",
      "http": false
    },
    {
      "name": "gateway",
      "source": {
        "image": "caddy:2.11.4-alpine@sha256:5f5c8640aae01df9654968d946d8f1a56c497f1dd5c5cda4cf95ab7c14d58648"
      },
      "needs_volume": false,
      "http": true
    },
    {
      "name": "rustfs",
      "source": {
        "image": "rustfs/rustfs:1.0.0-rc.5@sha256:c36b3efea3d1e503f1a2581abd0e7611e0e5820dd30e1850a52384b3fc52bda4"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    },
    {
      "name": "backend",
      "source": {
        "image": "ghcr.io/smaug6739/alexandrie-backend:v8.14.0"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "frontend",
      "source": {
        "image": "ghcr.io/smaug6739/alexandrie-frontend:v8.14.0"
      },
      "needs_volume": false,
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "PORT",
      "service": "MySQL",
      "description": "Internal service port.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MYSQLHOST",
      "service": "MySQL",
      "description": "Private hostname for the Railway Data panel.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MYSQLPORT",
      "service": "MySQL",
      "description": "Internal MySQL port; no public TCP proxy is created.",
      "secret": false,
      "strategy": "default",
      "default": "3306"
    },
    {
      "key": "MYSQLUSER",
      "service": "MySQL",
      "description": "Administrative user for the Railway Data panel only.",
      "secret": false,
      "strategy": "default",
      "default": "root"
    },
    {
      "key": "MYSQL_URL",
      "service": "MySQL",
      "description": "Private administrative connection URL for Railway database integration.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MYSQL_USER",
      "service": "MySQL",
      "description": "Non-root application user, created on first initialization.",
      "secret": false,
      "strategy": "default",
      "default": "alexandrie"
    },
    {
      "key": "MYSQLDATABASE",
      "service": "MySQL",
      "description": "Railway Data panel database.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MYSQLPASSWORD",
      "service": "MySQL",
      "description": "Root credential reference for the Railway Data panel.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MYSQL_DATABASE",
      "service": "MySQL",
      "description": "Database created on first initialization. Changing this does not rename an existing database.",
      "secret": false,
      "strategy": "default",
      "default": "alexandrie"
    },
    {
      "key": "MYSQL_PASSWORD",
      "service": "MySQL",
      "description": "Generated application-user password. Changing only this variable does not rotate an initialized MySQL user.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "MYSQL_ROOT_PASSWORD",
      "service": "MySQL",
      "description": "Independent generated root password, used by the Railway Data panel, not Alexandrie.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PORT",
      "service": "gateway",
      "description": "HTTP port behind Railway TLS termination.",
      "secret": false,
      "strategy": "default",
      "default": "8080"
    },
    {
      "key": "CADDY_CONFIG",
      "service": "gateway",
      "description": "Path-preserving routing, including private signed backup downloads.",
      "secret": false,
      "strategy": "default",
      "default": "{\n\tadmin off\n\tauto_https off\n\tservers {\n\t\ttrusted_proxies static private_ranges\n\t\ttrusted_proxies_strict\n\t}\n}\n\n(forwarded_https) {\n\theader_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}\n\theader_up X-Forwarded-Port 443\n}\n\n:{$PORT:8080} {\n\t@health {\n\t\tmethod GET\n\t\tpath /_health\n\t}\n\thandle @health {\n\t\trespond \"ok\" 200\n\t}\n\n\t@api path /api /api/*\n\thandle @api {\n\t\treverse_proxy {$BACKEND_UPSTREAM} {\n\t\t\timport forwarded_https\n\t\t}\n\t}\n\n\t# Backup objects stay private in S3; only valid signed requests can read them.\n\t# Do not use handle_path: S3 signatures require the original bucket/object path.\n\t@objects path /alexandrie/* /alexandrie-backups/*\n\thandle @objects {\n\t\treverse_proxy {$RUSTFS_UPSTREAM} {\n\t\t\timport forwarded_https\n\t\t}\n\t}\n\n\thandle {\n\t\treverse_proxy {$FRONTEND_UPSTREAM} {\n\t\t\timport forwarded_https\n\t\t}\n\t}\n}\n"
    },
    {
      "key": "RUSTFS_UPSTREAM",
      "service": "gateway",
      "description": "Private S3 upstream; never the console.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "BACKEND_UPSTREAM",
      "service": "gateway",
      "description": "Private API upstream.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "FRONTEND_UPSTREAM",
      "service": "gateway",
      "description": "Private frontend upstream.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PORT",
      "service": "rustfs",
      "description": "Private S3 API port.",
      "secret": false,
      "strategy": "default",
      "default": "9000"
    },
    {
      "key": "RUSTFS_ADDRESS",
      "service": "rustfs",
      "description": "Dual-stack listener for Railway private networking.",
      "secret": false,
      "strategy": "default",
      "default": "[::]:9000"
    },
    {
      "key": "RUSTFS_VOLUMES",
      "service": "rustfs",
      "description": "Persistent object-storage directory.",
      "secret": false,
      "strategy": "default",
      "default": "/data"
    },
    {
      "key": "RAILWAY_RUN_UID",
      "service": "rustfs",
      "description": "Allows the RustFS entrypoint to initialize a Railway-owned volume.",
      "secret": false,
      "strategy": "default",
      "default": "0"
    },
    {
      "key": "RUSTFS_ACCESS_KEY",
      "service": "rustfs",
      "description": "Generated S3 access key, unique per installation.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "RUSTFS_SECRET_KEY",
      "service": "rustfs",
      "description": "Generated S3 secret key, unique per installation.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "RUSTFS_CONSOLE_ENABLE",
      "service": "rustfs",
      "description": "Console disabled; no console port or public domain is created.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "RUSTFS_OBS_LOGGER_LEVEL",
      "service": "rustfs",
      "description": "RustFS log level.",
      "secret": false,
      "strategy": "default",
      "default": "info"
    },
    {
      "key": "RUSTFS_OBS_LOG_DIRECTORY",
      "service": "rustfs",
      "description": "Ephemeral logs; object data remains on the persistent volume.",
      "secret": false,
      "strategy": "default",
      "default": "/tmp/rustfs-logs"
    },
    {
      "key": "PORT",
      "service": "backend",
      "description": "Private backend API port.",
      "secret": false,
      "strategy": "default",
      "default": "8201"
    },
    {
      "key": "GIN_MODE",
      "service": "backend",
      "description": "Production Gin mode.",
      "secret": false,
      "strategy": "default",
      "default": "release"
    },
    {
      "key": "JWT_SECRET",
      "service": "backend",
      "description": "Generated JWT signing secret. Do not share this between installations.",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "BACKEND_PORT",
      "service": "backend",
      "description": "Alexandrie listener port.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "FRONTEND_URL",
      "service": "backend",
      "description": "Generated HTTPS origin used by browsers and emails.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "MINIO_BUCKET",
      "service": "backend",
      "description": "Main bucket; gateway routes are tied to this name. Backup bucket is alexandrie-backups.",
      "secret": false,
      "strategy": "default",
      "default": "alexandrie"
    },
    {
      "key": "MINIO_SECURE",
      "service": "backend",
      "description": "Internal S3 uses HTTP over Railway private networking; public URLs remain HTTPS.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "COOKIE_DOMAIN",
      "service": "backend",
      "description": "Gateway hostname only, without a scheme.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "DATABASE_HOST",
      "service": "backend",
      "description": "MySQL private hostname.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "DATABASE_NAME",
      "service": "backend",
      "description": "Application database.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DATABASE_PORT",
      "service": "backend",
      "description": "MySQL private port.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DATABASE_USER",
      "service": "backend",
      "description": "Dedicated non-root application user.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "ALLOW_UNSECURE",
      "service": "backend",
      "description": "Keep Secure and HTTP-only authentication cookies enabled.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "MINIO_ENDPOINT",
      "service": "backend",
      "description": "Private S3 API endpoint.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "MINIO_ACCESSKEY",
      "service": "backend",
      "description": "S3 access-key reference.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MINIO_SECRETKEY",
      "service": "backend",
      "description": "S3 secret-key reference.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "MINIO_PUBLIC_URL",
      "service": "backend",
      "description": "HTTPS origin for image and signed backup URLs.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "DATABASE_PASSWORD",
      "service": "backend",
      "description": "Reference to the application credential, not the root credential.",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CONFIG_DISABLE_SIGNUP",
      "service": "backend",
      "description": "Keep false for initial account creation; change to true after bootstrap if desired.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "CONFIG_DISABLE_NATIVE_LOGIN",
      "service": "backend",
      "description": "Do not disable native login before configuring and testing OIDC.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "HOST",
      "service": "frontend",
      "description": "Dual-stack listener.",
      "secret": false,
      "strategy": "default",
      "default": "::"
    },
    {
      "key": "PORT",
      "service": "frontend",
      "description": "Private frontend port.",
      "secret": false,
      "strategy": "default",
      "default": "8200"
    },
    {
      "key": "NODE_ENV",
      "service": "frontend",
      "description": "Production mode.",
      "secret": false,
      "strategy": "default",
      "default": "production"
    },
    {
      "key": "NITRO_HOST",
      "service": "frontend",
      "description": "Nuxt/Nitro dual-stack listener.",
      "secret": false,
      "strategy": "default",
      "default": "::"
    },
    {
      "key": "NUXT_PUBLIC_BASE_API",
      "service": "frontend",
      "description": "Same-origin public API base URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "NUXT_PUBLIC_BASE_CDN",
      "service": "frontend",
      "description": "Same-origin public file URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "NUXT_PUBLIC_BASE_URL",
      "service": "frontend",
      "description": "Generated public application URL.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "NUXT_PUBLIC_CDN_ENDPOINT",
      "service": "frontend",
      "description": "Public object path; must match the bucket and Caddy route.",
      "secret": false,
      "strategy": "default",
      "default": "/alexandrie/"
    },
    {
      "key": "NUXT_PUBLIC_CONFIG_HIDE_NATIVE_LOGIN",
      "service": "frontend",
      "description": "Keep native login visible for first-time setup.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "NUXT_PUBLIC_CONFIG_DISABLE_SIGNUP_PAGE",
      "service": "frontend",
      "description": "Mirrors backend signup policy.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "NUXT_PUBLIC_CONFIG_DISABLE_LANDING_PAGE",
      "service": "frontend",
      "description": "Optional: set true to skip the landing page.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "NUXT_PUBLIC_CONFIG_DISABLE_NATIVE_LOGIN",
      "service": "frontend",
      "description": "Mirrors backend native-login policy.",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "alexandrie"
      }
    },
    "cli": "railway deploy --template alexandrie",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "f764c82d-aaa4-460a-923b-0f01fa0b8b94",
            "serializedConfig": {
              "buckets": {},
              "services": {
                "13bc1c8f-45f5-4951-aa1b-1cb3faecff88": {
                  "icon": "https://devicons.railway.app/i/mysql.svg",
                  "name": "MySQL",
                  "deploy": {
                    "startCommand": "docker-entrypoint.sh mysqld --innodb-use-native-aio=0 --disable-log-bin --performance_schema=0 --innodb-buffer-pool-size=256M",
                    "healthcheckPath": null,
                    "sleepApplication": false,
                    "requiredMountPath": "/var/lib/mysql",
                    "restartPolicyType": "ALWAYS",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "mysql:8.0.46@sha256:7dcddc01f13bab2f15cde676d44d01f61fc9f99fe7785e86196dfc07d358ae2b",
                    "autoUpdates": {
                      "type": "disabled"
                    }
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Internal service port.",
                      "defaultValue": "${{MYSQLPORT}}"
                    },
                    "MYSQLHOST": {
                      "isOptional": false,
                      "description": "Private hostname for the Railway Data panel.",
                      "defaultValue": "${{RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "MYSQLPORT": {
                      "isOptional": false,
                      "description": "Internal MySQL port; no public TCP proxy is created.",
                      "defaultValue": "3306"
                    },
                    "MYSQLUSER": {
                      "isOptional": false,
                      "description": "Administrative user for the Railway Data panel only.",
                      "defaultValue": "root"
                    },
                    "MYSQL_URL": {
                      "isOptional": false,
                      "description": "Private administrative connection URL for Railway database integration.",
                      "defaultValue": "mysql://${{MYSQLUSER}}:${{MYSQL_ROOT_PASSWORD}}@${{RAILWAY_PRIVATE_DOMAIN}}:${{MYSQLPORT}}/${{MYSQL_DATABASE}}"
                    },
                    "MYSQL_USER": {
                      "isOptional": false,
                      "description": "Non-root application user, created on first initialization.",
                      "defaultValue": "alexandrie"
                    },
                    "MYSQLDATABASE": {
                      "isOptional": false,
                      "description": "Railway Data panel database.",
                      "defaultValue": "${{MYSQL_DATABASE}}"
                    },
                    "MYSQLPASSWORD": {
                      "isOptional": false,
                      "description": "Root credential reference for the Railway Data panel.",
                      "defaultValue": "${{MYSQL_ROOT_PASSWORD}}"
                    },
                    "MYSQL_DATABASE": {
                      "isOptional": false,
                      "description": "Database created on first initialization. Changing this does not rename an existing database.",
                      "defaultValue": "alexandrie"
                    },
                    "MYSQL_PASSWORD": {
                      "isOptional": false,
                      "description": "Generated application-user password. Changing only this variable does not rotate an initialized MySQL user.",
                      "defaultValue": "{{MYSQL_PASSWORD}}"
                    },
                    "MYSQL_ROOT_PASSWORD": {
                      "isOptional": false,
                      "description": "Independent generated root password, used by the Railway Data panel, not Alexandrie.",
                      "defaultValue": "{{MYSQL_ROOT_PASSWORD}}"
                    }
                  },
                  "networking": {},
                  "volumeMounts": {
                    "13bc1c8f-45f5-4951-aa1b-1cb3faecff88": {
                      "mountPath": "/var/lib/mysql"
                    }
                  }
                },
                "5550e3d9-bb14-49e7-95e8-0ab44bda8f2c": {
                  "icon": "https://devicons.railway.app/i/caddy.svg",
                  "name": "gateway",
                  "deploy": {
                    "startCommand": "/bin/sh -c 'printf \"%s\\n\" \"$CADDY_CONFIG\" > /etc/caddy/Caddyfile && exec caddy run --config /etc/caddy/Caddyfile --adapter caddyfile'",
                    "healthcheckPath": "/_health",
                    "sleepApplication": false,
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 300,
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "caddy:2.11.4-alpine@sha256:5f5c8640aae01df9654968d946d8f1a56c497f1dd5c5cda4cf95ab7c14d58648",
                    "autoUpdates": {
                      "type": "disabled"
                    }
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "HTTP port behind Railway TLS termination.",
                      "defaultValue": "8080"
                    },
                    "CADDY_CONFIG": {
                      "isOptional": false,
                      "description": "Path-preserving routing, including private signed backup downloads.",
                      "defaultValue": "{\n\tadmin off\n\tauto_https off\n\tservers {\n\t\ttrusted_proxies static private_ranges\n\t\ttrusted_proxies_strict\n\t}\n}\n\n(forwarded_https) {\n\theader_up X-Forwarded-Proto {http.request.header.X-Forwarded-Proto}\n\theader_up X-Forwarded-Port 443\n}\n\n:{$PORT:8080} {\n\t@health {\n\t\tmethod GET\n\t\tpath /_health\n\t}\n\thandle @health {\n\t\trespond \"ok\" 200\n\t}\n\n\t@api path /api /api/*\n\thandle @api {\n\t\treverse_proxy {$BACKEND_UPSTREAM} {\n\t\t\timport forwarded_https\n\t\t}\n\t}\n\n\t# Backup objects stay private in S3; only valid signed requests can read them.\n\t# Do not use handle_path: S3 signatures require the original bucket/object path.\n\t@objects path /alexandrie/* /alexandrie-backups/*\n\thandle @objects {\n\t\treverse_proxy {$RUSTFS_UPSTREAM} {\n\t\t\timport forwarded_https\n\t\t}\n\t}\n\n\thandle {\n\t\treverse_proxy {$FRONTEND_UPSTREAM} {\n\t\t\timport forwarded_https\n\t\t}\n\t}\n}\n"
                    },
                    "RUSTFS_UPSTREAM": {
                      "isOptional": false,
                      "description": "Private S3 upstream; never the console.",
                      "defaultValue": "${{rustfs.RAILWAY_PRIVATE_DOMAIN}}:${{rustfs.PORT}}"
                    },
                    "BACKEND_UPSTREAM": {
                      "isOptional": false,
                      "description": "Private API upstream.",
                      "defaultValue": "${{backend.RAILWAY_PRIVATE_DOMAIN}}:${{backend.PORT}}"
                    },
                    "FRONTEND_UPSTREAM": {
                      "isOptional": false,
                      "description": "Private frontend upstream.",
                      "defaultValue": "${{frontend.RAILWAY_PRIVATE_DOMAIN}}:${{frontend.PORT}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:8080": {
                        "port": 8080
                      }
                    }
                  }
                },
                "cae4cf45-8673-40c8-9878-226eac8fab9c": {
                  "icon": "https://rustfs.com/favicon-32x32.png",
                  "name": "rustfs",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/health",
                    "sleepApplication": false,
                    "requiredMountPath": "/data",
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 300,
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "rustfs/rustfs:1.0.0-rc.5@sha256:c36b3efea3d1e503f1a2581abd0e7611e0e5820dd30e1850a52384b3fc52bda4",
                    "autoUpdates": {
                      "type": "disabled"
                    }
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Private S3 API port.",
                      "defaultValue": "9000"
                    },
                    "RUSTFS_ADDRESS": {
                      "isOptional": false,
                      "description": "Dual-stack listener for Railway private networking.",
                      "defaultValue": "[::]:9000"
                    },
                    "RUSTFS_VOLUMES": {
                      "isOptional": false,
                      "description": "Persistent object-storage directory.",
                      "defaultValue": "/data"
                    },
                    "RAILWAY_RUN_UID": {
                      "isOptional": false,
                      "description": "Allows the RustFS entrypoint to initialize a Railway-owned volume.",
                      "defaultValue": "0"
                    },
                    "RUSTFS_ACCESS_KEY": {
                      "isOptional": false,
                      "description": "Generated S3 access key, unique per installation.",
                      "defaultValue": "{{RUSTFS_ACCESS_KEY}}"
                    },
                    "RUSTFS_SECRET_KEY": {
                      "isOptional": false,
                      "description": "Generated S3 secret key, unique per installation.",
                      "defaultValue": "{{RUSTFS_SECRET_KEY}}"
                    },
                    "RUSTFS_CONSOLE_ENABLE": {
                      "isOptional": false,
                      "description": "Console disabled; no console port or public domain is created.",
                      "defaultValue": "false"
                    },
                    "RUSTFS_OBS_LOGGER_LEVEL": {
                      "isOptional": false,
                      "description": "RustFS log level.",
                      "defaultValue": "info"
                    },
                    "RUSTFS_OBS_LOG_DIRECTORY": {
                      "isOptional": false,
                      "description": "Ephemeral logs; object data remains on the persistent volume.",
                      "defaultValue": "/tmp/rustfs-logs"
                    }
                  },
                  "networking": {},
                  "volumeMounts": {
                    "cae4cf45-8673-40c8-9878-226eac8fab9c": {
                      "mountPath": "/data"
                    }
                  }
                },
                "e5f2582e-f5d2-4e59-99d8-a1151fa68285": {
                  "icon": "https://github.com/Smaug6739/Alexandrie/blob/3204e623c5ec85bf0d0c7aae8ac0b071ec909800/frontend/public/icons/icon-512.png?raw=true",
                  "name": "backend",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": null,
                    "sleepApplication": false,
                    "restartPolicyType": "ALWAYS",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/smaug6739/alexandrie-backend:v8.14.0",
                    "autoUpdates": {
                      "type": "disabled"
                    }
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Private backend API port.",
                      "defaultValue": "8201"
                    },
                    "GIN_MODE": {
                      "isOptional": false,
                      "description": "Production Gin mode.",
                      "defaultValue": "release"
                    },
                    "JWT_SECRET": {
                      "isOptional": false,
                      "description": "Generated JWT signing secret. Do not share this between installations.",
                      "defaultValue": "{{JWT_SECRET}}"
                    },
                    "BACKEND_PORT": {
                      "isOptional": false,
                      "description": "Alexandrie listener port.",
                      "defaultValue": "${{PORT}}"
                    },
                    "FRONTEND_URL": {
                      "isOptional": false,
                      "description": "Generated HTTPS origin used by browsers and emails.",
                      "defaultValue": "https://${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "MINIO_BUCKET": {
                      "isOptional": false,
                      "description": "Main bucket; gateway routes are tied to this name. Backup bucket is alexandrie-backups.",
                      "defaultValue": "alexandrie"
                    },
                    "MINIO_SECURE": {
                      "isOptional": false,
                      "description": "Internal S3 uses HTTP over Railway private networking; public URLs remain HTTPS.",
                      "defaultValue": "false"
                    },
                    "COOKIE_DOMAIN": {
                      "isOptional": false,
                      "description": "Gateway hostname only, without a scheme.",
                      "defaultValue": "${{gateway.RAILWAY_PUBLIC_DOMAIN}}"
                    },
                    "DATABASE_HOST": {
                      "isOptional": false,
                      "description": "MySQL private hostname.",
                      "defaultValue": "${{MySQL.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "DATABASE_NAME": {
                      "isOptional": false,
                      "description": "Application database.",
                      "defaultValue": "${{MySQL.MYSQL_DATABASE}}"
                    },
                    "DATABASE_PORT": {
                      "isOptional": false,
                      "description": "MySQL private port.",
                      "defaultValue": "${{MySQL.MYSQLPORT}}"
                    },
                    "DATABASE_USER": {
                      "isOptional": false,
                      "description": "Dedicated non-root application user.",
                      "defaultValue": "${{MySQL.MYSQL_USER}}"
                    },
                    "ADMIN_ACCOUNTS": {
                      "isOptional": true,
                      "description": "After signing up, enter your user ID here and redeploy to obtain admin rights. Comma-separated for multiple admins.",
                      "defaultValue": ""
                    },
                    "ALLOW_UNSECURE": {
                      "isOptional": false,
                      "description": "Keep Secure and HTTP-only authentication cookies enabled.",
                      "defaultValue": "false"
                    },
                    "MINIO_ENDPOINT": {
                      "isOptional": false,
                      "description": "Private S3 API endpoint.",
                      "defaultValue": "${{rustfs.RAILWAY_PRIVATE_DOMAIN}}:${{rustfs.PORT}}"
                    },
                    "MINIO_ACCESSKEY": {
                      "isOptional": false,
                      "description": "S3 access-key reference.",
                      "defaultValue": "${{rustfs.RUSTFS_ACCESS_KEY}}"
                    },
                    "MINIO_SECRETKEY": {
                      "isOptional": false,
                      "description": "S3 secret-key reference.",
                      "defaultValue": "${{rustfs.RUSTFS_SECRET_KEY}}"
                    },
                    "MINIO_PUBLIC_URL": {
                      "isOptional": false,
                      "description": "HTTPS origin for image and signed backup URLs.",
                      "defaultValue": "${{FRONTEND_URL}}"
                    },
                    "DATABASE_PASSWORD": {
                      "isOptional": false,
                      "description": "Reference to the application credential, not the root credential.",
                      "defaultValue": "${{MySQL.MYSQL_PASSWORD}}"
                    },
                    "CONFIG_DISABLE_SIGNUP": {
                      "isOptional": false,
                      "description": "Keep false for initial account creation; change to true after bootstrap if desired.",
                      "defaultValue": "false"
                    },
                    "CONFIG_DISABLE_NATIVE_LOGIN": {
                      "isOptional": false,
                      "description": "Do not disable native login before configuring and testing OIDC.",
                      "defaultValue": "false"
                    }
                  },
                  "networking": {}
                },
                "f450127b-60d9-4d04-9966-60670ad509d0": {
                  "icon": "https://github.com/Smaug6739/Alexandrie/blob/3204e623c5ec85bf0d0c7aae8ac0b071ec909800/frontend/public/icons/icon-512.png?raw=true",
                  "name": "frontend",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/login",
                    "sleepApplication": false,
                    "restartPolicyType": "ALWAYS",
                    "healthcheckTimeout": 300,
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/smaug6739/alexandrie-frontend:v8.14.0",
                    "autoUpdates": {
                      "type": "disabled"
                    }
                  },
                  "variables": {
                    "HOST": {
                      "isOptional": false,
                      "description": "Dual-stack listener.",
                      "defaultValue": "::"
                    },
                    "PORT": {
                      "isOptional": false,
                      "description": "Private frontend port.",
                      "defaultValue": "8200"
                    },
                    "NODE_ENV": {
                      "isOptional": false,
                      "description": "Production mode.",
                      "defaultValue": "production"
                    },
                    "NITRO_HOST": {
                      "isOptional": false,
                      "description": "Nuxt/Nitro dual-stack listener.",
                      "defaultValue": "::"
                    },
                    "NUXT_PUBLIC_BASE_API": {
                      "isOptional": false,
                      "description": "Same-origin public API base URL.",
                      "defaultValue": "${{backend.FRONTEND_URL}}"
                    },
                    "NUXT_PUBLIC_BASE_CDN": {
                      "isOptional": false,
                      "description": "Same-origin public file URL.",
                      "defaultValue": "${{backend.MINIO_PUBLIC_URL}}"
                    },
                    "NUXT_PUBLIC_BASE_URL": {
                      "isOptional": false,
                      "description": "Generated public application URL.",
                      "defaultValue": "${{backend.FRONTEND_URL}}"
                    },
                    "NUXT_PUBLIC_CDN_ENDPOINT": {
                      "isOptional": false,
                      "description": "Public object path; must match the bucket and Caddy route.",
                      "defaultValue": "/alexandrie/"
                    },
                    "NUXT_PUBLIC_CONFIG_HIDE_NATIVE_LOGIN": {
                      "isOptional": false,
                      "description": "Keep native login visible for first-time setup.",
                      "defaultValue": "false"
                    },
                    "NUXT_PUBLIC_CONFIG_DISABLE_SIGNUP_PAGE": {
                      "isOptional": false,
                      "description": "Mirrors backend signup policy.",
                      "defaultValue": "${{backend.CONFIG_DISABLE_SIGNUP}}"
                    },
                    "NUXT_PUBLIC_CONFIG_DISABLE_LANDING_PAGE": {
                      "isOptional": false,
                      "description": "Optional: set true to skip the landing page.",
                      "defaultValue": "false"
                    },
                    "NUXT_PUBLIC_CONFIG_DISABLE_NATIVE_LOGIN": {
                      "isOptional": false,
                      "description": "Mirrors backend native-login policy.",
                      "defaultValue": "${{backend.CONFIG_DISABLE_NATIVE_LOGIN}}"
                    }
                  },
                  "networking": {}
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "gateway",
      "method": "GET",
      "path": "/_health",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 5,
    "needs_volume": true
  },
  "generated_at": "2026-09-06T23:54:14.295Z",
  "generator_version": "0.1.0",
  "status": "validated",
  "validated_at": "2026-09-06T23:56:47.270Z",
  "success_rate_30d": 1,
  "validation": {
    "last_run_id": "run_8c7d63a1be7b42c4b95f",
    "checks": [
      {
        "name": "workflow_completed",
        "passed": true
      },
      {
        "name": "all_services_deployed",
        "passed": true
      },
      {
        "name": "healthcheck",
        "passed": true
      },
      {
        "name": "stays_up",
        "passed": true
      }
    ],
    "typical_ready_seconds": 97,
    "typical_build_seconds": 0,
    "typical_start_seconds": 10,
    "slowest_service": "MySQL"
  }
}
