Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Local Portal Setup

This guide starts the local Light Portal runtime from two sibling repositories:

~/lightapi/portal-config-loc
~/lightapi/service-asset

portal-config-loc contains the local Compose stacks and startup script. service-asset contains the checked-in service jars, UI assets, released image tags, and the event snapshot used to initialize a new local database.

Quick Start

Clone or update both repositories under ~/lightapi:

cd ~
mkdir -p lightapi
cd lightapi
git clone [email protected]:lightapi/portal-config-loc.git
git clone [email protected]:lightapi/service-asset.git

If they are already cloned:

cd ~/lightapi/portal-config-loc
git pull --rebase
cd ~/lightapi/service-asset
git pull --rebase

Optional: Use Your Own Events

The importer always reads this exact file:

~/lightapi/service-asset/events.json

To initialize a new local database with your own snapshot, replace ~/lightapi/service-asset/events.json before running deploy-local.sh for the first time:

cp /path/to/your/events.json ~/lightapi/service-asset/events.json

Do not use a different filename. deploy-local.sh rejects EVENT_IMPORT_FILE so every import path uses only service-asset/events.json. After the script has started and imported events into Postgres, replacing the file will not change the existing database. To reinitialize from a different file, remove the Postgres named volume, replace service-asset/events.json, and then start the script again with IMPORT_EVENTS=auto.

For Podman:

cd ~/lightapi/portal-config-loc/all-in-lt
podman compose -f docker-compose.yml -f docker-compose-rust.yml down -v

For Docker:

cd ~/lightapi/portal-config-loc/all-in-lt
docker compose -f docker-compose.yml -f docker-compose-rust.yml down -v

Start the Rust stack with Docker Compose:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="docker compose" \
CONTAINER_CMD=docker \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

Start the Rust stack with Podman Compose:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="podman compose" \
CONTAINER_CMD=podman \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

Open the portal at:

https://localhost

If the selected configuration uses hostnames such as dev.lightapi.net, add them to the local hosts file and point them to 127.0.0.1.

What The Script Does

deploy-local.sh copies assets from the sibling service-asset repository into the selected portal-config-loc stack only when the target directories are missing or empty. It does not overwrite populated asset directories during a normal run.

For the lt rust stack, the script starts all-in-lt with the Rust compose override. It also passes service-asset/docker-images.env to Compose when that file is present, so the stack can use the released image tags generated by the asset release process.

When IMPORT_EVENTS=auto is set, the script waits for Postgres, checks event_store_t, and imports service-asset/events.json only if the event store is empty. This is intended for a brand new environment or after removing the Postgres named volume. Leave IMPORT_EVENTS unset for normal restarts.

Automatic event import uses the event-importer container image by default:

CONTAINER_CMD=podman
EVENT_IMPORTER_IMAGE=networknt/event-importer:latest

Use EVENT_IMPORT_RUNNER=local only when you intentionally want to run the host-side importer scripts from service-asset.

Postgres uses a Compose named volume called postgres-data instead of the host bind directory postgres-db/data. This avoids rootless Podman permission and SELinux label issues on Fedora Silverblue. To reset Postgres for a selected stack, run Compose directly from that stack directory with down -v.

Ubuntu

Docker Compose is the simplest Ubuntu path. Install Docker Engine and the Compose plugin by following the official Docker Ubuntu guide, then run:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="docker compose" \
CONTAINER_CMD=docker \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

Podman also works on Ubuntu after installing Podman and a Compose provider:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="podman compose" \
CONTAINER_CMD=podman \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

References:

Fedora Silverblue

Fedora Silverblue already fits a Podman-first local workflow. Install the Compose provider once, then reboot into the new deployment:

sudo rpm-ostree install podman-compose
systemctl reboot

Rootless Podman normally cannot bind host port 443. The local configuration expects https://localhost, so allow unprivileged processes to bind from 443 upward before starting the stack:

printf 'net.ipv4.ip_unprivileged_port_start=443\n' | \
  sudo tee /etc/sysctl.d/99-rootless-low-ports.conf
sudo sysctl --system

Then start the stack:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="podman compose" \
CONTAINER_CMD=podman \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

References:

Postgres Permission Recovery

Postgres data is stored in a Compose named volume, not in postgres-db/data. If you previously started the stack before this change and hit a permission error on the old bind-mounted data directory, pull the latest config and recreate the stack:

cd ~/lightapi/portal-config-loc
git pull --rebase
COMPOSE_CMD="podman compose" CONTAINER_CMD=podman ./scripts/deploy-local.sh lt rust stop
COMPOSE_CMD="podman compose" CONTAINER_CMD=podman IMPORT_EVENTS=auto ./scripts/deploy-local.sh lt rust

If you need a completely fresh database after a failed first run, remove the Compose volume before starting again:

cd ~/lightapi/portal-config-loc/all-in-lt
podman compose -f docker-compose.yml -f docker-compose-rust.yml down -v

Controller Certificate Recovery

If controller-rs fails with a message that CONTROLLER_TLS_CERT_PATH points to missing /keystore/server.pem, use the latest Compose files and recreate the Rust stack. The cert files are tracked in all-in-lt/light-controller-rust, but rootless Podman on Silverblue needs the keystore bind mount to be SELinux relabeled.

cd ~/lightapi/portal-config-loc
git pull --rebase
COMPOSE_CMD="podman compose" CONTAINER_CMD=podman ./scripts/deploy-local.sh lt rust restart

macOS

Docker Desktop is the simplest macOS path. Install Docker Desktop, start it, then run the same script from Terminal:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="docker compose" \
CONTAINER_CMD=docker \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

Podman Desktop can also be used. Start the Podman machine first, then use the Podman command form:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="podman compose" \
CONTAINER_CMD=podman \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

References:

Windows

Use WSL2 Ubuntu for the local development shell. Clone the repositories under the WSL home directory, not under a Windows drive mount:

~/lightapi/portal-config-loc
~/lightapi/service-asset

With Docker Desktop, enable WSL integration for the Ubuntu distribution and run the script inside the WSL shell:

cd ~/lightapi/portal-config-loc
COMPOSE_CMD="docker compose" \
CONTAINER_CMD=docker \
IMPORT_EVENTS=auto \
RUST_LOG=info \
./scripts/deploy-local.sh lt rust

Podman on Windows also works through a Podman machine, but WSL2 plus Docker Desktop is usually the shortest setup path for this local stack.

References:

Common Commands

Show status:

COMPOSE_CMD="podman compose" ./scripts/deploy-local.sh lt rust status

Show logs:

COMPOSE_CMD="podman compose" ./scripts/deploy-local.sh lt rust logs

Restart:

COMPOSE_CMD="podman compose" ./scripts/deploy-local.sh lt rust restart

Stop:

COMPOSE_CMD="podman compose" ./scripts/deploy-local.sh lt rust stop

Force event import:

COMPOSE_CMD="podman compose" \
CONTAINER_CMD=podman \
IMPORT_EVENTS=true \
./scripts/deploy-local.sh lt rust start