{
  "manifest_version": "1.0.0",
  "template": {
    "id": "e1fae538-feb1-4274-9888-27767d75fc38",
    "slug": "hll-crcon-cloud",
    "name": "hll-crcon-cloud",
    "description": "Cloud hosting for CRCON, the community RCON tool for Hell Let Loose.",
    "url": "https://railway.com/deploy/hll-crcon-cloud",
    "upstream": {
      "repo_url": "https://github.com/sledro/crcon.cloud"
    }
  },
  "status": "unvalidated",
  "validated_at": null,
  "success_rate_30d": null,
  "services": [
    {
      "name": "maintenance",
      "source": {
        "repo": "https://github.com/sledro/crcon.cloud"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "webhooks",
      "source": {
        "repo": "https://github.com/sledro/crcon.cloud"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "frontend",
      "source": {
        "repo": "https://github.com/sledro/crcon.cloud"
      },
      "needs_volume": false,
      "http": true
    },
    {
      "name": "redis",
      "source": {
        "image": "redis:alpine"
      },
      "needs_volume": true,
      "volume_mount_path": "/data",
      "http": false
    },
    {
      "name": "postgres",
      "source": {
        "image": "postgres:12-alpine"
      },
      "needs_volume": true,
      "volume_mount_path": "/var/lib/postgresql/data",
      "http": false
    },
    {
      "name": "backend",
      "source": {
        "repo": "https://github.com/sledro/crcon.cloud"
      },
      "needs_volume": false,
      "http": false
    },
    {
      "name": "supervisor",
      "source": {
        "repo": "https://github.com/sledro/crcon.cloud"
      },
      "needs_volume": true,
      "volume_mount_path": "/scoreboard_db",
      "http": false
    }
  ],
  "required_inputs": [
    {
      "key": "HLL_GAME",
      "service": "maintenance",
      "description": "Game type; needed by database migrations",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_URL",
      "service": "maintenance",
      "description": "Full Postgres connection URL used by alembic",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_HOST",
      "service": "maintenance",
      "description": "Postgres private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_NAME",
      "service": "maintenance",
      "description": "Postgres database name",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_USER",
      "service": "maintenance",
      "description": "Postgres user, referenced from the postgres service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_REDIS_DB",
      "service": "maintenance",
      "description": "Redis logical database for server 1",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "HLL_REDIS_URL",
      "service": "maintenance",
      "description": "Full Redis connection URL used by cache migrations",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "SERVER_NUMBER",
      "service": "maintenance",
      "description": "Server number; needed by database migrations",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "HLL_REDIS_HOST",
      "service": "maintenance",
      "description": "Redis private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_PASSWORD",
      "service": "maintenance",
      "description": "Postgres password, referenced from the postgres service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_HOST_PORT",
      "service": "maintenance",
      "description": "Postgres port",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "HLL_REDIS_HOST_PORT",
      "service": "maintenance",
      "description": "Redis port",
      "secret": false,
      "strategy": "default",
      "default": "6379"
    },
    {
      "key": "HLL_MAINTENANCE_CONTAINER",
      "service": "maintenance",
      "description": "Marks this container as the migration runner",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "HLL_DB_URL",
      "service": "webhooks",
      "description": "Full Postgres connection URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_HOST",
      "service": "webhooks",
      "description": "Postgres private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_NAME",
      "service": "webhooks",
      "description": "Postgres database name",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_USER",
      "service": "webhooks",
      "description": "Postgres user, referenced from the postgres service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "LOGGING_PATH",
      "service": "webhooks",
      "description": "Directory CRCON writes log files to",
      "secret": false,
      "strategy": "default",
      "default": "/logs/"
    },
    {
      "key": "LOGGING_LEVEL",
      "service": "webhooks",
      "description": "Log verbosity",
      "secret": false,
      "strategy": "default",
      "default": "INFO"
    },
    {
      "key": "HLL_REDIS_HOST",
      "service": "webhooks",
      "description": "Redis private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_REDIS_PORT",
      "service": "webhooks",
      "description": "Redis port",
      "secret": false,
      "strategy": "default",
      "default": "6379"
    },
    {
      "key": "HLL_DB_PASSWORD",
      "service": "webhooks",
      "description": "Postgres password, referenced from the postgres service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_HOST_PORT",
      "service": "webhooks",
      "description": "Postgres port",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "HLL_WH_LOOP_SLEEP_TIME",
      "service": "webhooks",
      "description": "Event loop sleep between webhook sends",
      "secret": false,
      "strategy": "default",
      "default": "0.006"
    },
    {
      "key": "HLL_WH_MAX_QUEUE_LENGTH",
      "service": "webhooks",
      "description": "Maximum queued webhook messages",
      "secret": false,
      "strategy": "default",
      "default": "150"
    },
    {
      "key": "HLL_WH_SERVICE_CONTAINER",
      "service": "webhooks",
      "description": "Marks this container as the webhook dispatcher",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "HLL_WH_SERVICE_RL_RESET_SECS",
      "service": "webhooks",
      "description": "Webhook rate limit window in seconds",
      "secret": false,
      "strategy": "default",
      "default": "3"
    },
    {
      "key": "HLL_WH_SERVICE_RL_TIME_WINDOW",
      "service": "webhooks",
      "description": "Seconds to track external rate limit hits",
      "secret": false,
      "strategy": "default",
      "default": "600"
    },
    {
      "key": "HLL_WH_SERVICE_RL_REQUESTS_PER",
      "service": "webhooks",
      "description": "Requests allowed per rate limit window",
      "secret": false,
      "strategy": "default",
      "default": "5"
    },
    {
      "key": "PORT",
      "service": "frontend",
      "description": "Tells Railway which port to healthcheck; nginx serves the admin UI on 80",
      "secret": false,
      "strategy": "default",
      "default": "80"
    },
    {
      "key": "HLL_GAME",
      "service": "frontend",
      "description": "Game type; selects which game assets nginx serves",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "CRCON_API_HOST",
      "service": "frontend",
      "description": "Backend private hostname nginx proxies API and websocket traffic to",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "RCONWEB_EXTERNAL_ADDRESS",
      "service": "frontend",
      "description": "This service's own public domain",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "PGDATA",
      "service": "postgres",
      "description": "Postgres data directory inside the mounted volume",
      "secret": false,
      "strategy": "default",
      "default": "/var/lib/postgresql/data/pgdata"
    },
    {
      "key": "POSTGRES_DB",
      "service": "postgres",
      "description": "Database name created on first boot",
      "secret": false,
      "strategy": "default",
      "default": "rcon"
    },
    {
      "key": "POSTGRES_USER",
      "service": "postgres",
      "description": "Database superuser name",
      "secret": false,
      "strategy": "default",
      "default": "rcon"
    },
    {
      "key": "POSTGRES_PASSWORD",
      "service": "postgres",
      "description": "Generated database password; alphanumeric because CRCON forbids special characters",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "PORT",
      "service": "backend",
      "description": "Tells Railway which port to healthcheck; unused by CRCON",
      "secret": false,
      "strategy": "default",
      "default": "8000"
    },
    {
      "key": "DOMAINS",
      "service": "backend",
      "description": "Django ALLOWED_HOSTS and CSRF origins, including Railway's healthcheck host",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "HLL_GAME",
      "service": "backend",
      "description": "Game type: hll, or hllv for Hell Let Loose Vietnam",
      "secret": false,
      "strategy": "default",
      "default": "hll"
    },
    {
      "key": "HLL_HOST",
      "service": "backend",
      "description": "IP address of your Hell Let Loose game server (no port)",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "HLL_PORT",
      "service": "backend",
      "description": "RCON port of your game server (not the game or query port)",
      "secret": false,
      "strategy": "ask_user"
    },
    {
      "key": "CONFIG_DIR",
      "service": "backend",
      "description": "Config directory expected by CRCON",
      "secret": false,
      "strategy": "default",
      "default": "/config/"
    },
    {
      "key": "HLL_DB_URL",
      "service": "backend",
      "description": "Full Postgres connection URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_HOST",
      "service": "backend",
      "description": "Postgres private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_NAME",
      "service": "backend",
      "description": "Postgres database name",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_USER",
      "service": "backend",
      "description": "Postgres user, referenced from the postgres service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_PASSWORD",
      "service": "backend",
      "description": "RCON password of your game server",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "HLL_REDIS_DB",
      "service": "backend",
      "description": "Redis logical database for this game server",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "LOGGING_PATH",
      "service": "backend",
      "description": "Directory CRCON writes log files to",
      "secret": false,
      "strategy": "default",
      "default": "/logs/"
    },
    {
      "key": "RCONWEB_PORT",
      "service": "backend",
      "description": "Display-only admin UI port shown in the interface",
      "secret": false,
      "strategy": "default",
      "default": "443"
    },
    {
      "key": "HLL_REDIS_URL",
      "service": "backend",
      "description": "Full Redis connection URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "LOGGING_LEVEL",
      "service": "backend",
      "description": "Log verbosity for CRCON",
      "secret": false,
      "strategy": "default",
      "default": "INFO"
    },
    {
      "key": "SERVER_NUMBER",
      "service": "backend",
      "description": "CRCON server number; namespaces this server's data",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "HLL_REDIS_HOST",
      "service": "backend",
      "description": "Redis private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_REDIS_PORT",
      "service": "backend",
      "description": "Redis port",
      "secret": false,
      "strategy": "default",
      "default": "6379"
    },
    {
      "key": "NB_API_THREADS",
      "service": "backend",
      "description": "Threads per gunicorn worker",
      "secret": false,
      "strategy": "default",
      "default": "8"
    },
    {
      "key": "NB_API_WORKERS",
      "service": "backend",
      "description": "Gunicorn worker count",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "HLL_DB_PASSWORD",
      "service": "backend",
      "description": "Postgres password, referenced from the postgres service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_HOST_PORT",
      "service": "backend",
      "description": "Postgres port",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "PUBLIC_STATS_PORT",
      "service": "backend",
      "description": "Display-only public stats port",
      "secret": false,
      "strategy": "default",
      "default": "80"
    },
    {
      "key": "RCONWEB_API_SECRET",
      "service": "backend",
      "description": "Django secret key encrypting sessions; never change after first deploy",
      "secret": true,
      "strategy": "generate",
      "generate": "random_base64_32"
    },
    {
      "key": "SUPERVISOR_RPC_URL",
      "service": "backend",
      "description": "Supervisord RPC endpoint used by the UI Services page",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "CRCON_FRONTEND_HOST",
      "service": "backend",
      "description": "Frontend private hostname, aliased for the multi-server registry",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "PUBLIC_STATS_PORT_HTTPS",
      "service": "backend",
      "description": "Display-only public stats HTTPS port",
      "secret": false,
      "strategy": "default",
      "default": "443"
    },
    {
      "key": "RCONWEB_EXTERNAL_ADDRESS",
      "service": "backend",
      "description": "Public address of the admin UI",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    },
    {
      "key": "HLL_GAME",
      "service": "supervisor",
      "description": "Game type, referenced from the backend service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_HOST",
      "service": "supervisor",
      "description": "Game server IP, referenced from the backend service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_PORT",
      "service": "supervisor",
      "description": "Game server RCON port, referenced from the backend service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_URL",
      "service": "supervisor",
      "description": "Full Postgres connection URL",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_HOST",
      "service": "supervisor",
      "description": "Postgres private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_DB_NAME",
      "service": "supervisor",
      "description": "Postgres database name",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_USER",
      "service": "supervisor",
      "description": "Postgres user, referenced from the postgres service",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_PASSWORD",
      "service": "supervisor",
      "description": "Game server RCON password, referenced from the backend service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_REDIS_DB",
      "service": "supervisor",
      "description": "Redis logical database for this game server",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "LOGGING_PATH",
      "service": "supervisor",
      "description": "Directory CRCON writes log files to",
      "secret": false,
      "strategy": "default",
      "default": "/logs/"
    },
    {
      "key": "HLL_REDIS_URL",
      "service": "supervisor",
      "description": "Full Redis connection URL used by the rq workers",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "LOGGING_LEVEL",
      "service": "supervisor",
      "description": "Log verbosity",
      "secret": false,
      "strategy": "default",
      "default": "INFO"
    },
    {
      "key": "SERVER_NUMBER",
      "service": "supervisor",
      "description": "CRCON server number",
      "secret": false,
      "strategy": "default",
      "default": "1"
    },
    {
      "key": "HLL_REDIS_HOST",
      "service": "supervisor",
      "description": "Redis private hostname",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_private_domain"
    },
    {
      "key": "HLL_REDIS_PORT",
      "service": "supervisor",
      "description": "Redis port",
      "secret": false,
      "strategy": "default",
      "default": "6379"
    },
    {
      "key": "HLL_DB_PASSWORD",
      "service": "supervisor",
      "description": "Postgres password, referenced from the postgres service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "HLL_DB_HOST_PORT",
      "service": "supervisor",
      "description": "Postgres port",
      "secret": false,
      "strategy": "default",
      "default": "5432"
    },
    {
      "key": "RCONWEB_API_SECRET",
      "service": "supervisor",
      "description": "Shared Django secret, referenced from the backend service",
      "secret": true,
      "strategy": "railway_provided",
      "railway_source": "reference_variable"
    },
    {
      "key": "RCONWEB_EXTERNAL_ADDRESS",
      "service": "supervisor",
      "description": "Public address of the admin UI",
      "secret": false,
      "strategy": "railway_provided",
      "railway_source": "railway_domain"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "hll-crcon-cloud"
      }
    },
    "cli": "railway deploy --template hll-crcon-cloud",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "e1fae538-feb1-4274-9888-27767d75fc38",
            "serializedConfig": {
              "buckets": {},
              "services": {
                "096e386a-c95e-4ecb-b505-f9dc5f239a23": {
                  "icon": "https://raw.githubusercontent.com/MarechJ/hll_rcon_tool/master/assets/hll/rcongui/android-chrome-512x512.png",
                  "name": "maintenance",
                  "deploy": {
                    "startCommand": "sh -c \"mkdir -p /logs && exec /code/entrypoint.sh maintenance\""
                  },
                  "source": {
                    "repo": "sledro/crcon.cloud",
                    "branch": "release",
                    "rootDirectory": "template/upstream"
                  },
                  "variables": {
                    "HLL_GAME": {
                      "description": "Game type; needed by database migrations",
                      "defaultValue": "${{backend.HLL_GAME}}"
                    },
                    "HLL_DB_URL": {
                      "description": "Full Postgres connection URL used by alembic",
                      "defaultValue": "postgresql://${{postgres.POSTGRES_USER}}:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_HOST": {
                      "description": "Postgres private hostname",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_DB_NAME": {
                      "description": "Postgres database name",
                      "defaultValue": "${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_USER": {
                      "description": "Postgres user, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_USER}}"
                    },
                    "HLL_REDIS_DB": {
                      "description": "Redis logical database for server 1",
                      "defaultValue": "1"
                    },
                    "HLL_REDIS_URL": {
                      "description": "Full Redis connection URL used by cache migrations",
                      "defaultValue": "redis://${{redis.RAILWAY_PRIVATE_DOMAIN}}:6379/1"
                    },
                    "SERVER_NUMBER": {
                      "description": "Server number; needed by database migrations",
                      "defaultValue": "1"
                    },
                    "HLL_REDIS_HOST": {
                      "description": "Redis private hostname",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_DB_PASSWORD": {
                      "description": "Postgres password, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "HLL_DB_HOST_PORT": {
                      "description": "Postgres port",
                      "defaultValue": "5432"
                    },
                    "HLL_REDIS_HOST_PORT": {
                      "description": "Redis port",
                      "defaultValue": "6379"
                    },
                    "HLL_MAINTENANCE_CONTAINER": {
                      "description": "Marks this container as the migration runner",
                      "defaultValue": "true"
                    }
                  }
                },
                "0b7b3cb6-a961-440e-bf7f-fb87e9838bce": {
                  "icon": "https://raw.githubusercontent.com/MarechJ/hll_rcon_tool/master/assets/hll/rcongui/android-chrome-512x512.png",
                  "name": "webhooks",
                  "deploy": {
                    "startCommand": "sh -c \"mkdir -p /logs && exec /code/entrypoint.sh webhook_service\""
                  },
                  "source": {
                    "repo": "sledro/crcon.cloud",
                    "branch": "release",
                    "rootDirectory": "template/upstream"
                  },
                  "variables": {
                    "HLL_DB_URL": {
                      "description": "Full Postgres connection URL",
                      "defaultValue": "postgresql://${{postgres.POSTGRES_USER}}:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_HOST": {
                      "description": "Postgres private hostname",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_DB_NAME": {
                      "description": "Postgres database name",
                      "defaultValue": "${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_USER": {
                      "description": "Postgres user, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_USER}}"
                    },
                    "LOGGING_PATH": {
                      "description": "Directory CRCON writes log files to",
                      "defaultValue": "/logs/"
                    },
                    "LOGGING_LEVEL": {
                      "description": "Log verbosity",
                      "defaultValue": "INFO"
                    },
                    "HLL_REDIS_HOST": {
                      "description": "Redis private hostname",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_REDIS_PORT": {
                      "description": "Redis port",
                      "defaultValue": "6379"
                    },
                    "HLL_DB_PASSWORD": {
                      "description": "Postgres password, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "HLL_DB_HOST_PORT": {
                      "description": "Postgres port",
                      "defaultValue": "5432"
                    },
                    "HLL_WH_LOOP_SLEEP_TIME": {
                      "description": "Event loop sleep between webhook sends",
                      "defaultValue": "0.006"
                    },
                    "HLL_WH_MAX_QUEUE_LENGTH": {
                      "description": "Maximum queued webhook messages",
                      "defaultValue": "150"
                    },
                    "HLL_WH_SERVICE_CONTAINER": {
                      "description": "Marks this container as the webhook dispatcher",
                      "defaultValue": "true"
                    },
                    "HLL_WH_SERVICE_RL_RESET_SECS": {
                      "description": "Webhook rate limit window in seconds",
                      "defaultValue": "3"
                    },
                    "HLL_WH_SERVICE_RL_TIME_WINDOW": {
                      "description": "Seconds to track external rate limit hits",
                      "defaultValue": "600"
                    },
                    "HLL_WH_SERVICE_RL_REQUESTS_PER": {
                      "description": "Requests allowed per rate limit window",
                      "defaultValue": "5"
                    }
                  }
                },
                "5ef2fb2d-9ea5-429d-a4c5-842126981721": {
                  "icon": "https://raw.githubusercontent.com/MarechJ/hll_rcon_tool/master/assets/hll/rcongui/android-chrome-512x512.png",
                  "name": "frontend",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "/",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "sledro/crcon.cloud",
                    "branch": "release",
                    "rootDirectory": "template/frontend"
                  },
                  "variables": {
                    "PORT": {
                      "description": "Tells Railway which port to healthcheck; nginx serves the admin UI on 80",
                      "defaultValue": "80"
                    },
                    "HLL_GAME": {
                      "isOptional": false,
                      "description": "Game type; selects which game assets nginx serves",
                      "defaultValue": "${{backend.HLL_GAME}}"
                    },
                    "CRCON_API_HOST": {
                      "isOptional": false,
                      "description": "Backend private hostname nginx proxies API and websocket traffic to",
                      "defaultValue": "${{backend.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "RCONWEB_EXTERNAL_ADDRESS": {
                      "isOptional": false,
                      "description": "This service's own public domain",
                      "defaultValue": "${{RAILWAY_PUBLIC_DOMAIN}}"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:80": {
                        "port": 80
                      },
                      "<hasDomain>:81": {
                        "port": 81
                      }
                    }
                  }
                },
                "6008c62e-c085-4e84-95e1-811c60b85bb5": {
                  "icon": "https://devicons.railway.app/i/redis.svg",
                  "name": "redis",
                  "deploy": {
                    "startCommand": "redis-server --save 60 1 --maxclients 100000",
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "redis:alpine"
                  },
                  "variables": {},
                  "volumeMounts": {
                    "6008c62e-c085-4e84-95e1-811c60b85bb5": {
                      "mountPath": "/data"
                    }
                  }
                },
                "8df7fb9b-b001-4e79-b80b-24f88a498661": {
                  "icon": "https://devicons.railway.app/i/postgresql.svg",
                  "name": "postgres",
                  "deploy": {
                    "startCommand": "docker-entrypoint.sh postgres -c max_connections=300",
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "postgres:12-alpine"
                  },
                  "variables": {
                    "PGDATA": {
                      "isOptional": false,
                      "description": "Postgres data directory inside the mounted volume",
                      "defaultValue": "/var/lib/postgresql/data/pgdata"
                    },
                    "POSTGRES_DB": {
                      "isOptional": false,
                      "description": "Database name created on first boot",
                      "defaultValue": "rcon"
                    },
                    "POSTGRES_USER": {
                      "isOptional": false,
                      "description": "Database superuser name",
                      "defaultValue": "rcon"
                    },
                    "POSTGRES_PASSWORD": {
                      "isOptional": false,
                      "description": "Generated database password; alphanumeric because CRCON forbids special characters",
                      "defaultValue": "{{POSTGRES_PASSWORD}}"
                    }
                  },
                  "volumeMounts": {
                    "8df7fb9b-b001-4e79-b80b-24f88a498661": {
                      "mountPath": "/var/lib/postgresql/data"
                    }
                  }
                },
                "9db38be5-43e9-4458-a684-4e99932f89b6": {
                  "icon": "https://raw.githubusercontent.com/MarechJ/hll_rcon_tool/master/assets/hll/rcongui/android-chrome-512x512.png",
                  "name": "backend",
                  "deploy": {
                    "startCommand": null,
                    "healthcheckPath": "",
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "sledro/crcon.cloud",
                    "branch": "release",
                    "rootDirectory": "template/backend"
                  },
                  "variables": {
                    "PORT": {
                      "isOptional": false,
                      "description": "Tells Railway which port to healthcheck; unused by CRCON",
                      "defaultValue": "8000"
                    },
                    "DOMAINS": {
                      "isOptional": false,
                      "description": "Django ALLOWED_HOSTS and CSRF origins, including Railway's healthcheck host",
                      "defaultValue": "${{frontend.RAILWAY_PUBLIC_DOMAIN}},${{RAILWAY_PRIVATE_DOMAIN}},healthcheck.railway.app"
                    },
                    "HLL_GAME": {
                      "isOptional": false,
                      "description": "Game type: hll, or hllv for Hell Let Loose Vietnam",
                      "defaultValue": "hll"
                    },
                    "HLL_HOST": {
                      "isOptional": false,
                      "description": "IP address of your Hell Let Loose game server (no port)",
                      "defaultValue": "{{HLL_HOST}}"
                    },
                    "HLL_PORT": {
                      "isOptional": false,
                      "description": "RCON port of your game server (not the game or query port)",
                      "defaultValue": "{{HLL_PORT}}"
                    },
                    "CONFIG_DIR": {
                      "isOptional": false,
                      "description": "Config directory expected by CRCON",
                      "defaultValue": "/config/"
                    },
                    "HLL_DB_URL": {
                      "isOptional": false,
                      "description": "Full Postgres connection URL",
                      "defaultValue": "postgresql://${{postgres.POSTGRES_USER}}:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_HOST": {
                      "isOptional": false,
                      "description": "Postgres private hostname",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_DB_NAME": {
                      "isOptional": false,
                      "description": "Postgres database name",
                      "defaultValue": "${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_USER": {
                      "isOptional": false,
                      "description": "Postgres user, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_USER}}"
                    },
                    "HLL_PASSWORD": {
                      "isOptional": false,
                      "description": "RCON password of your game server",
                      "defaultValue": "{{HLL_PASSWORD}}"
                    },
                    "HLL_REDIS_DB": {
                      "isOptional": false,
                      "description": "Redis logical database for this game server",
                      "defaultValue": "1"
                    },
                    "LOGGING_PATH": {
                      "isOptional": false,
                      "description": "Directory CRCON writes log files to",
                      "defaultValue": "/logs/"
                    },
                    "RCONWEB_PORT": {
                      "isOptional": false,
                      "description": "Display-only admin UI port shown in the interface",
                      "defaultValue": "443"
                    },
                    "HLL_REDIS_URL": {
                      "isOptional": false,
                      "description": "Full Redis connection URL",
                      "defaultValue": "redis://${{redis.RAILWAY_PRIVATE_DOMAIN}}:6379/1"
                    },
                    "LOGGING_LEVEL": {
                      "isOptional": false,
                      "description": "Log verbosity for CRCON",
                      "defaultValue": "INFO"
                    },
                    "SERVER_NUMBER": {
                      "isOptional": false,
                      "description": "CRCON server number; namespaces this server's data",
                      "defaultValue": "1"
                    },
                    "HLL_REDIS_HOST": {
                      "isOptional": false,
                      "description": "Redis private hostname",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_REDIS_PORT": {
                      "isOptional": false,
                      "description": "Redis port",
                      "defaultValue": "6379"
                    },
                    "NB_API_THREADS": {
                      "isOptional": false,
                      "description": "Threads per gunicorn worker",
                      "defaultValue": "8"
                    },
                    "NB_API_WORKERS": {
                      "isOptional": false,
                      "description": "Gunicorn worker count",
                      "defaultValue": "1"
                    },
                    "HLL_DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres password, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "HLL_DB_HOST_PORT": {
                      "isOptional": false,
                      "description": "Postgres port",
                      "defaultValue": "5432"
                    },
                    "PUBLIC_STATS_PORT": {
                      "isOptional": false,
                      "description": "Display-only public stats port",
                      "defaultValue": "80"
                    },
                    "RCONWEB_API_SECRET": {
                      "isOptional": false,
                      "description": "Django secret key encrypting sessions; never change after first deploy",
                      "defaultValue": "{{RCONWEB_API_SECRET}}"
                    },
                    "SUPERVISOR_RPC_URL": {
                      "isOptional": false,
                      "description": "Supervisord RPC endpoint used by the UI Services page",
                      "defaultValue": "http://${{supervisor.RAILWAY_PRIVATE_DOMAIN}}:9001/RPC2"
                    },
                    "CRCON_FRONTEND_HOST": {
                      "isOptional": false,
                      "description": "Frontend private hostname, aliased for the multi-server registry",
                      "defaultValue": "${{frontend.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "PUBLIC_STATS_PORT_HTTPS": {
                      "isOptional": false,
                      "description": "Display-only public stats HTTPS port",
                      "defaultValue": "443"
                    },
                    "RCONWEB_EXTERNAL_ADDRESS": {
                      "isOptional": false,
                      "description": "Public address of the admin UI",
                      "defaultValue": "${{frontend.RAILWAY_PUBLIC_DOMAIN}}"
                    }
                  }
                },
                "baddfe06-975e-488c-bff3-c93d5796e869": {
                  "icon": "https://raw.githubusercontent.com/MarechJ/hll_rcon_tool/master/assets/hll/rcongui/android-chrome-512x512.png",
                  "name": "supervisor",
                  "deploy": {
                    "startCommand": "sh -c \"mkdir -p /logs && exec /code/entrypoint.sh supervisor\"",
                    "healthcheckPath": null,
                    "restartPolicyType": "ON_FAILURE",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "repo": "sledro/crcon.cloud",
                    "branch": "release",
                    "rootDirectory": "template/supervisor"
                  },
                  "variables": {
                    "HLL_GAME": {
                      "isOptional": false,
                      "description": "Game type, referenced from the backend service",
                      "defaultValue": "${{backend.HLL_GAME}}"
                    },
                    "HLL_HOST": {
                      "isOptional": false,
                      "description": "Game server IP, referenced from the backend service",
                      "defaultValue": "${{backend.HLL_HOST}}"
                    },
                    "HLL_PORT": {
                      "isOptional": false,
                      "description": "Game server RCON port, referenced from the backend service",
                      "defaultValue": "${{backend.HLL_PORT}}"
                    },
                    "HLL_DB_URL": {
                      "isOptional": false,
                      "description": "Full Postgres connection URL",
                      "defaultValue": "postgresql://${{postgres.POSTGRES_USER}}:${{postgres.POSTGRES_PASSWORD}}@${{postgres.RAILWAY_PRIVATE_DOMAIN}}:5432/${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_HOST": {
                      "isOptional": false,
                      "description": "Postgres private hostname",
                      "defaultValue": "${{postgres.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_DB_NAME": {
                      "isOptional": false,
                      "description": "Postgres database name",
                      "defaultValue": "${{postgres.POSTGRES_DB}}"
                    },
                    "HLL_DB_USER": {
                      "isOptional": false,
                      "description": "Postgres user, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_USER}}"
                    },
                    "HLL_PASSWORD": {
                      "isOptional": false,
                      "description": "Game server RCON password, referenced from the backend service",
                      "defaultValue": "${{backend.HLL_PASSWORD}}"
                    },
                    "HLL_REDIS_DB": {
                      "isOptional": false,
                      "description": "Redis logical database for this game server",
                      "defaultValue": "1"
                    },
                    "LOGGING_PATH": {
                      "isOptional": false,
                      "description": "Directory CRCON writes log files to",
                      "defaultValue": "/logs/"
                    },
                    "HLL_REDIS_URL": {
                      "isOptional": false,
                      "description": "Full Redis connection URL used by the rq workers",
                      "defaultValue": "redis://${{redis.RAILWAY_PRIVATE_DOMAIN}}:6379/1"
                    },
                    "LOGGING_LEVEL": {
                      "isOptional": false,
                      "description": "Log verbosity",
                      "defaultValue": "INFO"
                    },
                    "SERVER_NUMBER": {
                      "isOptional": false,
                      "description": "CRCON server number",
                      "defaultValue": "1"
                    },
                    "HLL_REDIS_HOST": {
                      "isOptional": false,
                      "description": "Redis private hostname",
                      "defaultValue": "${{redis.RAILWAY_PRIVATE_DOMAIN}}"
                    },
                    "HLL_REDIS_PORT": {
                      "isOptional": false,
                      "description": "Redis port",
                      "defaultValue": "6379"
                    },
                    "HLL_DB_PASSWORD": {
                      "isOptional": false,
                      "description": "Postgres password, referenced from the postgres service",
                      "defaultValue": "${{postgres.POSTGRES_PASSWORD}}"
                    },
                    "HLL_DB_HOST_PORT": {
                      "isOptional": false,
                      "description": "Postgres port",
                      "defaultValue": "5432"
                    },
                    "RCONWEB_API_SECRET": {
                      "isOptional": false,
                      "description": "Shared Django secret, referenced from the backend service",
                      "defaultValue": "${{backend.RCONWEB_API_SECRET}}"
                    },
                    "RCONWEB_EXTERNAL_ADDRESS": {
                      "isOptional": false,
                      "description": "Public address of the admin UI",
                      "defaultValue": "${{frontend.RAILWAY_PUBLIC_DOMAIN}}"
                    }
                  },
                  "volumeMounts": {
                    "baddfe06-975e-488c-bff3-c93d5796e869": {
                      "mountPath": "/scoreboard_db"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "frontend",
      "method": "GET",
      "path": "/",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 7,
    "needs_volume": true
  },
  "generated_at": "2026-09-20T10:14:37.339Z",
  "generator_version": "0.1.0"
}
