{
  "manifest_version": "1.0.0",
  "template": {
    "id": "9e98334b-3711-4bb6-ae68-e4d4ddc2b021",
    "slug": "deploy-sillytavern-with-deepseek",
    "name": "Deploy SillyTavern with DeepSeek",
    "description": "Chat with DeepSeek models in your own SillyTavern",
    "url": "https://railway.com/deploy/deploy-sillytavern-with-deepseek",
    "upstream": {
      "image": "ghcr.io/sillytavern/sillytavern:1.19.0@sha256:eef27ff0c7961f1a2f488400f581f48ff38f8b910c5d3b8d389138d71791bb14"
    }
  },
  "status": "unvalidated",
  "validated_at": null,
  "success_rate_30d": null,
  "services": [
    {
      "name": "SillyTavern",
      "source": {
        "image": "ghcr.io/sillytavern/sillytavern:1.19.0@sha256:eef27ff0c7961f1a2f488400f581f48ff38f8b910c5d3b8d389138d71791bb14"
      },
      "needs_volume": true,
      "volume_mount_path": "/home/node/app/data",
      "http": true
    }
  ],
  "required_inputs": [
    {
      "key": "PGID",
      "service": "SillyTavern",
      "description": "Group id SillyTavern runs as (1000 = node).",
      "secret": false,
      "strategy": "default",
      "default": "1000"
    },
    {
      "key": "PORT",
      "service": "SillyTavern",
      "description": "Port the public domain routes to; keep it equal to SILLYTAVERN_PORT.",
      "secret": false,
      "strategy": "default",
      "default": "8000"
    },
    {
      "key": "PUID",
      "service": "SillyTavern",
      "description": "User id SillyTavern runs as (1000 = node) instead of root.",
      "secret": false,
      "strategy": "default",
      "default": "1000"
    },
    {
      "key": "ADMIN_PASSWORD",
      "service": "SillyTavern",
      "description": "Password of the admin account default-user, generated per deploy and re-applied on every boot. Copy it from this Variables tab to log in.",
      "secret": true,
      "strategy": "generate",
      "generate": "strong_password"
    },
    {
      "key": "SILLYTAVERN_PORT",
      "service": "SillyTavern",
      "description": "Port SillyTavern listens on (config.yaml port).",
      "secret": false,
      "strategy": "default",
      "default": "8000"
    },
    {
      "key": "SILLYTAVERN_LISTEN",
      "service": "SillyTavern",
      "description": "Listen on all interfaces (0.0.0.0) so Railway can reach the server.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "SILLYTAVERN_BASICAUTHMODE",
      "service": "SillyTavern",
      "description": "Extra HTTP basic-auth prompt off; user accounts already require a login.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "SILLYTAVERN_WHITELISTMODE",
      "service": "SillyTavern",
      "description": "IP whitelist off; it would block everyone behind Railway's proxy. Accounts protect the instance instead.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "SILLYTAVERN_ENABLEUSERACCOUNTS",
      "service": "SillyTavern",
      "description": "User accounts with a login page and per-user data; keeps the public URL protected.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    },
    {
      "key": "SILLYTAVERN_HOSTWHITELIST_SCAN",
      "service": "SillyTavern",
      "description": "Don't log a warning for every new Host header (Railway domain, healthcheck, custom domains).",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "SILLYTAVERN_BROWSERLAUNCH_ENABLED",
      "service": "SillyTavern",
      "description": "Don't try to open a desktop browser when the server starts.",
      "secret": false,
      "strategy": "default",
      "default": "false"
    },
    {
      "key": "SILLYTAVERN_RATELIMITING_PREFERREALIPHEADER",
      "service": "SillyTavern",
      "description": "Rate-limit logins per real client IP from Railway's forwarded headers, not per proxy.",
      "secret": false,
      "strategy": "default",
      "default": "true"
    }
  ],
  "deploy": {
    "mcp": {
      "server": "railway",
      "tool": "deploy_template",
      "args": {
        "template_code": "deploy-sillytavern-with-deepseek"
      }
    },
    "cli": "railway deploy --template deploy-sillytavern-with-deepseek",
    "api": {
      "method": "POST",
      "path": "/graphql/v2",
      "body": {
        "query": "mutation templateDeploy($input: TemplateDeployV2Input!) { templateDeployV2(input: $input) { projectId workflowId } }",
        "variables": {
          "input": {
            "templateId": "9e98334b-3711-4bb6-ae68-e4d4ddc2b021",
            "serializedConfig": {
              "services": {
                "9df6e372-7f80-4a7f-a3de-c3dd5b694dd8": {
                  "icon": null,
                  "name": "SillyTavern",
                  "deploy": {
                    "startCommand": "/bin/sh -c 'set -e; cd /home/node/app; R=/home/node/app/data/_railway; if [ \"$(stat -c %u data)\" != 1000 ]; then chown -R 1000:1000 data; echo \"volume: data handed to node (uid 1000)\"; fi; su-exec node mkdir -p \"$R/config\" \"$R/extensions\" \"$R/plugins\"; for p in config:config plugins:plugins public/scripts/extensions/third-party:extensions; do s=\"${p%%:*}\"; t=\"$R/${p##*:}\"; if [ ! -L \"$s\" ]; then [ -d \"$s\" ] && su-exec node cp -an \"$s/.\" \"$t/\"; rm -rf \"$s\"; ln -s \"$t\" \"$s\"; chown -h 1000:1000 \"$s\"; fi; done; if [ ! -e config/config.yaml ]; then su-exec node cp default/config.yaml config/config.yaml; echo \"config: seeded data/_railway/config/config.yaml from defaults\"; fi; if [ -n \"$ADMIN_PASSWORD\" ]; then H=\"${ADMIN_HANDLE:-default-user}\"; if su-exec node node recover.js \"$H\" \"$ADMIN_PASSWORD\" >/dev/null; then echo \"accounts: password for $H set from ADMIN_PASSWORD\"; else echo \"accounts: could not set password for $H\" >&2; fi; fi; exec tini -- ./docker-entrypoint.sh'",
                    "healthcheckPath": "/login",
                    "restartPolicyType": "ALWAYS",
                    "restartPolicyMaxRetries": 10
                  },
                  "source": {
                    "image": "ghcr.io/sillytavern/sillytavern:1.19.0@sha256:eef27ff0c7961f1a2f488400f581f48ff38f8b910c5d3b8d389138d71791bb14"
                  },
                  "variables": {
                    "PGID": {
                      "isOptional": false,
                      "description": "Group id SillyTavern runs as (1000 = node).",
                      "defaultValue": "1000"
                    },
                    "PORT": {
                      "isOptional": false,
                      "description": "Port the public domain routes to; keep it equal to SILLYTAVERN_PORT.",
                      "defaultValue": "8000"
                    },
                    "PUID": {
                      "isOptional": false,
                      "description": "User id SillyTavern runs as (1000 = node) instead of root.",
                      "defaultValue": "1000"
                    },
                    "ADMIN_PASSWORD": {
                      "isOptional": false,
                      "description": "Password of the admin account default-user, generated per deploy and re-applied on every boot. Copy it from this Variables tab to log in.",
                      "defaultValue": "{{ADMIN_PASSWORD}}"
                    },
                    "SILLYTAVERN_PORT": {
                      "isOptional": false,
                      "description": "Port SillyTavern listens on (config.yaml port).",
                      "defaultValue": "8000"
                    },
                    "SILLYTAVERN_LISTEN": {
                      "isOptional": false,
                      "description": "Listen on all interfaces (0.0.0.0) so Railway can reach the server.",
                      "defaultValue": "true"
                    },
                    "SILLYTAVERN_BASICAUTHMODE": {
                      "isOptional": false,
                      "description": "Extra HTTP basic-auth prompt off; user accounts already require a login.",
                      "defaultValue": "false"
                    },
                    "SILLYTAVERN_WHITELISTMODE": {
                      "isOptional": false,
                      "description": "IP whitelist off; it would block everyone behind Railway's proxy. Accounts protect the instance instead.",
                      "defaultValue": "false"
                    },
                    "SILLYTAVERN_ENABLEUSERACCOUNTS": {
                      "isOptional": false,
                      "description": "User accounts with a login page and per-user data; keeps the public URL protected.",
                      "defaultValue": "true"
                    },
                    "SILLYTAVERN_HOSTWHITELIST_SCAN": {
                      "isOptional": false,
                      "description": "Don't log a warning for every new Host header (Railway domain, healthcheck, custom domains).",
                      "defaultValue": "false"
                    },
                    "SILLYTAVERN_BROWSERLAUNCH_ENABLED": {
                      "isOptional": false,
                      "description": "Don't try to open a desktop browser when the server starts.",
                      "defaultValue": "false"
                    },
                    "SILLYTAVERN_RATELIMITING_PREFERREALIPHEADER": {
                      "isOptional": false,
                      "description": "Rate-limit logins per real client IP from Railway's forwarded headers, not per proxy.",
                      "defaultValue": "true"
                    }
                  },
                  "networking": {
                    "serviceDomains": {
                      "<hasDomain>:8000": {
                        "port": 8000
                      }
                    }
                  },
                  "volumeMounts": {
                    "9df6e372-7f80-4a7f-a3de-c3dd5b694dd8": {
                      "mountPath": "/home/node/app/data"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "post_deploy": {
    "healthcheck": {
      "service": "SillyTavern",
      "method": "GET",
      "path": "/login",
      "expect_status": 200
    }
  },
  "resources": {
    "expected_services": 1,
    "needs_volume": true
  },
  "generated_at": "2026-10-31T04:14:55.520Z",
  "generator_version": "0.1.0"
}
