Appearance
Filesystem ​
4ALLPORTAL is only deployed as a Docker container. The image ships the core app embedded at /4allportal-core, the startup script at /startup.sh (the container entrypoint) and the installation folder at /4allportal (working directory). Only /4allportal/data holds state and is mounted as a volume.
/ (container root)
├── startup.sh (entrypoint)
├── 4allportal-core (core app embedded in the image)
│ ├── 4app.json
│ ├── application
│ ├── global
│ ├── modules
│ ├── updates
│ ├── release-notes
│ └── _runtime_core
│ ├── 4allportal-core.jar (Main Jar)
│ ├── derivateservice.jar
│ └── libs/*.jar
└── 4allportal (Installation folder, $INSTALL_DIR)
├── data (persistent volume)
│ ├── config
│ │ └── general.xml (default language and available languages)
│ ├── apps
│ │ ├── order.txt (optional)
│ │ ├── deactivated.txt (optional)
│ │ ├── 4allportal-core -> /4allportal-core (symlink to the embedded core app)
│ │ ├── app1.4app
│ │ ├── app2.4app
│ │ └── ...
│ ├── apps_repository
│ │ ├── 4allportal-dam/6.1.2/4allportal-dam.4app
│ │ ├── 4allportal-essentials/6.1.0/4allportal-essentials.4app
│ │ └── ...
│ ├── custom
│ │ ├── application
│ │ ├── global
│ │ ├── modules
│ │ └── updates
│ └── cefs
├── tools (exiftool, ffmpeg, ghostscript, imagemagick, libraw)
├── _runtime_core -> /4allportal-core/_runtime_core
└── _runtime (recreated on every startup)
├── application
│ ├── html
│ └── libs
├── global
└── modules
Configuration ​
Most configuration (general, database, mail, ...) is passed as environment variables, e.g. GENERAL_ADMIN_PASSWORD (required, the container refuses to start without it), GENERAL_EXTERNAL_URL, DATABASE_HOST, DATABASE_USER, DATABASE_PASSWORD, MAIL_HOST. The default language and available languages are the exception — they are still persisted to data/config/general.xml and managed via the admin UI.
Startup script ​
/startup.sh is the container entrypoint:
- Validates that
GENERAL_ADMIN_PASSWORDis set and thatdataanddata/appsare readable/writable. - Ensures the core app is available in
data/apps: if none is installed, it symlinks the embedded/4allportal-core. If an installed core app differs from the embedded one, the newer version wins — the embedded app replaces an older installed one, while a newer core app indata/apps(as folder or.4app) has itsruntime_corecopied/extracted to_runtime_core. WithMANAGED=true(e.g. Kubernetes) the embedded core always wins. - Rebuilds
_runtime/application/libsfrom theapplication/libsof all apps indata/apps(apps listed indeactivated.txtare skipped). - Starts the JVM with
_runtime_core/4allportal-core.jarand restarts it in a loop as long as it exits with code 0 (in-place restart without recreating the container).
The _runtime_core folder cannot be modified by reload and only changes when the container (image) is updated.
App installation and restart ​
On startup the core reads the apps to install from APPS_INSTALL (comma-separated list) and downloads any missing apps from the apps repository into data/apps_repository, activating them in data/apps. Apps that fail to load are written to data/apps/deactivated.txt and skipped from then on.
Whenever the set of active apps changed (apps were installed, updated or deactivated), the core exits with code 0. startup.sh then rebuilds _runtime/application/libs — now including the libs of the newly installed apps — and starts the JVM again, so the next start runs with the complete classpath.

