This guide generates the local files Trellis needs, starts NATS in a container, applies shared infrastructure, and runs Trellis from the source tree with deno task dev.
By the end, you will have:
- a local folder at
~/trelliswith generated Trellis and NATS files - a NATS container running on your machine
- Trellis running at
http://localhost:3000 - the built-in setup page for creating your first admin account
- Console running at
http://localhost:5173 - a CLI login you can use for admin commands
What you need
- Git
- Deno v2+
- a Rust toolchain, because local prepare tasks run the Rust generator
- the
trellisCLI installed (see Install the Trellis CLI) podman
The local bootstrap command uses a nats-box container internally to generate NATS operator, account, credential, signing-key, and resolver files. You do not need to configure NATS accounts, credentials, or signing keys by hand.
1. Generate the local bundle
trellis local init --out ~/trellis This creates a movable local bundle under ~/trellis:
| Path | Purpose |
|---|---|
manifest.json | Generated bundle manifest with public keys and relative paths |
nats/ | NATS config, resolver data, service credentials, and signing seeds |
trellis/config.jsonc | Trellis runtime config using relative file paths |
trellis/session.seed | Local Trellis runtime session key seed |
trellis/data/ | Local Trellis SQLite data directory |
The generated Trellis config omits nats.jetstream.replicas. On startup,
Trellis probes NATS JetStream topology and uses 1 for this standalone local
server. Production deployments can set nats.jetstream.replicas explicitly, or
omit it to let Trellis choose 3 only when enough current JetStream metadata
peers are visible.
Useful local flags:
| Flag | Default | Use when |
|---|---|---|
--container-runtime podman | auto | You want to avoid runtime autodetection |
--public-origin http://localhost:3000 | http://localhost:3000 | Trellis is exposed on a different local origin |
--nats-server-url nats://127.0.0.1:4222 | nats://127.0.0.1:4222 | Server-side clients reach NATS somewhere else |
--nats-websocket-url ws://localhost:8080 | ws://localhost:8080 | Browser clients reach NATS somewhere else |
2. Start NATS
Run NATS from the generated config and resolver data:
podman run --replace --detach --name trellis-nats \
--publish 127.0.0.1:4222:4222 \
--publish 127.0.0.1:8080:8080 \
--publish 127.0.0.1:8222:8222 \
--volume "$HOME/trellis/nats/nats.conf:/etc/nats/nats.conf:ro,Z" \
--volume "$HOME/trellis/nats/jwt.conf:/etc/nats/jwt.conf:ro,Z" \
--volume "$HOME/trellis/nats/data:/data:Z" \
docker.io/library/nats:latest \
-c /etc/nats/nats.conf The container publishes only loopback ports:
| Port | Purpose |
|---|---|
4222 | Native NATS clients |
8080 | Browser websocket clients |
8222 | NATS monitoring and health |
3. Verify NATS
curl http://127.0.0.1:8222/healthz An HTTP 200 response means NATS is ready for the Trellis infrastructure bootstrap step.
4. Check out the source tree
TRELLIS_VERSION="$(trellis --version)"
TRELLIS_VERSION="${TRELLIS_VERSION#trellis }"
TRELLIS_VERSION="${TRELLIS_VERSION%%+*}"
git clone --branch "v${TRELLIS_VERSION#v}" --depth 1 https://github.com/qlever-llc/trellis.git
cd trellis This checks out the release tag that matches your installed CLI. If you already have a checkout, use that directory instead.
5. Apply shared infrastructure
Create the Trellis event stream and auth-owned KV buckets in NATS:
trellis infra apply \
--servers 127.0.0.1 \
--trellis-creds ~/trellis/nats/creds/trellis-auth.creds \
--auth-creds ~/trellis/nats/creds/auth-auth.creds Verify that the resources are ready:
trellis infra check \
--servers 127.0.0.1 \
--trellis-creds ~/trellis/nats/creds/trellis-auth.creds \
--auth-creds ~/trellis/nats/creds/auth-auth.creds 6. Start Trellis from source
In the source checkout:
cd js/services/trellis
TRELLIS_CONFIG="$HOME/trellis/trellis/config.jsonc" deno task dev Keep this terminal running. The task prepares generated artifacts, builds the built-in portal, and starts the Trellis runtime with file watching.
On first boot, Trellis prints an admin setup URL because no admin account exists yet. You will use that link in the next step.
7. Create your first admin account
Find the admin setup URL in the Trellis server output. It looks like this:
http://localhost:3000/_trellis/portal/admin/bootstrap?flowId=... Open that URL in your browser and set the password for the initial local admin account.
8. Log in with the CLI
trellis login http://localhost:3000 The CLI prints a portal URL and QR code. Open the URL, sign in with the local admin username and password you just set, approve the CLI contract, and wait for the command to complete.
Confirm the stored admin session:
trellis whoami 9. Start the Console
In another terminal from the source checkout:
cd js/apps/console
cp .env.example .env
deno task dev Open http://localhost:5173 and log in with the local admin username and password. The browser flow uses the built-in Trellis portal served by the source-run runtime.
10. Verify the local stack
curl http://127.0.0.1:8222/healthz
curl -i http://localhost:3000/_trellis/portal
curl -I http://localhost:5173/
trellis whoami At this point you have:
- NATS running in a container
- Trellis running from source with
deno task dev - the built-in portal served by Trellis
- Console running from source
- an admin CLI session