● Ship · Hosting
Deployment
Vercel or your own server.
Two supported ways to put THESIS online. Vercel needs Postgres for the admin; your own server can use a local SQLite file. Either way, serve it over HTTPS.
01Vercel
- Import the projectPush the folder to your own Git repository and import it in Vercel.
vercel.jsonalready sets the build (pnpm build), output (dist), the/appand/adminrewrites,/api/*and/admin/api/*to the functionapi/[...path].ts(60 s limit) and the security headers. - Postgres RequiredCreate a Postgres 14+ database (for example Neon from the Vercel marketplace) and set
DATABASE_URLto its pooled connection string withsslmode=require. The admin creates itsmk_admin_*tables on first use. There is no SQLite on Vercel. - Blob RecommendedStorage → create a private Blob store and connect it; that sets
BLOB_READ_WRITE_TOKEN. Without it the aggregate counters live in/tmpand reset on cold starts, and the Status page says so. A public store needsTHESIS_BLOB_ACCESS=public. - Environment variables
ADMIN_SECRET_KEY(openssl rand -hex 32),DATABASE_URL, optionallyANTHROPIC_API_KEY. - Deploy, then create the ownerOpen
/adminonce so a function starts, then open the deployment's Logs (orvercel logs <deployment-url>) and search forsetup code. Every cold start before the owner exists prints its own code; any printed code works (next steps). - DomainProject → Settings → Domains. Add your domain and follow the DNS instructions.
Visitor country for blocking live modes comes from Vercel's x-vercel-ip-country header (or cf-ipcountry behind Cloudflare).
02Your own server
- Build on the server
pnpm install pnpm build - SettingsCreate
.env(how). WithoutDATABASE_URLthe admin uses SQLite inTHESIS_DATA_DIR; back that folder up. - Keep it runningUse a process manager. The command it should run, from the project folder:
The process manager must supply the variables frompnpm run server.env: with systemd,EnvironmentFile=/path/to/thesis/.envandExecStart=/usr/bin/env pnpm run server; by hand,set -a && . ./.env && set +a && pnpm run server. - HTTPS in frontPut a reverse proxy (Caddy, nginx) in front of port
8787, setTHESIS_HOST=127.0.0.1so only the proxy can reach it, and setTHESIS_TRUST_PROXY=1so rate limits and theSecurecookie see the real client and scheme.
No country blocking without a header
On a bare server there is no country header, so nobody is geo-blocked. If you rely on blocked countries, run behind Cloudflare (which adds cf-ipcountry) or on Vercel.
Security headers
vercel.json sets a strict Content-Security-Policy (only Hyperliquid and api.telegram.org may be contacted by the browser), X-Frame-Options: DENY and more. The Node server applies its own policy from server/csp.ts. If you add another service the browser must reach, add it to both.
03Before you open it to users
- Owner created, two-factor on,
ADMIN_SECRET_KEYbacked up. - Status page: no blockers.
- Your own risk notice in Legal; your terms linked from the landing copy if you need them.
- Blocked countries reviewed; mainnet left off until you have tested on testnet yourself.
- AI daily cap set to a budget you accept.