Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ TURBO_STATE_DIR:-*

# Plugin build artifacts — shipped via GitHub Releases, not committed
plugin/dist/

# Railway deploy state (contains generated secrets)
railway/.deploy-state
.railway/
143 changes: 113 additions & 30 deletions railway/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
# Railway template
# Railway deploy

One-click Railway deploy for the REVA-OPS stack.

**Single Railway project. Single public endpoint (`/mcp`). Multiple internal services.**

## What gets deployed
One Railway project, three application services, three managed databases.
Only `mcp-router` has a public domain — everything else is on Railway's
private network (`*.railway.internal`).

```
┌─────────────────────── Railway project ───────────────────────┐
│ │
│ PUBLIC │
│ ┌──────────────────┐ │
│ │ mcp-router │ ← reva-turbo plugin points here │
│ │ services/... │ https://<router>.up.railway.app/mcp │
│ │ /mcp + /signup │ https://<router>.up.railway.app/mcp │
│ └────────┬─────────┘ │
│ │ (Railway private network, *.railway.internal) │
│ ┌────────▼─────────┐ ┌──────────────────┐ │
Expand All @@ -22,43 +20,128 @@ One-click Railway deploy for the REVA-OPS stack.
│ │ │ │ │
│ ┌─────▼─────┐ ┌─────▼─────┐ ┌──▼────────┐ │
│ │ Postgres │ │ FalkorDB │ │ Qdrant │ │
│ │ (plugin) │ │ (plugin) │ │ (plugin) │ │
│ └───────────┘ └───────────┘ └───────────┘ │
└────────────────────────────────────────────────────────────────┘
```

## Files

- `template.yaml` — Railway template manifest (services, envs, plugins, build
refs)
- `deploy.sh` — CLI path: clone, provision, seed, print the public URL + API
key. Use this when you want a repeatable deploy you can script against.
- `env.example` — everything the template prompts for
- `deploy.sh` — phased deploy script against the Railway CLI (4.40+)
- `template.yaml` — reference spec for the stack. Not executable — Railway
CLI doesn't deploy from a local YAML; use `deploy.sh` for reproducibility
or the web UI for manual clicks.
- `.deploy-state` — generated secrets (gitignored)

## Prerequisites

```bash
# CLI
brew install railwayapp/railway/railway # macOS
# or: npm i -g @railway/cli

railway login # browser-based OAuth
railway whoami # sanity check

# Other deps
brew install jq openssl
```

**Authorize Railway's GitHub App for the `mrdulasolutions` org.** Railway
installs its GitHub App inline the first time you add a repo-sourced
service, so there is no standalone "Integrations" page to click. Until
the app is installed for the org, `railway add --repo` returns
`Unauthorized`.

Trigger the install by adding the first service through the web UI:

## One-click deploy
1. Open the `reva-ops` project dashboard → `+ Create` → **GitHub Repo**
2. Pick `mrdulasolutions/NakatomiCRM`. If it isn't listed, click the
**Configure GitHub App** link Railway shows and grant access to
`NakatomiCRM` **and** `automem` (or the whole `mrdulasolutions` org)
3. Name the service exactly **`nakatomi-backend`** (env var wiring
depends on this name)
4. Repeat for `mrdulasolutions/automem` → name **`automem-backend`**

Click the button in the root `README.md`. Railway reads `template.yaml`,
provisions the three plugins, spins up all three services, runs the
Nakatomi migrations, and seeds the Rev A schema.
Don't configure env vars in the UI; `deploy.sh services` sets all of
them via CLI after the services exist.

## CLI deploy (recommended for admins)
## Deploy (phased)

`deploy.sh` is broken into phases so you can inspect Railway's state
between steps. Run without arguments for the whole flight, or pass a
specific phase name to retry one.

```bash
# from repo root
./railway/deploy.sh --project-name reva-ops --admin-email you@reva.com
# → prints:
# public MCP url: https://<router>.up.railway.app/mcp
# admin api key: nk_...
# Save both. The plugin's install.sh will prompt you for them.
# Phase 1: create project + provision DBs (Postgres, FalkorDB, Qdrant)
./railway/deploy.sh init

# Phase 2: add & configure nakatomi-backend, automem-backend, mcp-router
# (sets private-network URLs, mints API tokens, generates router
# public domain, runs `railway up` for the router from
# services/mcp-router)
./railway/deploy.sh services

# Phase 3: seed Nakatomi admin user + Rev A pipeline/custom fields
./railway/deploy.sh seed --admin-email you@reva-mfg.com

# Phase 4: print the public MCP URL, admin creds, and PM signup token
./railway/deploy.sh finalize

# Or do all four in order:
./railway/deploy.sh --admin-email you@reva-mfg.com
```

## After deploy
After `init`, this directory is linked to the project via `.railway/`;
every subsequent `railway` command auto-discovers it.

## What you hand out to PMs

Point the REVA-TURBO plugin at the new stack:
Two things only:

1. **Signup URL** — `https://<router>.up.railway.app/signup`
2. **Signup token** — the `REVA_SIGNUP_TOKEN` value printed by
`deploy.sh finalize` (or read from `.deploy-state`)

PMs mint their own `nk_...` API keys from that page. You don't share your
admin key with anyone.

## Rotating the signup token

```bash
railway variables --service mcp-router --set "REVA_SIGNUP_TOKEN=$(openssl rand -hex 16)"
# Old token stops working on the next deploy. Existing PMs are unaffected
# (their API keys don't depend on the signup token after mint).
```

## If something fails mid-flight

Each phase is independently re-runnable:

```bash
curl -fsSL https://raw.githubusercontent.com/mrdulasolutions/RevOps-RevAMfg/main/plugin/install.sh \
| REVA_MCP_URL=https://<router>.up.railway.app/mcp \
REVA_API_KEY=nk_... \
bash
./railway/deploy.sh services # re-runs service adds (idempotent — `railway add` errors on dupes, which the script tolerates)
./railway/deploy.sh seed # retry just the seed if Nakatomi wasn't ready the first time
```

Logs:

```bash
railway logs --service mcp-router
railway logs --service nakatomi-backend
railway logs --service automem-backend
```

## Manual fallback (web UI)

If the CLI path fails and you need to unblock, you can click the same
topology together in the Railway dashboard:

1. Create project `reva-ops`
2. Add Postgres, FalkorDB (`falkordb/falkordb:latest`), Qdrant
(`qdrant/qdrant:latest`) as services
3. Add GitHub-source services `nakatomi-backend` (`mrdulasolutions/NakatomiCRM`)
and `automem-backend` (`mrdulasolutions/automem`)
4. Add `mcp-router`: either point at `mrdulasolutions/RevOps-RevAMfg` with
Root Directory = `services/mcp-router`, or deploy via CLI from the local
subdir (`cd services/mcp-router && railway up`)
5. Copy the env-var blocks from `deploy.sh` phase 2 into the dashboard
6. Run the seed commands from phase 3 via `railway run`
Loading
Loading