Container image
The Bundled image, registry.tinyfactory.ai/tinyblox/tinyconductor-bundled, is one
container that holds the engine and PostgreSQL. One volume holds PostgreSQL’s
data and the secrets the engine generates on its first start. For a step-by-step walkthrough, see
Quickstart. The images are published to
TinyFactory’s registry; the exact address is given with your access.
docker run -d --name tinyconductor -p 127.0.0.1:8080:8080 \ -v tinyconductor-pgdata:/var/lib/postgresql/data \ registry.tinyfactory.ai/tinyblox/tinyconductor-bundled:0.1.0See Bundled mode.
Published images
Section titled “Published images”Every release publishes these images for linux/amd64 and linux/arm64,
tagged with the release version, as in registry.tinyfactory.ai/tinyblox/tinyconductor:0.1.0. A release without a pre-release
suffix also moves the <major>.<minor> and latest tags.
| Image | What it runs | Guide |
|---|---|---|
registry.tinyfactory.ai/tinyblox/tinyconductor-bundled | Bundled mode: the engine and PostgreSQL in one container | this page, Quickstart |
registry.tinyfactory.ai/tinyblox/tinyconductor | the engine alone: the Embedded test engine by default, or a Cluster node with --mode cluster | Embedded mode, Cluster mode |
registry.tinyfactory.ai/tinyblox/tinyconductor-script-worker | the external Script Task worker | Script tasks |
registry.tinyfactory.ai/tinyblox/tinyconductor-docs | this documentation, served on port 8080 (docker run -p 127.0.0.1:8080:8080 …) for reading offline or on your own network | — |
The engine program is also published as a download for Linux, macOS and Windows, for running without containers; see Embedded mode.
Authentication
Section titled “Authentication”The engine requires a credential by default. On first boot it generates a random bearer token and keeps only its digest in PostgreSQL. The token is never written to the log: it is written once to the first-boot secrets file on the data volume, which only the engine’s user can read. The log says where. Read it, store it, then delete the file:
docker exec tinyconductor cat /var/lib/postgresql/data/tinyconductor/first-boot-secretsdocker exec tinyconductor rm /var/lib/postgresql/data/tinyconductor/first-boot-secretsEvery later boot reuses the stored credential and writes nothing. Only the token’s SHA-256 digest is stored, so the token can’t be read back. If you lose it, delete the row and restart to get a new one:
docker exec tinyconductor psql -U postgres -d tinyconductor -c \ 'DELETE FROM bpm_runtime.engine_credential'docker restart tinyconductorSend it as Authorization: Bearer <token>. It is a bootstrap credential:
use it to set the engine up, and give each job worker and script an API
client of its own (Access → Clients in the console, or POST /v2/clients;
see Identity and access). GET /healthz, GET /readyz, the console’s own page files and /auth/* are
public. Everything that reads or changes engine state needs a credential. A
call without one answers 401 with urn:bpm:error:unauthorized.
People sign in to the console instead of pasting tokens. On first boot the
image also creates a bootstrap administrator (the first admin account).
Its password is the CONDUCTOR_BOOTSTRAP_ADMIN_PASSWORD line of the same
first-boot secrets file; only an argon2id hash of it is stored.
Open http://127.0.0.1:8080/console/ and sign in as admin. The session
cookie is Secure and __Host- prefixed. Browsers accept that over plain
HTTP only for localhost/127.0.0.1, and Safari not even then. For such a
local-only setup, set CONDUCTOR_SESSION_INSECURE_COOKIE=1 (the cookie is then
hb_session, without Secure). Never set it otherwise.
To sign in with your organisation’s identity provider instead, configure OIDC
(this turns local users off unless CONDUCTOR_LOCAL_USERS_ENABLED=1):
docker run -d --name tinyconductor -p 127.0.0.1:8080:8080 \ -v tinyconductor-pgdata:/var/lib/postgresql/data \ -e CONDUCTOR_OIDC_ISSUER=https://sso.example.com/realms/tinyconductor \ -e CONDUCTOR_OIDC_CLIENT_ID=tinyconductor \ -e CONDUCTOR_OIDC_CLIENT_SECRET=… \ -e CONDUCTOR_OIDC_REDIRECT_URI=https://bpm.example.com/auth/callback \ -e 'CONDUCTOR_AUTH_MAPPING_RULES_JSON=[{"claim":"groups","equals":"bpm-operators","roles":["operator"]}]' \ registry.tinyfactory.ai/tinyblox/tinyconductor-bundled:0.1.0A worked Keycloak setup, the mapping rules, the roles and every variable are in Identity and access.
| Variable | Meaning |
|---|---|
CONDUCTOR_AUTH_CREDENTIALS_JSON | Static tokens, for bootstrap and tests (programs normally use API clients created in the console or with POST /v2/clients), in the same document Cluster mode takes, optionally with "expiresAt":"<RFC 3339>". Overrides the generated one. A subject may hold two tokens only when the credentials are identical except for the token — that is how a token is rotated; anything else sharing a subject refuses startup |
CONDUCTOR_OIDC_*, CONDUCTOR_AUTH_MAPPING_RULES_JSON, CONDUCTOR_AUTH_ROLES_JSON | Sign-in through your identity provider. See Identity and access |
CONDUCTOR_LOCAL_USERS_ENABLED, CONDUCTOR_LOCAL_USERS_JSON, CONDUCTOR_BOOTSTRAP_ADMIN_USERNAME | Local users; on by default without OIDC. Hash passwords with printf '%s' 'pw' | docker exec -i tinyconductor tinyconductor hash-password |
CONDUCTOR_IDENTITY_DEFAULT_PROVIDER | With more than one identity provider (local users count as one): local or an OIDC alias (CONDUCTOR_OIDC_ALIAS, default sso), the provider whose people a plain username such as alice names; others are written alice@<alias> |
CONDUCTOR_SESSION_IDLE_TIMEOUT_S, CONDUCTOR_SESSION_ABSOLUTE_TIMEOUT_S, CONDUCTOR_SESSION_INSECURE_COOKIE | Browser session policy: 1800 s idle, 43200 s absolute, Secure cookie |
CONDUCTOR_ALLOW_ANONYMOUS | Turns authentication off. Warns at every startup, shows a banner in the console, and cannot be combined with a non-loopback bind, with credentials, or with OIDC or local users. Only 1 and true turn it off; 0, false, empty and unset keep authentication on; any other value is refused at startup |
To rotate a token, list the old and the new token for one subject, move the callers to the new one, then remove the old entry. The subject never changes, so the audit log keeps naming the same caller:
[{"token":"OLD","subject":"ops","tenantId":"default","kind":"service","actions":["*"]}, {"token":"NEW","subject":"ops","tenantId":"default","kind":"service","actions":["*"]}]Exposure
Section titled “Exposure”CONDUCTOR_SERVER_LISTEN_HOST is 0.0.0.0 and should stay that way. Inside a
container that is the correct address. Docker’s published port targets the container’s own
interface, so a loopback bind would make the published port unreachable.
You control who can reach the engine with the publish address instead.
-p 127.0.0.1:8080:8080— this host only. What the quickstart uses.-p 0.0.0.0:8080:8080— routable. A deliberate step; keep the credential and put TLS in front of it.- Remote access is an SSH tunnel or a reverse proxy to the loopback-published port, not a wider bind.
The engine refuses to start when CONDUCTOR_ALLOW_ANONYMOUS is combined with a
non-loopback bind. The generated token means credentials exist by default,
so the container’s own 0.0.0.0 bind starts normally.
PostgreSQL
Section titled “PostgreSQL”PostgreSQL runs with listen_addresses='', so it has no TCP listener at all.
The only way in is the Unix domain socket inside the container, and
publishing a port cannot expose the database. To attach a streaming standby,
set CONDUCTOR_POSTGRES_LISTEN_ADDRESSES (plus CONDUCTOR_POSTGRES_OPTIONS if you need
more server settings) and add the matching pg_hba.conf rules in the volume.
On the first start the image creates two PostgreSQL logins:
postgres, the superuser, for your own administration over the socket. It logs in only with its password, which the image generates and keeps on the volume;docker exec -it tinyconductor psqluses it for you;tinyconductor, which the engine uses. It owns thetinyconductordatabase, is not a superuser and cannot bypass row-level security.
The image sets CONDUCTOR_DATABASE_URL for the engine; don’t set it yourself.
Runs without root
Section titled “Runs without root”The container runs as its own user, tinyconductor (uid and gid 65532),
never as root, with no capabilities and no way to gain privileges. It writes
only to its volume, so it runs with --read-only, --cap-drop ALL and
--security-opt no-new-privileges, and in a Kubernetes pod with a read-only
root file system. The engine runs in a sandbox of the Linux kernel
(Landlock) that keeps it away from PostgreSQL’s files and the superuser’s
password, so code running in the engine cannot act as the database
superuser. See Bundled mode for
what it needs and what it does not cover. On the volume, PostgreSQL’s data is
in pgdata, its socket in run, the superuser’s password in admin and
the engine’s own files in tinyconductor.
Upgrading
Section titled “Upgrading”Data from preview builds
Section titled “Data from preview builds”Data written by preview builds before 0.1.0 is not carried over. On such a
volume the container stops with a message that says what to do: stop the
container, remove its data volume (docker volume rm tinyconductor-pgdata,
or whichever volume you mounted at /var/lib/postgresql/data), and start
the 0.1.0 image with a fresh volume. Then deploy your process models again.
Upgrading to later releases
Section titled “Upgrading to later releases”From 0.1.0 on, the database is upgraded forward automatically: when a newer version starts on the same volume, it updates the database layout before it serves requests. Back up the volume first, stop the old container, and start the new image on the same volume. An older version cannot be started again on a database that a newer version has upgraded; restore the backup instead.
Notices
Section titled “Notices”Third-party notices for everything bundled here ship inside the image at
/usr/share/tinyconductor/THIRD_PARTY_NOTICES.md and in
THIRD_PARTY_NOTICES.md. No connector runtime is
bundled.