Automated Updates and License Server
A single installation is updated with the automatic or manual update. This page is for the administrators of several myDBR installations, and for everybody who wants to update from a script or let myDBR update itself.
| You want to | Use |
|---|---|
| Check the version and the license of an installation from a script | The status call |
| Update from a script or a cron job, only when there is a new version | The update call |
| Let every installation update itself at night | Automatic updates |
| See and update all your installations from one place | A program that uses these calls, such as the License Manager |
| Keep using scripts that use the older Basic authentication | The older method, which still works |
Enable the automation API
The automation API is off until you create a token.
- Log in as an administrator and open Environment settings, tab Misc, group Automation (updates and licenses).
- Check Generate a token when saving and save the settings.
- Copy the token from the page that opens. It is shown only once, myDBR keeps only its hash. If you lose it, generate a new one.
- Optional: write the addresses that may use the API in Allowed addresses (one address or range in CIDR form on each line), for example
203.0.113.0/24. Leave it empty to allow all addresses. - Require HTTPS is on by default. The token is sent in a header, so use HTTPS on a public server. Calls from
localhostare always allowed.
The calls send the token in the Authorization header:
curl -H "Authorization: Bearer mydbr_0123456789abcdef..." "https://yourserver.com/mydbr/install/index.php?controller=update&action=status"
A call with a missing or a wrong token gets 401 and {"status":"error","error":"Unauthorized"}. A wrong token is written to the log of failed logins. Remove the token (check Remove the token when saving) to turn the API off.
Check the status
The status call tells the version, the latest available version, the license and the state of the installation. It needs no Premium license.
curl -H "Authorization: Bearer $TOKEN" "https://yourserver.com/mydbr/install/index.php?controller=update&action=status"
{
"status": "ok",
"version": "7.6.0",
"build": "5480",
"latest": "7.6.1",
"update_available": true,
"license": { "host": "yourserver.com", "expiration": "2027-04-06", "type": "premium", "key": "153105cd31" },
"php": "8.4.1",
"db": "mysql",
"database_version": "7.6.0",
"database_matches": true,
"files_writable": true,
"updating": false,
"automatic_updates": "off"
}
| Field | Meaning |
|---|---|
latest, update_available | The latest version that the installation knows (it asks the update server every 48 hours). Add &refresh=1 to ask now. null when it is not known, for example with a local update package. |
license.key | The last 10 characters of the license key, to check that the license is the one you expect |
database_version, database_matches | The version of the reporting database. false after an update that stopped half way. An update call completes it. |
files_writable | Whether the application files can be replaced by an update |
updating | An update is running now |
Update from a script
The update call downloads the new version, replaces the files and updates the database. The update and the rollback calls need a Premium license.
curl -X POST -H "Authorization: Bearer $TOKEN" "https://yourserver.com/mydbr/install/index.php?controller=update&action=update&only_if_newer=1"
| Parameter | Meaning |
|---|---|
only_if_newer=1 | Ends with "status":"up_to_date" and downloads nothing when the installation already has the latest version. Use it in cron jobs. |
dry_run=1 | Checks the file permissions and downloads the package, and changes nothing else |
The answer has the old fields and a status:
{
"host": "yourserver.com",
"expiration": "2027-04-06",
"version": { "before_update": "7.5.0/5300", "after_update": "7.6.0/5480" },
"status": "updated"
}
status is updated, up_to_date, dry_run, rolled_back or error (with an error text). The token API uses HTTP status codes: 200 for success, 401 for a wrong token, 403 when the license is not Premium, 409 when another update is running and 500 for a failure.
A script that updates when there is a new version:
#!/bin/bash
# Update myDBR when a new version exists. Run it from cron, for example at 03:00.
URL="https://yourserver.com/mydbr/install/index.php"
TOKEN="mydbr_0123456789abcdef..."
result=$(curl -s -X POST -H "Authorization: Bearer $TOKEN" "$URL?controller=update&action=update&only_if_newer=1")
echo "$(date '+%F %T') $result" >> /var/log/mydbr-update.log
Safety of an update
- One update at a time. An update takes a lock (
update/update.lock). A second call gets409. A lock older than 30 minutes is ignored. - Backup. Before the files are replaced, the application files (not the
user/directory and notmydbr_config.php) are saved toupdate/backup-<version>.zip. The two newest backups are kept. - Automatic restore. If the extraction of the package fails, the files are restored from the backup and the answer has the error.
- Rollback.
action=rollbackrestores the files of the newest backup (for examplecurl -X POST -H "Authorization: Bearer $TOKEN" ".../install/index.php?controller=update&action=rollback"). The database is not changed, so use it when the update did not change the database. After a rollback the status call showsdatabase_matches: falseuntil you update again. - Checksum (off by default). The update server does not publish checksums yet, so the package is not verified. If your own update server publishes
<package URL>.sha256, set$mydbr_defaults['update']['verify_checksum'] = true;inuser/defaults.phpand the downloaded package is verified with it. Add$mydbr_defaults['update']['require_checksum'] = true;to refuse a package without a checksum. - HTTP and HTTPS. The update check asks
http://www.mydbr.com/latest.php, because many servers cannot verify certificates. Set$mydbr_defaults['update']['check_url'] = 'https://www.mydbr.com/latest.php?v=';when your server can, or point it to your own mirror. The download link of the package is switched tohttps://, unless$mydbr_defaults['update']['use_HTTP'] = true;keeps it on plain HTTP.
Automatic updates and license refresh
An installation can update itself and fetch its own license. Both run from the scheduler, so the cron job that calls scheduler.php must exist, with the allowed address and the user name set on the Scheduler tab (see Scheduled Tasks). Set them in Environment settings, group Automation (updates and licenses):
- Automatic updates: Install new versions. The scheduler installs a new version in the update time window (default 02:00 to 05:59, in the server time). It needs a Premium license. If an update fails, it is tried again after six hours. The result of the last update is shown under the setting.
- Fetch a new license from the license server. When the license expires within 14 days (or has expired), the installation fetches its license from the license server (the last result is shown under the setting). Set the server in
user/defaults.php:
$mydbr_defaults['license_server']['server_url'] = 'https://license.mycompany.com/mydbr';
// The token of the license server (its Environment settings, Automation). Without it the older username and password are used.
$mydbr_defaults['license_server']['token'] = 'mydbr_0123456789abcdef...';
Many installations
The status, update, rollback and license calls above work the same for every installation, so one program can follow a whole fleet: ask the status of each installation, start the update on the outdated ones, and have each installation fetch its license from a central place.
Organizations with many installations can use the separate myDBR License Manager application. It lists the installations with their version and license, highlights the ones that need a new license or an update, and installs them with these calls. It is a standalone PHP application with its own documentation.
An installation fetches its license from a license server or from the License Manager with the token, set in user/defaults.php:
$mydbr_defaults['license_server']['custom_server'] = true;
$mydbr_defaults['license_server']['server_url'] = 'https://manager.example.com/license.php?get=reports.example.com';
$mydbr_defaults['license_server']['token'] = 'the token of the license server';
The call that makes an installation fetch its license is index.php?a=license_service&update=1 with the token of the installation, see Automatic updates and license refresh.
Security
- Use HTTPS, and keep Require HTTPS on. The token is a secret like a password.
- Limit the callers with Allowed addresses. Only the address of the connection is used, not forwarding headers.
- Generating a new token replaces the old one at once. When the license server uses one token for all installations, change it on all of them and on the server at the same time.
- A program that follows many installations has all their tokens. Protect it and its database like a password store.
Older method (Basic authentication)
The scripts that use Basic authentication keep working as before. The older method needs:
- A Premium license on the installation that is called (the token API needs it only for updates).
- A local myDBR user for the calls:
mydbr_updaterfor updates andlicense_checkerfor licenses (the names are in$mydbr_defaults['updater_users']and['license_users']). These users cannot log in normally. - The header
X-MYDBR-AUTH: 1, which keeps a browser from sending the credentials by accident. - For a license fetched from a license server without a token, the user name of
$mydbr_defaults['license_server']['username']and the same password on both servers (when no password is configured, the password of the call is passed on).
Updating from a script (Basic authentication)
The update process can be fully automated using scripts.
Retrieving the Current Version
To retrieve the current myDBR version and build information in JSON format, use the following command:
curl "https://yourserver.com/mydbr/index.php?a=version&export=json"
The response provides the version and build:
{
"version": "7.6.0",
"build": "5480"
}
This endpoint also supports JSONP by adding a callback parameter. The response will include a key field containing the last 10 characters of your license, which can be used to verify license validity in your scripts.
Executing an Automated Update
Scripted updates use HTTP Basic Authentication. By default, myDBR includes a mydbr_updater user for this purpose (configurable in defaults.php). To use this feature, add the mydbr_updater user to your myDBR installation. This user is restricted to update operations and cannot be used for standard logins.
Run the following command to initiate an update (replace credentials and URL accordingly):
curl -H "X-MYDBR-AUTH: 1" -u mydbr_updater:password "https://yourserver.com/mydbr/install/index.php?controller=update&action=update"
A successful update returns a JSON object with version details:
{
"host": "yourserver.com",
"expiration": "2027-12-22",
"version": {
"before_update": "7.5.0/5300",
"after_update": "7.6.0/5480"
}
}
If the update fails, an error field is included with the failure reason.
Automated license management (Basic authentication)
For environments with multiple myDBR installations, you can designate one instance as a License Server to manage and distribute licenses centrally.
Configuring the License Server
- Enable the license server role in
user/defaults.phpon the primary instance:$mydbr_defaults['license_server']['is_server'] = true; - Create a dedicated local user (default:
license_checker) on the license server. - Add all purchased licenses to the license server's Licenses tab.
Configuring Client Instances
On each client server, specify the URL of the primary license server in user/defaults.php:
$mydbr_defaults['license_server']['server_url'] = 'https://your-license-server.com/mydbr';
Distributing Licenses
To trigger a license update on a client server, use the following command:
curl -H "X-MYDBR-AUTH: 1" -u license_checker:password "https://client-server.com/mydbr/index.php?a=license_service&update=1"
A successful retrieval returns {"status":"ok"}. Errors are returned in a success: "error" object containing an array of specific failure messages.
Managing large-scale installations
For environments with numerous myDBR instances, we recommend automating the update and license management processes. You can utilize scheduled reports on client instances to request new licenses or deploy a centralized management report to oversee distribution and updates across your entire infrastructure.
Centralized license and update management (management report)
The following example demonstrates a management report designed to run on a primary License Server. This report monitors the version and license status of multiple client servers and allows administrators to initiate remote updates and license distribution from a single interface.
Preparation
- Client Configuration: Add the
mydbr_updaterandlicense_checkerusers to all client servers (default names are defined in$mydbr_defaults['updater_users']and$mydbr_defaults['license_users']). - Server Configuration: Add the
license_checkeruser to the primary License Server (defined in client servers via$mydbr_defaults['license_server']['username']and$mydbr_defaults['license_server']['password']). - Connectivity: Define the
server_urlfor the License Server on each client instance. - Role Activation: Enable the
is_serverrole on the primary License Server by adding$mydbr_defaults['license_server']['is_server'] = true;to its configuration. - License Import: Upload all relevant licenses to the primary License Server.
- Report Deployment: Install the monitoring report (detailed below) on the License Server.
Workflow Summary
- Version Updates: The management report compares the version and build of each client against the latest available. Administrators can click a version indicator to trigger a remote update via JSONP and Basic Authentication.
- License Synchronization: The report identifies clients with outdated or missing licenses. A single click initiates a license refresh, where the client server securely retrieves its assigned license from the management server.
Management Stored Procedure
create procedure sp_DBR_update_license(
inVersionBuild varchar(20)
)
begin
select 'dbr.css', '
.license_status { text-align: center; }
.license_update, .version_update {
cursor: pointer;
background-color: green;
padding: 3px 6px;
border-radius: 6px;
color: white;
}
.red { background-color: red; }
.version { text-align: center; }
.version .ajaxspin { margin: auto; }
';
select 'dbr.colclass', 'host', 'host';
select 'dbr.colclass', 'license_status', 'license_status';
select 'dbr.colclass', 'version', 'version';
select 'dbr.colclass', 'errors', 'errors';
select 'dbr.html5data', 'host', 'license_key', 'license-key';
select 'dbr.html5data', 'host', 'license_host', 'license-host';
select 'dbr.html5data', 'version', 'version_build', 'version';
select
concat('https://', host) as 'Installation URL[host]',
l.host as 'license_host',
l.license_key,
'' as 'Version[version]',
'' as 'License OK[license_status]',
inVersionBuild as 'version_build',
'' as '[errors]'
from mydbr_licenses l
where host != 'mylicenseserver.mydomain.com';
select 'dbr.javascript',
"$(document).ready(function() {
// Retrieve installed versions and license hashes
$('.host').each( function() {
var $tr = $(this).closest('tr'),
url = $(this).text()+'/index.php?a=version&export=jsonp&callback=?';
$.ajax({
url: url,
dataType: 'jsonp',
success: function(v) {
var $v, vb, key_ok = (v.key == $tr.find('.host').attr('data-license-key').substr(-10));
$v = $tr.find('.version');
vb = v.version+'/'+v.build;
if ($v.data('version') !== vb) {
$v.html('<span class=\"version_update\">'+vb+'</span>');
} else {
$v.text(v.version+'/'+v.build);
}
if (key_ok) {
$tr.find('.license_status').text('OK');
} else {
$tr.find('.license_status').html('<span class=\"license_update\">Newer license available</span>');
}
},
error: function(e, status, error) {
$tr.find('.version').text('Unknown');
$tr.find('.errors').text(e.status+'/'+error);
}
});
});
// Initiate remote license update
$(document).on('click', '.license_update', function() {
var url, $tr = $(this).closest('tr');
url=$tr.find('.host').text()+'/index.php?a=license_service&update=1&callback=?';
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader('X-MYDBR-AUTH', '1');
xhr.setRequestHeader('Authorization', 'Basic ' + btoa('license_checker:password'));
},
dataType: 'jsonp',
success: function(r) {
if (r.status=='ok') {
$tr.find('.license_status').text('OK');
} else {
$tr.find('.license_status .license_update').addClass('red');
var e = r.errors.map(function(err){ return '<div>'+err+'</div>'; }).join('');
$tr.find('.errors').html(e);
}
},
error: function(e, status, error) {
$tr.find('.errors').text(e.status+'/'+error);
}
});
});
// Initiate remote application update
$(document).on('click', '.version_update', function() {
if (confirm('Execute remote update?')) {
var url, $tr = $(this).closest('tr'), $v = $tr.find('.version');
url=$tr.find('.host').text()+'/install/index.php?controller=update&action=update&callback=?';
$v.html('<div class=\"ajaxspin\"></div>');
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.withCredentials = true;
xhr.setRequestHeader('X-MYDBR-AUTH', '1');
xhr.setRequestHeader('Authorization', 'Basic ' + btoa('mydbr_updater:password'));
},
dataType: 'jsonp',
success: function(r) {
if (r.error) {
$v.text(r.error);
} else {
$v.text(r.version.after_update || 'Unknown error');
}
},
error: function(e, status, error) {
$tr.find('.errors').text(e.status+'/'+error);
}
});
}
});
});
";
end