All constants live in config.php, copied from config.sample.php. Each has
a default in includes/bootstrap.php; a minimal config.php only needs
MANAGE_PUBLIC_URL and MANAGE_ADMIN_PASSWORD_HASH.
The client's constants are in ../client-package/docs/03_CONFIG_REFERENCE.md.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_PRODUCT_NAME |
"Managed Application" |
display name in the UI |
MANAGE_PACKAGE_PREFIX |
"release" |
filename prefix of stored packages: <prefix>-vX.Y.Z.zip |
| Constant | Default | Meaning |
|---|---|---|
MANAGE_PUBLIC_URL |
"" |
absolute base URL of this installation, without a trailing slash |
This value builds the download URL clients receive in the manifest. It is
deliberately not derived from the Host header: a spoofed header could
otherwise redirect a client to a foreign server.
If the value is empty, the overview reports a warning and manifest.php
responds with an error.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_ADMIN_PASSWORD_HASH |
– | bcrypt hash, checked with password_verify() |
MANAGE_ADMIN_PASSWORD |
– | plaintext alternative, checked with hash_equals() |
The hash takes precedence. It is ignored as long as it still holds the
placeholder from config.sample.php — so an unfinished configuration fails
visibly instead of allowing an open login.
php -r 'echo password_hash("a-long-password", PASSWORD_DEFAULT), PHP_EOL;'
Use single quotes; a bcrypt hash contains $.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_STORAGE_DIR |
__DIR__ . "/storage/" |
root for instances, releases, backups, logs |
All other paths derive from this one and don't need to be set individually:
storage/instances.json, storage/settings.json,
storage/releases/manifest.json, storage/releases/packages/,
storage/backups/, storage/logs/.
The directory must not be reachable over the web.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_BACKUP_RETENTION |
30 |
local backups per instance. Minimum 1 |
MANAGE_BACKUP_MAX_UPLOAD_BYTES |
0 |
extra size limit; 0 disables it |
The value stored in the UI (storage/settings.json) takes precedence over
MANAGE_BACKUP_RETENTION once it has been saved.
MANAGE_BACKUP_MAX_UPLOAD_BYTES sits above the PHP limits:
upload_max_filesize and post_max_size apply regardless and are usually
lower.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_S3_ENABLED |
false |
turn archiving on |
MANAGE_S3_ENDPOINT |
"" |
e.g. https://fsn1.your-objectstorage.com |
MANAGE_S3_REGION |
"" |
region for the signature |
MANAGE_S3_BUCKET |
"" |
bucket name |
MANAGE_S3_PREFIX |
"" |
key prefix in the bucket, may be empty |
MANAGE_S3_ACCESS_KEY |
"" |
access key |
MANAGE_S3_SECRET_KEY |
"" |
secret key |
MANAGE_S3_PATH_STYLE |
false |
false = virtual-hosted, true = path-style |
MANAGE_S3_TIMEOUT |
120 |
seconds per HTTP request |
MANAGE_S3_RETENTION |
365 |
S3 backups per instance |
The archive only counts as active when MANAGE_S3_ENABLED is set and
endpoint, region, bucket, access key and secret key are all filled in. A
half-done configuration stays inert instead of failing on every upload.
Behavior and troubleshooting: SERVER_SETUP.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_LOGIN_RATE_LIMIT_MAX |
10 |
failed UI attempts per window and IP |
MANAGE_LOGIN_RATE_LIMIT_WINDOW |
900 |
window in seconds |
MANAGE_API_RATE_LIMIT_MAX |
240 |
failed API authentications per window and IP |
MANAGE_API_RATE_LIMIT_WINDOW |
300 |
window in seconds |
State lives in storage/ratelimit/. A successful authentication resets the
IP's counter. If the state directory isn't writable, the limiter
deliberately lets requests through instead of locking everyone out.
| Constant | Default | Meaning |
|---|---|---|
MANAGE_LOG_MAX_BYTES |
1048576 |
rotate once a log reaches this size |
MANAGE_LOG_KEEP_FILES |
5 |
number of rotated files kept |
MANAGE_LOG_MAX_AGE_SECONDS |
2592000 |
delete rotated files after this (30 days) |
Applies to access.log and error.log. s3.log grows unbounded and is
trimmed by hand when needed.
<?php
define("MANAGE_PRODUCT_NAME", "Example Orderform");
define("MANAGE_PACKAGE_PREFIX", "example-orderform");
define("MANAGE_PUBLIC_URL", "https://manage.example.org");
define("MANAGE_ADMIN_PASSWORD_HASH", '$2y$12$…');
Everything else takes the default values.