Skip to main content

Architecture

A Liberty Next install always has the same parts. Docker or Python only changes where each part lives and which command drives it (./liberty or liberty-ops).

PartWhat it is
The serverOne Python process: the web application, the REST API, the Nomaflow job scheduler and the live updates (Socket.IO) on the same port.
The framework databaseNomaflow run history, saved grid views, change packages, notifications, upgrade history — and users and roles when they are kept in the database rather than in auth.toml.
The configurationTOML files: pools, connectors, dictionary, menus, screens, dashboards, charts, notification rules, Nomaflow jobs, application settings. Everything saved in Settings is written there.
The licensed apps (optional)Nomasx-1, Nomajde and their jobs: configuration files, Python code (plugins/) and reference data, delivered as one wheel.
Two secretsThe master key, which encrypts the passwords stored in the configuration, and the key that signs the sessions.

The data the applications show stays in your databases (Oracle, PostgreSQL…): Liberty Next reads them through the pools of its configuration and copies nothing unless a Nomaflow job is told to.


At a glance — the full Docker layout​

Browserusers · API clientsDOCKER HOST — FULL LAYOUTTraefik:80 / :443 — routes /, /pgadmin, /portainer, /traefik · TLSliberty-nextone processWeb appscreens, dashboards, SettingsAPI/api · /admin · /authSchedulerNomaflow jobsLive updatesSocket.IO: bell, locksreads its configuration, writes its historyPostgreSQLframework + app databasesvolume pg-dataConfigurationTOML saved by Settingsvolume liberty-config · ./appspgAdmindatabase console · /pgadminPortainercontainer console · /portainerYour databasesOracle · PostgreSQLREST APIsAPI connectorsServicesSMTP · OIDC · Anthropicoutside the hostOne URLTraefik sends each path to its serviceLicensed apps./apps mounted on /apps: config + plugins

Three ways to run it​

Docker — lightDocker — fullPython
Serverliberty-next containerliberty-next containerpipx package run by systemd
Around it—PostgreSQL 16, Traefik, pgAdmin, Portainer containersYour PostgreSQL, your reverse proxy
Framework databaseSQLiteBundled PostgreSQLYour PostgreSQL (SQLite for a trial)
Addresshttp://<host>:8000/http(s)://<host>/http://<host>:8000/ behind your proxy
HTTPSYour own proxyTraefik (HTTPS and Traefik)Your own proxy
Licensed appsPossible, but they need PostgreSQLYesYes
Operations command./liberty./libertyliberty-ops
PageDockerDockerPython server

On the full layout Traefik is the only entry point: it sends / to Liberty Next and /pgadmin, /portainer, /traefik to the tools. PostgreSQL is published on 127.0.0.1:5432 only — reachable from the host or through an SSH tunnel, not from the network.


Where the configuration lives​

The configuration is split in two places — the same rule for Docker and Python:

FilesLocation
app.toml (application settings, licence, AI, SSO, SMTP) and auth.toml (local users and roles)The config/ folder of the server's working directory — or the file named by LIBERTY_APP_CONFIG for app.toml.
connectors.toml, dictionary.toml, menus.toml, screens.toml, dashboards.toml, charts.toml, notifications.toml…The folder named by LIBERTY_APPS_DIR when it is set — the config/ folder of the licensed apps — otherwise the same config/ folder.
jobs.toml (Nomaflow)plugins/nomaflow/jobs.toml next to that folder (LIBERTY_APPS_DIR/../plugins/…), otherwise config/jobs.toml.
History of the configuration and of the upgrades (.versions/)Next to connectors.toml.

Hence the layout of the licensed apps folder, the same in Docker and in Python:

apps/
├── config/ ← LIBERTY_APPS_DIR: connectors, screens, menus, dictionary… and .bundled/ (what was delivered)
├── plugins/ ← the apps' Python code, and nomaflow/jobs.toml
└── data/ ← reference data loaded at installation

Where everything lives​

WhatDocker — lightDocker — fullPython (paths of the Python server page)
app.toml, auth.tomlvolume liberty-configvolume liberty-config/var/lib/liberty-next/config/
Other configuration filesvolume liberty-config, or release/apps/config/ with the licensed appssame/var/lib/liberty-next/apps/config/
Licensed apps code and datarelease/apps/plugins/, release/apps/data/ (mounted on /apps)same/var/lib/liberty-next/apps/plugins/, …/data/
Framework databaseSQLite in volume liberty-dataPostgreSQL in volume pg-datayour PostgreSQL server
Licensed apps databases (nomasx1, nomajde)—PostgreSQL in pg-datayour PostgreSQL server
Secretsrelease/.envrelease/.env/etc/liberty/secrets.env
Tools, certificates—volumes pgadmin-data, portainer-data, traefik-acme—
Backupsrelease/backups/release/backups/backups/ next to the configuration folder

On Docker, stopping, recreating or upgrading the containers never touches the volumes nor release/apps/; only docker compose down -v or ./liberty install --reset deletes the volumes. What each backup contains is on Operations.


The two secrets​

The Docker installation generates both into release/.env (mode 0600); on a Python install you generate them into the service's environment file. Keep a copy outside the server.

SecretUsed forIf it changes
LIBERTY_MASTER_KEYEncrypts every ENC: value of the configuration: pool passwords, the licence key, the AI key, the OIDC secret, the SMTP password.Every encrypted value becomes unreadable — the pools stop connecting. Never change it on an existing install.
LIBERTY_JWT_SECRETSigns the session tokens.Everybody is signed out and signs in again. Nothing else is lost.

doctor (Docker or Python) checks that both are at least 32 characters long and that the master key really decrypts every pool password. Every LIBERTY_* and POSTGRES_* variable can also be read from a file: LIBERTY_MASTER_KEY_FILE=/run/secrets/master_key (Docker, Swarm or Kubernetes secrets).


What happens when the server starts​

  1. The settings are read; ${VARIABLE} references in the TOML files are replaced by the environment.
  2. Docker only: secrets given as files are read, the ownership of the configuration volume and of the apps folder is fixed, then the process drops root and runs as the liberty user (uid 1000). On a first start without licensed apps, the default configuration files are copied into liberty-config — an existing file is never overwritten.
  3. Docker only: liberty-admin init-db creates the framework tables that are missing and, on the very first start, the admin user. On a Python install you run it once yourself.
  4. The framework's own tables are compared with the version of the code: a missing column is added and recorded in Settings → History → Upgrades.
  5. Pending schema migrations of the licensed apps are reported in the log; they are applied by the upgrade or by migrate (Docker: also at start-up with LIBERTY_AUTO_MIGRATE=1).
  6. The server starts answering, even if the framework database is still unreachable — so that a pool can be fixed from Settings. /ready says when the database answers.

Health and versions​

URLAnswersUsed by
/healthThe process is up.Liveness probes.
/readyThe framework database answers (503 when it does not).The Docker healthcheck — a stack whose database is down shows unhealthy — and liberty-ops start, which waits for it.
/infoVersion and counts; connector and pool names only for a signed-in user.Quick checks, support.
/docs, /redocThe REST API reference.Developers — see REST API.

Versions, pending migrations and the last upgrade are gathered by status — see Operations.