Head Office
A head-office (HO) setup is usually more complex than a standalone POS setup, such as using multiple service-tiers, SQL server on a different machine and etc. This section descibes the key differences and how you can use Update Service in these cases and what to beaware of.
Multiple Service-tiers
A common practice is to run multiple service-tiers that connect to the same database, which is accomplished by installing multiple instances with the bc-server
argument, ConnectionString
set to the database to connect to. But there are some limitations you must beaware of:
- Only one main instance can update the database (platform upgrade, apps, license, etc...).
- Secondary instances should not update the database and should not include any packages that install into the database such as apps, objects, license, etc.
- Also, to ensure no database changes, set bc-server.NoDatabaseUpgrades = 'true'.
During a platform upgrade you must take extra care to update in correct order:
- Create a backup of the database (database on different machine).
- Stop all secondary instances (with argument bc-server.NoDatabaseUpgrades = 'true').
- Update the main instance (with bc-server.NoDatabaseUpgrades = 'false').
- Update all secondary instances (with bc-server.NoDatabaseUpgrades = 'true').
Warning
Only one instance can take care of database updates, such as platform upgrade, apps, license and objects.
Warning
When there is a platform upgrade, stop all secondary instances, update the main instance, and then update secondary instances.
SQL Server on a Different Machine
Installation
Database packages are based on backup files that can't be restored from a different machine than the SQL server. Thus, do not include database packages in bundle packages in these cases. Either restore the database manually or install the database package on the SQL server. When you install the bundle package, you can specify what database to connect to, either in the wizard or specify the argument bc-server.ConnectionString.
Database packages are based on backup files that cannot be restored from a machine other than the SQL server. Therefore, it is advised not to include database packages in bundle packages under such circumstances. Instead, manually restore the database or install the database package directly on the SQL server. During the installation of the bundle package, you have the option to specify the database to connect to either through the wizard or by specifying the argument bc-server.ConnectionString.
Database packages rely on backup files, which can only be restored from the same machine as the SQL server. Therefore, database packages should not be included in bundle packages in these situations. Instead, choose to either manually restore the database or install the database package directly on the SQL server machine. During the bundle package (with no database package) installation, you have the option to select the database to connect to. You can do this either through the installer or by specifying the argument bc-server.ConnectionString via PowerShell.
The SQL server also needs to have the Business Central database components installed. You can do this, for instance, by using the Update Service command: Install-UscPackage -PackageId 'bc-db-components'
.
Updates
When you update a Business Central instance and the SQL server is on the same machine, a database backup is created first. If any error happens during the update, all changes are rolled back, the database backup is restored, and the instance should return to being operational.
However, when the SQL server is on a different machine, no backup is created. If the update fails, the platform is rolled back, but the database isn't. This could leave the instance non-operational and potentially brick the current database.
Therefore it's important to back up the database before it's updated.
Warning
Update Service will not automatically create a database backup if the SQL server is on a different machine.
Portsharing + Domain User
By default, service-tiers are installed with Portsharing enabled (bc-server.PortSharing = 'true'), allowing multiple service-tiers to run on the same machine and port. If a domain user (or a local user for that matter) is assigned to the service-tier you either need to:
- Disable port sharing on the service tier and use different ports for multiple service-tiers (see configuration key in the example below).
- Add user to <allowAccounts> in SMSvcHost.exe.config
Example:
$Arguments = @{
'bc-server' = @{
# ...
#PortSharing = 'true'
ServiceUser = 'MY_DOMAIN\MyUser'
ServicePassword = 'SomeP@ssword'
}
}
Install-UscPackage -Id 'bundle/head-office-main' -VersionQuery '' -InstanceName 'Main' -Arguments $Arguments
Running NAS
You can configure the NAS to start after installation by supplying the following arguments.
$Arguments = @{
'bc-server' = @{
# ...
NASServicesStartupCodeunit = "99001468"
NASServicesStartupMethod = "LSRSCHEDULER"
NASServicesStartupArgument = "NASID,LOG=1,REPEAT=1"
}
}
Install-UscPackage -Id 'bundle/head-office-secondary' -VersionQuery '' -InstanceName 'Secondary-NAS' -Arguments $Arguments
Examples
Bundle Packages
Here are examples of bundles for main and secondary instances.
You should only have one main instance per database, which handles any database changes, such as platform upgrades, apps, objects and licenses:
$ErrorActionPreference = 'stop'
Import-Module UpdateServiceServer
$BcPlatformVersion = '17.0.20458'
$BcAppVersion = '17.3.20469'
$LsCentralVersion = '17.3.0'
$Package = @{
Id = 'bundle/cronus-head-office-main'
Name = 'Cronus Head Office main setup'
Version = '1.0.0'
Dependencies = @(
@{ Id = "bc-web-client"; Version = $BcPlatformVersion }
@{ Id = "bc-system-symbols"; Version = $BcPlatformVersion }
@{ Id = "bc-system-application-runtime"; Version = $BcAppVersion }
@{ Id = "bc-base-application-us-runtime"; Version = $BcAppVersion }
@{ Id = 'ls-central-app-runtime'; Version = $LsCentralVersion }
@{ Id = 'ls-central-toolbox-server'; Version = $LsCentralVersion }
@{ Id = 'ls-dd-server-addin'; Version = "^ >=3.0 <4.0" }
# Customer specific packages
@{ Id = "cronus-app"; 'Version' = "1.0.0" }
@{ Id = "cronus-license"; 'Version' = "1.0.0" }
)
FillParameters = @{
'bc-server' = @{
AllowSessionCallSuspendWhenWriteTransactionStarted = 'true'
# Few of many optional arguments:
#PortSharing = 'true'
#ManagementServicesPort = '9045'
#ClientServicesPort = '9046'
#SOAPServicesPort = '9047'
#ODataServicesPort = '9048'
#NASServicesStartupCodeunit = "99001468"
#NASServicesStartupMethod = "LSRSCHEDULER"
#NASServicesStartupArgument = "NASID,LOG=1,REPEAT=1"
}
}
OutputDir = (Join-Path $PSScriptRoot 'Output')
}
New-UssPackage @Package
You can have multiple secondary instances with different configurations. Note that this bundle does not include any packages that modify the database and use the setting bc-server.NoDatabaseUpgrades = 'true':
$ErrorActionPreference = 'stop'
Import-Module UpdateServiceServer
$BcPlatformVersion = '17.0.20458'
$LsCentralVersion = '17.3.0'
$Package = @{
Id = 'bundle/cronus-head-office-secondary'
Name = 'Cronus Head Office secondary setup'
Version = '1.0.0'
Dependencies = @(
@{ Id = "bc-server"; Version = $BcPlatformVersion }
@{ Id = 'ls-central-toolbox-server'; Version = $LsCentralVersion }
@{ Id = 'ls-dd-server-addin'; Version = "^ >=3.0 <4.0" }
)
FillParameters = @{
'bc-server' = @{
AllowSessionCallSuspendWhenWriteTransactionStarted = 'true'
NoDatabaseUpgrades = 'true'
# Few of many optional arguments:
#ClientServicesEnabled = 'false'
#SOAPServicesPort = 'true'
#NASServicesStartupCodeunit = "99001468"
#NASServicesStartupMethod = "LSRSCHEDULER"
#NASServicesStartupArgument = "NASID,LOG=1,REPEAT=1"
}
}
OutputDir = (Join-Path $PSScriptRoot 'Output')
}
New-UssPackage @Package
Installation
Now let's say we have a SQL server on a machine with hostname MY_SERVER and you already have a database ready, called MY_DATABASE.
First install the main instance:
$ErrorActionPreference = 'stop'
$Arguments = @{
'bc-server' = @{
ConnectionString = 'Data Source=MY_SERVER;Initial Catalog=MY_DATABASE;Integrated Security=True'
ServiceUser = 'MY_DOMAIN\MyUser'
ServicePassword = 'SomeP@ssword'
}
}
Install-UscPackage -Id 'bundle/head-office-main' -VersionQuery '' -InstanceName 'Main' -Arguments $Arguments
And then one or more secondary instances, only with web services enabled:
$ErrorActionPreference = 'stop'
$Arguments = @{
'bc-server' = @{
ConnectionString = 'Data Source=MY_SERVER;Initial Catalog=MY_DATABASE;Integrated Security=True'
ServiceUser = 'MY_DOMAIN\MyUser'
ServicePassword = 'SomeP@ssword'
ClientServicesEnabled = 'false'
SOAPServicesPort = 'true'
ODataServicesEnabled = 'true'
}
}
Install-UscPackage -Id 'bundle/head-office-secondary' -VersionQuery '' -InstanceName 'Secondary-WS' -Arguments $Arguments
A secondary instance with only NAS enabled:
$Arguments = @{
'bc-server' = @{
ConnectionString = 'Data Source=MY_SERVER;Initial Catalog=MY_DATABASE;Integrated Security=True'
ServiceUser = 'MY_DOMAIN\MyUser'
ServicePassword = 'SomeP@ssword'
ClientServicesEnabled = 'false'
SOAPServicesPort = 'false'
ODataServicesEnabled = 'false'
NASServicesStartupCodeunit = "99001468"
NASServicesStartupMethod = "LSRSCHEDULER"
NASServicesStartupArgument = "NASID,LOG=1,REPEAT=1"
}
}
Install-UscPackage -Id 'bundle/head-office-secondary' -VersionQuery '' -InstanceName 'Secondary-NAS' -Arguments $Arguments