End-to-end guide to running Apache Airavata Custos locally: database, OIDC, API server, and portal. For coding conventions and contribution workflow, see CONTRIBUTING.md.
gitCustos is OIDC-generic and verifies bearer tokens against whatever issuer you point it at. For local development you have two convenient options:
http://localhost:3000/api/auth/callback/oidc, then plug the issuer, client_id, and client_secret into the env files.The steps below cover both. Where they differ, they're labeled Bundled Keycloak / External OIDC.
From dev-ops/compose/:
docker compose up -d db
This starts MariaDB on localhost:3306 and runs dbinit/init-db.sh, which creates the custos database and the admin user (password admin).
Bundled Keycloak only: also bring up Keycloak. On first start it imports the realm definition from dev-ops/compose/keycloak/import/custos-realm.json (OIDC client + dev users inside Keycloak itself).
docker compose up -d keycloak
Keycloak will be available at http://localhost:8081 once healthy (~60s). Skip this if you're using an external OIDC provider.
Stop everything later with docker compose down, or docker compose down -v to also wipe the DB volume.
From the repo root:
cp .env.example .env
Edit .env:
admin@custos.local (matches the seeded realm user).http://localhost:3000/api/auth/callback/oidc, then:OIDC_ISSUER_URL to the issuer URL.OIDC_AUDIENCE to whatever your IdP puts in the access-token aud claim (typically your client_id).CUSTOS_BOOTSTRAP_ADMIN_EMAIL=<your email>. A PENDING super_admin user is created on first boot; your first sign-in links your OIDC sub to it via email fallback.Source it: set -a && . ./.env && set +a.
From the repo root:
go run ./cmd/server
On startup, the server opens the DB, runs the embedded migrations (internal/db/migrations/), grants super_admin to CUSTOS_BOOTSTRAP_ADMIN_EMAIL (creating a PENDING user if needed), wires the event bus + service layer, and listens on the port from config/custos.yaml (core.api.port, default 8080).
Leave it running.
The migrations create the schema; the cluster seed inserts the default compute_clusters row that connectors and portal features reference by ID. Apply it once, in a second terminal, after the server has come up:
docker exec -i custos_db mariadb -uadmin -padmin custos < dev-ops/compose/seeds/default_cluster.sql
The seed uses INSERT IGNORE, so re-running is safe.
For the bundled Keycloak path there is also a sample identity seed (org, users, roles, role assignments) matched to the users in the imported realm:
docker exec -i custos_db mariadb -uadmin -padmin custos < dev-ops/compose/seeds/dev_users_and_roles.sql
Skip this for external OIDC. You don't need it, and the emails would collide with the identity you actually sign in as.
cd web cp .env.example .env.local pnpm install
Edit web/.env.local:
NEXTAUTH_SECRET with openssl rand -base64 32.OIDC_ISSUER_URL, OIDC_CLIENT_ID, and OIDC_CLIENT_SECRET to the values from the client you registered in step 2.Start the portal:
pnpm dev
Open http://localhost:3000 and sign in:
admin@custos.local / admin; see the realm import for the full list).sub is linked to the PENDING super_admin user created in step 3, and the user is promoted to ACTIVE.After first sign-in the sidebar renders but every screen is empty. That's the correct state on a fresh DB, no allocation or project data has been produced yet. To populate it:
connectors/ACCESS/AMIE-Processor/README.md.dev-ops/compose/seeds/dev_portal_data.sql. Apply after AMIE has run so the referenced allocation IDs exist.The portal serves a landing page at / to signed-out users; signed-in users get the portal home instead. The page lives at web/public/landing/index.html, a single self-contained file.
To use your own landing page, replace that file with your index.html before building the portal. Put any assets it needs (images, stylesheets, fonts) anywhere under web/public/ and reference them by their URL path from the site root (web/public/brand/logo.svg is served at /brand/logo.svg). They ship with the build automatically.
Point the page's sign-in links at /api/auth/federated-sign-in to send users straight to the identity provider.