> ## Documentation Index
> Fetch the complete documentation index at: https://phidatainc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Run on Railway

> Deploy your agent platform to Railway with JWT auth on.

Your company probably has a set way of running software. Follow that. If you're looking for a place to test this out without going through the full DevOps process, Railway is a good option, and the template includes scripts to:

* Deploy to Railway: `./scripts/railway/up.sh`
* Sync environment variables: `./scripts/railway/env-sync.sh`
* Redeploy the app: `./scripts/railway/redeploy.sh`

## Prerequisites

* A [Railway](https://railway.com) account
* The [Railway CLI](https://docs.railway.com/cli#installing-the-cli) installed and authenticated (`railway login`)

## Why JWT is on by default

Token-Based Authorization is **ON** by default. Without a `JWT_VERIFICATION_KEY` (or `JWT_JWKS_FILE`), the app refuses to serve traffic in production. This is why the deploy script stops and asks you for a key.

Token-Based Auth gives you three things:

* **Protected application routes.** Requests to agent, team, workflow, and data routes require a valid token.
* **Per-request identity.** Middleware parses the token and exposes `user_id`, `session_id`, and custom claims to protected routes.
* **Granular permissions.** A user token can be scoped to run a single agent. An admin token can read all sessions and test any agent.

AgentOS leaves its operational and API-documentation routes public: `/`, `/health`, `/info`, `/docs`, `/redoc`, `/openapi.json`, and `/docs/oauth2-redirect`.

## Deploy your agent platform to Railway

<Steps>
  <Step title="Configure your production environment">
    The deploy and sync scripts read `.env.production`. This keeps local and production values separate: different OpenAI keys with different budgets, production-only credentials, a different Slack workspace.

    ```bash theme={null}
    cp .env .env.production
    ```

    Edit `.env.production` with a production OpenAI key.
  </Step>

  <Step title="Provision and deploy">
    ```bash theme={null}
    ./scripts/railway/up.sh
    ```

    This script:

    1. Creates a Railway project for your agent platform.
    2. Provisions a Postgres service (with pgvector) and a persistent volume.
    3. Creates the `agent-os` service and forwards the database connection vars.
    4. Issues your public Railway domain and sets `AGENTOS_URL` to it, on Railway and in `.env.production`.
    5. Pauses and asks for a JWT verification key.
    6. Builds and deploys from the current directory.

    The domain takes a few minutes to start resolving after the first deploy.
  </Step>

  <Step title="Mint your verification key">
    [os.agno.com](https://os.agno.com) can generate the keypair while the script waits:

    1. Click **Connect OS** → **Live** and enter your Railway domain.
    2. Name it **Live Agent Platform**, turn on **Token-Based Authorization (JWT)** on the connection panel, and connect. The UI generates an RSA keypair, keeps the private key, and shows you the public key. If the OS is already connected, enable the setting under **Settings** → **OS & Security**.
    3. Paste the public key into the script prompt. The script saves it to `.env.production` and sets it on Railway, then deploys.

    <Note>
      Live AgentOS connections are a paid feature. Use code `PLATFORM30` for one month off.
    </Note>

    You can also bring your own keypair. Generate an RSA keypair, sign tokens with the private key in your own auth service, and put the matching public key in `JWT_VERIFICATION_KEY`. The middleware verifies RS256 by default. For another algorithm, set `algorithm` in `authorization_config`.
  </Step>

  <Step title="Confirm it's live">
    ```bash theme={null}
    railway logs --service agent-os
    ```

    Once you see successful requests, open `https://<your-app>.up.railway.app/docs` and you're live.
  </Step>
</Steps>

## Auto-deploys from GitHub

By default every code update needs `./scripts/railway/redeploy.sh`. To auto-deploy on every push to `main`:

1. Open the Railway dashboard → your project → the `agent-os` service → **Settings**.
2. Under **Source**, click **Connect Repo** and pick your repo.
3. Set the deploy branch to `main`.

Push to `main` now triggers a build and deploy. `./scripts/railway/env-sync.sh` is still how you push env changes.

## Opting out of JWT (not recommended)

If you must run production without auth (inside a private VPC behind another auth layer), set `authorization=False` in `app/main.py` and redeploy. Keep authorization on for any deploy holding real data. Without it, anyone who guesses your Railway domain can read your sessions and run your agents.

## Scaling

The default deploy is one replica with 4 GiB of memory and 2 vCPU. Change `numReplicas` and `limits` in `railway.json` as your load and availability requirements grow.

## Operations

| Task                                   | Command                                     |
| -------------------------------------- | ------------------------------------------- |
| Tail logs                              | `railway logs --service agent-os`           |
| Open the Railway dashboard             | `railway open`                              |
| Run a command with production env vars | `railway run --service agent-os <command>`  |
| Push env changes                       | `./scripts/railway/env-sync.sh`             |
| Redeploy without git push              | `./scripts/railway/redeploy.sh`             |
| Tear everything down                   | Delete the project in the Railway dashboard |

<Warning>
  Deleting the Railway project removes the app, the database, and all data.
</Warning>

## Next

[Lock in behavior with evals →](/agent-platform/evals)
