Free-Tier Stack
This recipe runs the engine and a Postgres database at $0 a month: one free account for the
engine, one for the database, wired together with a handful of environment variables. The
result is a headless engine over HTTPS, managed with curl or your own tooling.
It suits a demo, a staging environment or a low-traffic project. To compare it with the other
ways to run LyEve, see Choose where to run LyEve.
Before you start
Section titled “Before you start”- An account on an engine host with a free plan: Render or Google Cloud Run. Each publishes one of the two APIs. Railway and Fly.io publish both, but they bill by usage after a trial.
- An account on Supabase or Neon for the database.
opensslandcurlon your machine.
-
Create the database. Make a free Postgres project and copy the connection string its page recommends: the session pooler on Supabase, the direct string on Neon.
-
Generate the secrets. Run this three times and keep each value somewhere durable:
Terminal window openssl rand -hex 32 -
Deploy the engine image
ghcr.io/lyeve-labs/lyeve-coreon your engine host, following its page, with these variables:DATABASE_URL=<the connection string from step 1>DATABASE_MAX_CONNECTIONS=5JWT_SECRET=<first secret>ENCRYPTION_KEY=<second secret>LYEVE_AUDIT_HMAC_KEY=<third secret>RATE_LIMIT_RPS=100SECURE_COOKIE=trueCORS_ORIGINS=https://your-app.example.comAPP_ENVdefaults toproduction, which refuses to start without the secrets,RATE_LIMIT_RPSandSECURE_COOKIE=true. Configuration lists every check.CORS_ORIGINSnames the browser apps that will call the Content API. -
Check the engine. Ask the Content API for the engine's public key, or ask the Admin API whether setup is needed, whichever your host publishes:
Terminal window curl https://<content-api-url>/.well-known/jwks.jsoncurl https://<admin-api-url>/api/admin/setupThe Admin API answers
{"setup_required":true,"token_source":"log"}. The setup token is the one-timesetup_tokenthe engine printed to its log at startup. -
Create the first administrator. Follow the quickstart from step 2, against your Admin API URL. On a host that publishes one API, publish port
3001for this step.
Limits of the free stack
Section titled “Limits of the free stack”- Cold starts. Both free engine hosts stop the container after a period with no traffic:
Render free web services, and Cloud Run with
--min-instances=0. The first request after that waits for the engine to start and reconnect to the database. On Neon the database may be resuming too. - Signing out on restart. The engine keeps its signing key at
JWT_KEY_PATH(/var/lib/lyeve/jwt_key.json) and creates a new one when the file is missing. On a host with no persistent disk, every cold start or redeploy makes a new key, and every token issued before it stops working. Where the host offers a volume, mount it at/var/lib/lyeve, writable by uid65532. - One engine service. Two services started from the image each create their own key, so a token from one is refused by the other. Do not run a second service to publish the other port.
- Connection limits. Free Postgres plans cap connections. Keep
DATABASE_MAX_CONNECTIONSsmall, because a redeploy can briefly run the old and new engine side by side. - No disk for media. Uploads stored on local disk, the default, are lost at a cold start or a redeploy. Store them in an S3-compatible bucket. See Object storage.
- No admin console. The console needs a host that runs a second container behind a proxy. See The admin console needs a server.
- No SQLite. SQLite, Turso and libSQL cannot replace the database. See supported databases.
- Production checklist before real data goes behind it.
- Docker Compose to add the admin console on a server you control.