# Provisioning & Going Live

> Stand up your live Seedly Sites instance - Railway for the CMS and database, Cloudflare Pages and R2 for hosting and media, GitHub for deploys.

The local sandbox from the [Install guide](/docs/help/install) proves everything works. Going live moves the same platform onto real infrastructure so client sites are on the internet with their own domains.

Your `SETUP/` handbook covers this in detail (chapters 04 through 13, including screenshots-level hand-holding for each provider). This page is the map: what you are creating, where, and how to verify it.

---

## What a Live Instance Looks Like

| Piece | Where It Runs | What It Does |
|-------|--------------|-------------|
| **CMS service** | Railway | Your admin, the portal, the API. The thing you log into |
| **Postgres** | Railway | The production database (replaces the local sandbox's file database) |
| **Studio (pagebuilder) service** | Railway | Serves the visual builder and page preview; the CMS proxies to it so the builder is same-origin |
| **Pages projects** | Cloudflare Pages | Static hosting - one project per client site |
| **R2 bucket** | Cloudflare | Durable storage for uploaded media |
| **Private repo + deploy workflow** | GitHub | Your copy of the code, plus the automated job that builds and deploys a client site when you click Deploy |

See [Architecture](/docs/architecture) for how the pieces talk to each other.

---

## The Provisioning Steps

Work through these in order. Each step is one provider account plus a few values you copy into the platform's environment settings.

### 1. Put your code in a private GitHub repo

Your download becomes a private repository you own. The deploy pipeline (a GitHub Action in that repo) is what builds and publishes client sites. You will create a personal access token so the platform can trigger that workflow, and point the platform at your repo. Set your OWN repo here - the readiness check flags this value if it is still the vendor default.

### 2. Create the Railway project

Three services: the **cms** app, a **Postgres** database, and the **pagebuilder** studio. Point the cms service at Postgres and switch it to the production database adapter, then wire the CMS to the studio via its internal URL so the builder loads in production.

### 3. Create the Cloudflare pieces

An **R2 bucket** for media (with access keys and a public URL for serving files), and an **API token** that lets the platform auto-create a Pages project per client site. You also add these as GitHub Actions secrets so the deploy workflow can push builds to Pages.

### 4. Generate and set your secrets

```
npx pnpm run gen:secrets
```

generates the platform's own secret values (session signing, cron auth, and the rest). Put app-owned secrets and config on the Railway **cms** service; put the deploy credentials in GitHub Actions secrets. The [Environment Variables reference](/docs/help/env-vars) explains the purpose of every value. Keep a copy of everything in a password manager - see [Backups](/docs/help/backups).

### 5. Set up email

Auth email (password resets, invitations, verification) sends through SendGrid. Create a restricted API key with mail-send permission, verify your sending domain, and set the key and From address on the cms service. Until it is set, the platform runs fine but those emails are logged instead of sent.

### 6. Point DNS

Your CMS gets a hostname (a CNAME at your registrar pointing at Railway). Each client site's custom domain is a CNAME to its Cloudflare Pages project, added both in Cloudflare and on the tenant in your portal. See [Hosting & Domains](/docs/help/hosting-domains).

### 7. Optional keys

- **Anthropic API key** - powers AI site generation, port revision, and visual QA
- **Stripe keys** - only if you want [native tenant billing](/docs/help/billing)
- **Google Places / Maps embed keys** - richer location capture and map cards
- **Sentry DSN** - error monitoring

Everything optional fails soft: the platform runs, the feature is simply inert until the key exists.

---

## The Doctor

At any point, from the project folder:

```
npx pnpm run setup:check -- --target=prod
```

It prints READY or NOT READY and names each missing or misconfigured value in plain English. Work top-down through the red lines; set each value on the correct service and redeploy. This is also the first thing to run when anything feels off later.

The guided alternative for a fresh instance is `npx pnpm run provision`, which walks the whole sequence. Provisioning is fresh-instance only: it refuses to run against an already-live setup, on purpose.

---

## First Login and First Site

Once the doctor says READY:

1. Create your operator (super-admin) account and log in to your live CMS.
2. Create your first client site in the portal ([Managing Sites](/docs/help/tenants)).
3. Build or [port](/docs/help/port-a-site) its pages, publish, and click **Deploy**.
4. Confirm the deployed site loads on its Pages URL, then attach the custom domain.

Remember the platform rule: publishing content never deploys anything by itself. The site goes live, and gets updated, only when you deploy it. See [Preview, Publish, Deploy](/docs/help/preview-publish).

---

## After Launch

- Enable Postgres backups on Railway and do one restore drill early ([Backups](/docs/help/backups))
- Read [Updating](/docs/help/updates) before your first version update
- Keep the leaked-key rule: if a secret ever ends up somewhere it should not, rotate it at the provider and update it everywhere it is stored

---
Source: https://seedlysites.com/docs/help/provisioning
