Skip to main content
Running Darpan for real users is mostly configuration, and the image enforces the parts that matter: it refuses to start without its secrets, exports the JVM flags Spark needs, and loads its own reference data. What is left is choosing the right image, setting a handful of environment variables, and running the first data load once. This page covers each in order.
This page describes the released backend, v2.0.0, with the app darpan-ui v3.0.0. For a development stack on your own machine, see Set up Darpan independently.

Before you start

Choose the image

Build images only from the darpan-docker-config repository. It is the single home of Darpan’s Docker files; the backend repositories no longer carry any. The components ship as a set. The pins in the production Dockerfile move together; changing one tag on its own can seed configuration that points at a service or field the other component does not have. For 2.0.0 no mixed pairing works in either direction: darpan v2.0.0 with an older connector fails at extraction, and the new connectors do not run on darpan v1.5.1. The app moves with the backend too: darpan-ui v3.0.0 calls methods v1.5.1 lacks, so keep the app on v2.6.1 if the backend stays on v1.5.1. Build from the repository root, so the Dockerfile’s COPY docker/... paths resolve:
The cloned repositories are public, so the build needs no credentials. If you build from private forks, pass a netrc file as a BuildKit secret (--secret id=netrc,src=<file>). Never pass credentials as build arguments; they would remain in the image history. During the build the image applies docker/buildGradle.patch to the framework build, builds the moqui-gql component’s jar, and fails if the active Java is not 21. moqui-gql is not a supported public API yet.

Configure the container

The entrypoint stops with an error naming the variable if any required value is missing. Required Optional The database configuration is MySQL (mysql8). Database sources that point at private, loopback or metadata addresses are refused by default; to allow a private database host, add -Ddatabase_source_allow_private_hosts=true to JAVA_OPTS. The entrypoint exports the JDK 21 flags Spark needs through JAVA_TOOL_OPTIONS. A value you set in that variable is kept, and the flags are added after it. The server listens on port 8080, and the image health check calls /status from inside the container.
The images currently run the server as root. Do not set runAsNonRoot: true in a pod security context, or the container will not start.

Load the database the first time

A new database needs one full data load before the first start. The image holds the command in the DB_LOAD environment variable; the entrypoint never runs it. Run it once from /moqui-framework inside a container that has the same environment:
Keep every type in the list. A data file whose type is not listed is skipped, and the load still reports success, so a missing type shows up later as missing configuration rather than as a load error.

Upgrade

An upgrade runs in this order: load the reference data with the new image, start the new backend, run the pending migrations, then deploy the matching app version. Both data steps are safe to repeat.
  1. Reference data. loadDarpanUpgradeData reloads every Darpan seed file of type darpan-seed. A data load is an upsert, so records already present are left as they are and new ones are added. By default the container runs this on every start. For routine restarts, set DARPAN_LOAD_UPGRADE_DATA=N and run the load once per release instead, before new containers start:
  2. One-time data migrations. Once the new backend is running, run the pending migrations from the backend’s Migrations screen at /apps/darpan/Migrations, signed in as a super-admin. A preview shows what would run. Migrations already applied are skipped, so a second run applies nothing.
Each entry in Release updates lists anything else that release needs before you deploy.

Upgrading to 2.0.0

2.0.0 changes what the backend, every connector and the app expect of each other, so the whole set moves at once. The upgrade data is a delta on 1.5.1: an installation must already have 1.5.1’s upgrade data loaded.
  1. Count before loading. The data/upgrade-data.xml header lists 15 tables to count for rows with no tenant stamp; expect 0. 2.0.0 puts 13 more tables under the tenant filter, and an unstamped row disappears from tenant reads. If a filter, key-field or scope count is not 0, run reconciliation.ReconciliationRuleEngineServices.sweep#RuleChildTenantStamps and count again. Also list the source filters saved against a Shopify-orders source: until now they were stored and ignored, and after the load they apply.
  2. Build and deploy the set. Build from darpan-docker-config v2.0.0, which pins all five backend components, and deploy it with darpan-ui v3.0.0.
  3. Load the upgrade data with loadDarpanUpgradeData, as above.
  4. Force the retired-fields migration once. A seed load never deletes, so the withdrawn Shopify Return workflow status field stays on the rules board until this runs. It is already marked applied wherever 1.5.0’s migrations ran, so it must be forced. It is idempotent. Signed in as a super-admin, call:
    A rule saved on the old field matches nothing afterwards. Re-add it on Return status with IN_PROGRESS; see Reconcile returns and exchanges.
  5. Run the pending migrations, as on every deploy.
  6. Probe the method fence. An anonymous call to org.moqui.impl.UserServices.update#Password over /rpc/json must answer HTTP 403.
Run step codes change in 2.0.0: anything that reads stageCode or stageSequence must expect the new values. See Reconciliation runs. To roll back, roll back the whole set and keep the app on v2.6.1. The upgrade data is additive, except the 13 tenant-filter rows (EntityFilter, listed last in the file): delete them before running a 1.5.1 backend on that database. Lifecycle snapshot reads can be switched off without a redeploy with -Ddarpan.reconciliation.runSnapshot=off.

Point the app at your backend

The app (darpan-ui) is a static site built against one API. Set these at build time: Cookie mode needs the backend to list the app’s origin in Moqui_WEBAPP_ALLOW_ORIGINS, and needs whatever sits in front of the backend to pass the backend’s CORS headers through unchanged. A proxy that rewrites Access-Control-Allow-Origin to * breaks cookie sign-in, because browsers refuse credentialed calls answered with *.

Next step

With the backend running and the app pointed at it, follow Tenant admin quickstart to set up the first tenant.