Deploy on PostgreSQL
This page covers running the Ed-Fi OneRoster® Node service against an Ed-Fi ODS that runs on PostgreSQL. Two distinct steps are involved:
- Schema deployment. A one-time install of the
oneroster12schema (materialized views + descriptor seed data) into each ODS database the service will serve. Uses direct ODS credentials. - Runtime configuration. The running service connects to the ODS
API's
EdFi_Admindatabase (not an ODS directly) and resolves the correct ODS from JWT claims on each request.
Prerequisites
- An Ed-Fi ODS PostgreSQL database reachable from where the deployment
script will run, plus the ODS API's
EdFi_Admindatabase reachable from where the OneRoster Node service will run - The ODS API's
ApiSettings:OdsConnectionStringEncryptionKeyvalue. The OneRoster service uses the same key to decrypt the ODS connection strings it reads fromEdFi_Admin.OdsInstances. - Node.js 22 LTS or later
Step 1. Deploy the SQL artifacts
Install the oneroster12 schema (materialized views, descriptors,
descriptor mappings) into your ODS database. The commands and the
standard/.env.deploy template live with the schema source:
- standard/README_pgsql.md
— automated (
node standard/deploy-pgsql.js) and manual (psql) paths for Data Standard 4.0 and 5.x.
Run the deployment once per ODS instance you intend to serve.
Step 2. Configure the Node service
Copy .env.example to .env at the repository root and set at least:
-
DB_TYPE=postgres -
CONNECTION_CONFIG— JSON with anadminConnectionvalue pointing at the ODS API'sEdFi_Admindatabase. Example:CONNECTION_CONFIG={"adminConnection":"host=localhost;port=5432;database=EdFi_Admin;username=<your-username>;password=<your-password>"} -
ODS_CONNECTION_STRING_ENCRYPTION_KEY— the base64 AES key that matches the ODS API'sApiSettings:OdsConnectionStringEncryptionKey -
sslmode(and optionallysslrootcert,sslcert,sslkey) embedded in theadminConnectionvalue ifEdFi_Adminrequires TLS. See PostgreSQL SSL. -
PG_BOSS_CONNECTION_CONFIG— same JSON shape asCONNECTION_CONFIG. Points at the PostgreSQL database pg-boss uses to store its job metadata. ReusingEdFi_Adminis the simplest default; a dedicated database is also supported. -
PGBOSS_CRON, the cron expression for the refresh job (default*/15 * * * *) -
OAUTH2_AUDIENCEandOAUTH2_ISSUERBASEURL. The server fails fast on startup if either is missing. -
OAUTH2_TOKENSIGNINGALG(typicallyRS256) -
OAUTH2_PUBLIC_KEY_PEMif you want PEM-based JWT verification. Otherwise leave it blank to use JWKS discovery fromOAUTH2_ISSUERBASEURL. -
PORT(defaults to3000)
For multi-tenant deployments, set MULTITENANCY_ENABLED=true and use
TENANTS_CONNECTION_CONFIG (a JSON map of tenant → adminConnection)
instead of CONNECTION_CONFIG. For school-year or other context
routing, set ODS_CONTEXT_ROUTE_TEMPLATE. See Environment
variables
for the full reference.
See OAuth and JWT and CORS, rate limiting, and proxy for the remaining configuration groups.
Step 3. Install and run
Option A: Official Docker image (recommended for production)
Pull and run the official image from Docker Hub, passing the .env
file from Step 2:
docker run --env-file .env -p 3000:3000 edfialliance/one-roster-api
Pin a specific version by appending a tag (for example,
edfialliance/one-roster-api:1.0.0). See
Docker Hub
for available tags.
Option B: Run from source
cd edfi-oneroster
npm install
node server.js
Verify the service responds:
curl -i http://localhost:3000/health-check
curl -i http://localhost:3000/ims/oneroster/rostering/v1p2/orgs \
-H "Authorization: Bearer <token>"
The bearer token must be issued by OAUTH2_ISSUERBASEURL, have
audience OAUTH2_AUDIENCE, contain at least one OneRoster v1.2 scope
(roster.readonly, roster-core.readonly, or
roster-demographics.readonly), and carry the odsInstanceId claim
(and tenantId in multi-tenant mode). See JWT claims used for ODS
resolution.
Refresh behavior
Materialized views are refreshed concurrently by a
pg-boss cron job running inside the
Node service, on the schedule given by PGBOSS_CRON. Refreshes run one
at a time to avoid contention. pg-boss job metadata is stored in the
database named by PG_BOSS_CONNECTION_CONFIG.
To refresh a view manually:
REFRESH MATERIALIZED VIEW CONCURRENTLY oneroster12.orgs;
Standing up a local Ed-Fi ODS for testing
For end-to-end local testing that stands up an ODS, EdFi_Admin, and
an Ed-Fi ODS / API configured as the OAuth issuer, use the Docker
Compose demo stack.