03 / Develop · Shell · Run

Run the Shell ​

Clone the repo, bring the stack up, sign in. It's self-contained — the repo's own docker-compose.yml carries every backing service. Two ways to run it:

  • Just run it — one command brings the whole stack up, migrated and seeded. Best for a first look or a demo.
  • Develop on it — run the API and UI from source for hot reload, with only the backing services in Docker.

Prerequisites ​

  • Docker (Compose v2), Bun, and Node 20.12+ — the platform toolchain (full list).
  • Docker runs the Shell's backing services — Postgres, Redis, MinIO and Keycloak — all defined in the repo's own docker-compose.yml.
  • New to the platform? Get started brings it up end to end; this page is the Shell on its own.

1 · Clone ​

bash
git clone https://github.com/VENIZIA-AI/veni-shell.git && cd veni-shell

2 · Fastest — the whole stack in one command ​

docker-compose.yml is self-contained: it starts Postgres, Redis, MinIO and Keycloak, runs a one-shot migrate + seed, then the API and UI.

bash
docker compose up -d
docker compose logs -f shell-api   # watch it boot — the migrate job runs first

When shell-api is healthy, open http://localhost:5173 and sign in — that's the Shell running, migrated and seeded, no config to set. (New to the platform? bash dev-up.sh does this and more — see Get started.)

bash
docker compose ps                  # every service should read "healthy"
docker compose down                # stop it — add -v to wipe the DB + MinIO volumes

Wiping the volumes (-v) gives you a clean database, so the next up re-migrates and re-seeds from scratch. This path runs the API and UI as containers; to edit code with hot reload, use the development setup instead.

3 · Develop against it (hot reload) ​

Run only the backing services in Docker, and the API + UI from source. Postgres and Redis are enough to sign in; add minio keycloak when you need uploads or SSO:

bash
docker compose up -d shell-db redis      # host: shell-db :15433 · redis :16379

Then the API first — it owns the database and the signing key — and the UI in a second terminal. bun is the direct path; make wraps the same commands.

API — :3000. Copy the env; you set only the signing secret (and the RSA key if remote apps will log in — tip below):

bash
cp api/.env.example api/.env
bash
# api/.env — already wired for local dev; the service URLs match the compose above
APP_ENV_JWT_SECRET=                                                     # REQUIRED · openssl rand -hex 32
APP_ENV_JWT_PRIVATE_KEY=                                                # optional — remote-app login (RS256)
APP_ENV_DATABASE_URL=postgresql://shell:shell@localhost:15433/shell_db  # shell-db
APP_ENV_REDIS_URL=redis://localhost:16379                              # redis
APP_ENV_PORT=3000
APP_ENV_FRONTEND_URL=http://localhost:5173

Everything else is opt-in — the full env catalog (providers, storage, email, AI) is on Configure. Then install, set up the database, and run it:

bash
cd api
bun install
bun run db:migrate && bun run seed   # migrate before seed
bun run dev                          # :3000
bash
make install                # installs API + UI deps
make migrate && make seed   # migrate before seed
make dev-api                # :3000

UI — :5173. No .env to copy — the UI reads the committed ui/.env.development, which Vite loads automatically:

bash
# ui/.env.development — already in the repo, points at the API above
VITE_API_URL=http://localhost:3000/api
VITE_DOCS_URL=http://localhost:5177

In a second terminal:

bash
cd ui
bun install
bun run dev    # :5173
bash
make dev-ui    # :5173 — deps already installed by `make install` above

(Or skip the two terminals: make dev runs both in the background — make logs tails them, make stop stops them, make db-reset CONFIRM=yes rebuilds the database.)

Sign in ​

Open http://localhost:5173 and sign in — that's the Shell running. Either path leaves you with the same seeded database; the development seed creates one account per role tier:

Sign in asPasswordRole
admin@venizia.localAdmin123!admin — start here
developer@venizia.localDeveloper123!developer — self-service app registration (Build a satellite)
guest@venizia.localGuest123!end-user — the plain signed-in view

Three accounts, one per tier — the development seed is deliberately minimal. It also registers just the shell app itself; remotes appear on the launchpad only once you register them. The seed data is api/scripts/seed-data/development/.

Remote-app login needs the RSA key

The optional APP_ENV_JWT_PRIVATE_KEY line in the API env is what lets the Shell sign RS256 tokens and publish its public keys at the JWKS endpoint — which is how satellites verify them.

Leave it blank and the Shell signs HS256: you can still sign in here, but every satellite fails token exchange with "Shell JWKS returned no usable signing keys" (the satellite side). Generate a key into api/.env, then restart the API:

bash
printf 'APP_ENV_JWT_PRIVATE_KEY="%s"\n' \
  "$(openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 | openssl pkcs8 -topk8 -nocrypt | sed ':a;N;$!ba;s/\n/\\n/g')" >> api/.env

Common snags ​

SymptomFix
Remote apps report "not signed in" / Shell JWKS returned no usable signing keysThe Shell is signing HS256 — set APP_ENV_JWT_PRIVATE_KEY (see the RSA-key tip) and restart the API.
make migrate fails / tables missingBring up shell-db first (docker compose up -d shell-db), and always migrate before seed.
docker compose up fails — port is already allocatedSomething already holds 15433 / 16379 / 3000 / 5173 — often a previous stack. Clear it with docker compose down, or stop the other process.
One-command stack is up, but sign-in 500s / no tablesThe one-shot shell-migrate job failed — inspect docker compose logs shell-migrate. It must exit 0 before shell-api starts; a fresh docker compose down -v && docker compose up -d re-runs it.
Seeded account won't sign inRun make seed after make migrate. To rebuild from scratch: make db-reset CONFIRM=yes.
Google / Keycloak missing from the login screenTheir env vars are unset, or the API wasn't restarted — both providers upsert on boot (Configure).
An edited OIDC provider row doesn't take effectSeeding is insert-only — it won't update an existing row. Edit the DB, or clear and re-seed.

See also ​

  • Overview — what the Shell is and how it's built.
  • Configure — turn on sign-in providers, storage, email and AI once it's up.