Configuration reference

The environment variables an operator sets to configure Bonita Process Designer, where to set them in each distribution, their defaults, and the values the shipped Docker files set.

Bonita Process Designer is configured through environment variables. Both distributions run the same Java application, which serves the editor and the API on a single port.

Only DATABASE_URL is required by the application. The start scripts of the standalone distribution also require SPRING_DATASOURCE_USERNAME and SPRING_DATASOURCE_PASSWORD, which otherwise default to postgres. Every other variable has a default; set the rest only when your deployment needs them.

Where to set a variable

Standalone distribution

Set the variable in config.env, next to start.sh, then restart. Put each comment on a line of its own: start.bat reads everything after the = sign as the value. config.env.example lists most of the optional variables with their defaults, but not all of them: AUTH_MODE, CORS_ORIGIN, AUTO_SNAPSHOT_EVERY_N_SAVES and DATA_RETENTION_SWEEP_INTERVAL_MS, for example, are missing. Add a line for them yourself.

Docker distribution

The application only receives the variables that the app service of docker-compose.yml lists in its environment:.

  • For the variables that docker-compose.yml already reads from your environment — TLS_DOMAIN, CORS_ORIGIN, APP_FRONTEND_URL, USE_HTTPS, LOG_LEVEL, LOG_LEVEL_ROOT and LOG_LEVEL_TOMCAT_HTTP — set the value in a .env file next to docker-compose.yml, or in the shell that runs docker compose. The same goes for PD_IMAGE and PD_VERSION, which choose the application image rather than configure the application: see Choose the image and its version.

  • For any other variable, add a line to the environment: of the app service, for example - JAVA_OPTS=-Xmx512m. Setting it in .env or in the shell alone has no effect.

Then run docker compose up -d: Compose recreates the containers whose configuration changed. docker-compose.http.yml reads none of these variables from your environment, apart from PD_IMAGE and PD_VERSION: add every other variable you need to the environment: of its app service.

Environment variable reference

Database and network

Variable Purpose Default

DATABASE_URL

JDBC URL of the PostgreSQL 16+ database, in the form jdbc:postgresql://<host>:<port>/<database>. Required.

(none)

SPRING_DATASOURCE_USERNAME

PostgreSQL user. Required by the standalone start scripts.

postgres

SPRING_DATASOURCE_PASSWORD

PostgreSQL password. Required by the standalone start scripts.

postgres

PORT

The single HTTP port of the application, serving both the editor and the API.

8080 (Docker image, start scripts); 3000 (bare JAR)

TLS_DOMAIN

Docker distribution only, read by the caddy proxy: the host name or IP address that users type in the browser. Caddy issues its certificate for this name and refuses TLS connections for any other name. See Access the application from other machines.

localhost

CORS_ORIGIN

Comma-separated list of the exact origins allowed to call the application with a user’s session, other than its own pages, whose requests are always accepted. Set it in every deployment, to the address users type in the browser. See CORS security.

(none): a fallback derived from the request and FRONTEND_PORT, not meant for production

FRONTEND_PORT

When CORS_ORIGIN is not set, the port of the fallback origin derived from the request. That fallback is not meant for production: set CORS_ORIGIN instead.

8080

USE_HTTPS

Set to true when users reach the application over HTTPS. Makes the session cookie Secure and sets SameSite=None. See TLS hardening.

false

APP_FRONTEND_URL

The public URL of the application. The shipped files set it, and the diagnostic archive reports it, but in version 1.1.0 no behavior of the application depends on it.

(none)

HTTP_PROXY, HTTPS_PROXY

Proxy URL, in the form http://<host>:<port>, for every outbound call to the AI service, including the registration of the installation, and to the connector marketplace. HTTPS_PROXY is used when both are set. Only the host and the port are used: a proxy that requires authentication is not supported. See Configure an outbound HTTP(S) proxy.

(none)

NO_PROXY

Not read by the application: setting it has no effect. The shipped Docker proxy lines and config.env.example include it, and the diagnostic archive reports whether it is set.

(none)

The config.env.example of the standalone archive shows the proxy URL as http://username:password@proxy.company.com:8080, with a NO_PROXY line. The application ignores both the credentials and NO_PROXY: set the proxy as http://<host>:<port>.

BACKEND_PORT is no longer read: there is no separate API port. LICENSE_BYPASS is removed: license enforcement cannot be turned off. If your configuration still sets either, remove it. See What changes for your scripts.

Application

Variable Purpose Default

AUTH_MODE

Authentication mode: standalone (username and password, with a server session) or bonita (delegated to a Bonita Runtime). See Run with Bonita Runtime.

standalone

BONITA_LICENSE_FOLDER

Folder holding the .lic license file. It is created at startup if it does not exist. License validation is local: it needs no network access. See Manage the license.

./licenses (standalone: next to app.jar)

JAVA_OPTS

Options passed to the Java virtual machine. A value replaces the default, heap ceiling included: always include an -Xmx value, for example -Xmx512m. Raise the ceiling if the log shows OutOfMemoryError. The process uses noticeably more memory than its heap ceiling.

-Xmx192m (Docker image), -Xmx512m (standalone)

AUTO_SNAPSHOT_EVERY_N_SAVES

Records an automatic version of a diagram every n saves. 1 records one at each save. A higher value keeps fewer automatic versions; manual snapshots are not affected.

1

TEXT2BPMN_API_URL

Address of the AI service. Do not change it unless Ofelia instructs you to.

(set by the distribution)

Data retention

Two scheduled tasks delete old AI data. A sweep, once a day by default, deletes the finished AI jobs and the AI quota usage events that are past their retention. A purge, every hour, removes the result of the successful AI jobs older than AI_JOB_RESULT_TTL_HOURS. These variables set how long the data is kept. Expired sessions are deleted separately, every minute, and none of these variables applies to them.

Variable Purpose Default

AI_JOB_RESULT_TTL_HOURS

Hours a successful AI job keeps its result, the generated BPMN or the analysis. After that, the job keeps its status but no longer its result. Raise it, for example to 168 (one week), if your users often report an AI problem a few days later. A failed job keeps its error for the full AI_JOB_RETENTION_DAYS.

24

AI_JOB_RETENTION_DAYS

Days a finished AI job is kept before it is deleted.

30

AI_USAGE_RETENTION_DAYS

Days an AI quota usage event is kept. Keep it at 30 days or more, the length of the quota window: below that, the quota stops counting usage it should still count. See Manage AI quota.

90

DATA_RETENTION_ENABLED

Turns the daily sweep on or off. With false, finished AI jobs and AI quota usage events are never deleted, and their tables grow without limit. The hourly purge of AI job results and the cleanup of expired sessions keep running.

true

DATA_RETENTION_SWEEP_INTERVAL_MS

Interval between two sweeps, in milliseconds. The first sweep runs one interval after startup.

86400000 (one day)

Logging

Variable Purpose Default

LOG_LEVEL

Verbosity of the application’s own log. Raise to DEBUG when diagnosing a problem. Read at startup: restart to apply. See Logs and log levels.

INFO

LOG_LEVEL_ROOT

Verbosity of everything else: framework, database driver, and other libraries. Raise only when the problem looks lower-level than the application itself. A few framework loggers are pinned separately and are not affected by it — see LOG_LEVEL_TOMCAT_HTTP.

INFO

LOG_LEVEL_TOMCAT_HTTP

Verbosity of Tomcat’s HTTP protocol loggers, pinned independently of LOG_LEVEL_ROOT and deliberately quieter than it, because at INFO these loggers write request data that is otherwise never recorded. Leave it alone unless you are diagnosing a protocol-level rejection, and read the warning below first.

WARN

LOGGING_FILE_NAME

Where to write the log file. Set it to place the log on a dedicated partition; the directory must exist and be writable. In the Docker distribution, an empty value turns off the copy of the log kept inside the app container. See Writing the file elsewhere.

logs/process-designer.log (standalone), /var/log/process-designer/app.log (Docker)

LOGGING_LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE

Size at which the log file rolls over.

10MB

LOGGING_LOGBACK_ROLLINGPOLICY_MAX_HISTORY

Days of gzipped archives to keep.

30

LOGGING_LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP

Total size the log file and its archives may occupy. Once reached, the oldest archives are deleted first.

1GB (standalone), 100MB (Docker)

Setting LOG_LEVEL_TOMCAT_HTTP=INFO makes Tomcat log the whole rejected request when a malformed request line or a non-conforming header arrives: the request target with its query string, and the offending header line with its value — which can be the Cookie or Authorization header. Session identifiers, credentials and query strings are otherwise never written to the log (see Logs and log levels).

Use it only briefly, and treat the log it produces as sensitive: it is no longer safe to send to Support unreviewed. Raising LOG_LEVEL_ROOT alone does not surface these lines, because this logger is pinned independently — which is the point.

In the Docker distribution, the log file is a copy kept inside the app container, bounded to 100 MB, and lost when the container is recreated. The log to collect is the container’s output, whose retention is set by the Docker logging driver in docker-compose.yml. See Logs and log levels.

Values set by the shipped Docker files

The Compose files of the Docker archive set some variables to values that differ from the application defaults above, because the application runs behind the caddy proxy.

Variable docker-compose.yml docker-compose.http.yml

PORT

8080, not published: reached through caddy on 443

8080, published on the host

CORS_ORIGIN

https://localhost, unless you set it

(not set)

USE_HTTPS

true, unless you set it

(not set): false

APP_FRONTEND_URL

https://localhost, unless you set it

(not set)

BONITA_LICENSE_FOLDER

/opt/bonita/licenses, in the bonita_licenses volume

/opt/bonita/licenses, in the bonita_licenses volume

DATABASE_URL, SPRING_DATASOURCE_USERNAME, SPRING_DATASOURCE_PASSWORD

The bpmnDB database of the postgres service, user postgres, password POSTGRES_PASSWORD of the .env file, postgres when unset

Same

TEXT2BPMN_API_URL

https://pd-ai.onrender.com/v1, unless you set it in the .env file

Same

HTTP_PROXY, HTTPS_PROXY, NO_PROXY

Shipped commented out

(not set)

The Docker image itself sets JAVA_OPTS=-Xmx192m.

AI configuration

AI diagram generation is configured by an administrator in the application, not through environment variables. After registration, an Admin enters one or more LLM provider keys under Admin → Settings. Bonita Process Designer does not store these provider keys in its own database — it persists only a per-provider "configured" flag so the admin UI can show which providers have a key. Use a dedicated, scoped key per provider and rotate keys periodically.

Set spend caps and usage limits in each provider’s own dashboard. The application’s per-group AI quota is a complementary control, not a substitute for a provider-side spend cap.

Secrets and the encryption key

There is no shared session-signing secret to configure on Bonita Process Designer. Session identifiers are random and stored server-side in PostgreSQL, so the security of session data depends on protecting the database and serving over HTTPS — not on a secret you set.

Likewise, LLM provider keys are never persisted locally (see AI configuration), so there is no application-level key-encryption secret to manage. Keep your PostgreSQL credentials strong and unique, and keep the database on a private network segment reachable only by the application. In the Docker distribution, set the database password in the .env file before the first start: see Security notes for the proxy and the stack.

CORS security

The application always accepts requests from its own pages. CORS governs the requests made from another origin with a user’s session. When CORS_ORIGIN is set, the application accepts them only from the origins it lists. When it is not set, the application falls back to an origin derived from the request and FRONTEND_PORT. That fallback is not meant for production: always set CORS_ORIGIN.

The shipped docker-compose.yml sets CORS_ORIGIN for you, to https://localhost or to the value you give it. Everywhere else, in the standalone distribution, with the Docker HTTP opt-out, or behind your own reverse proxy, always set CORS_ORIGIN to the exact origin that users type in the browser, and add any other site that must call the application:

# Single explicit origin
CORS_ORIGIN=https://pd.example.com

# Several origins (comma-separated)
CORS_ORIGIN=https://pd.example.com,https://portal.example.com

Never use a wildcard origin with credentials. Wildcard CORS is a CSRF vector. Always list exact origins.

TLS hardening

In the Docker distribution, TLS is on by default: the shipped caddy proxy terminates HTTPS on port 443, redirects port 80 to it, and the shipped docker-compose.yml sets USE_HTTPS=true. Do not add a second TLS proxy in front of it. To replace its self-signed certificate, see Use your own certificate.

The standalone distribution and the Docker HTTP opt-out serve plain HTTP. To serve them over HTTPS, terminate TLS in front of the application with a reverse proxy (such as nginx, Traefik or Caddy) or a load balancer, rather than exposing the application directly. Then:

  • Set USE_HTTPS=true so the session cookie is issued with the Secure flag. It also sets the cookie attribute SameSite=None. Leaving it false behind HTTPS would emit a non-Secure cookie.

  • Always forward X-Forwarded-Proto from the proxy. Also forward X-Forwarded-Host, or preserve the original Host header, so that the application knows its public origin.

  • Forward WebSocket connections on /ws: the proxy must pass the Upgrade and Connection headers of the request. Without them, users do not see each other’s changes in real time. With nginx, for example, add these lines to the location that proxies the application:

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  • Set CORS_ORIGIN to the public HTTPS origin, as described in CORS security.

Over HTTPS, the application also sends a Strict-Transport-Security header with a one-day lifetime, so browsers keep using HTTPS for its host.

For the deployment-mode guidance, see Installation and Run with Bonita Runtime.