Deploying Your SmartDesktop

A simple analogy is that a Finsemble SmartDesktop is a desktop-deployed web app. Finsemble displays web assets using a technology we call a "container". As such, deploying Finsemble consists of three aspects:

  1. Finsemble assets that are deployed to a hosting server.
  2. An executable that installs the container to end users' desktops. The executable can be distributed to users' desktops like any other software. Once installed, a desktop icon and Start menu entry for your SmartDesktop are created. When an end user clicks the desktop icon, your SmartDesktop is loaded from the assets on your server.
  3. Methods for updating your SmartDesktop. In general, updates are handled in a similar manner to updating a website.

This tutorial will step through these three aspects of deployment.


Hosting Finsemble Assets

Your components and assets need to be hosted on a web server so they can be retrieved by your end users.

The hosting servers can be internal—inside your firewall and accessible only to people on your corporate network—or external—available to anyone with internet access. A Finsemble SmartDesktop can be made of components hosted on a mixture of internal and external servers. Ideally, all of the components would be hosted from the same server because this allows for the faster Shared Worker communication. For details, see the Router documentation.

To host your assets:

  1. Ensure that component URLs are correct for production. These URLs are (typically) found in config/application/component.json.
  2. Ensure that your manifest URLs are correct for production. There are several paths defined in config/application/manifest-local.json that will need to be updated: crucially, your configuration variables.
    • URL variables are an important tool for deployment because they allow you to control the environment: development, staging, or production. If components are built as part of Finsemble, use $applicationRoot as the URL base.
  3. Build using a build system. See our example in package.json. Running npm build:prod from the command line will build the production assets and output them to the dist folder.
  4. Copy the finsemble folder to your $moduleRoot location, as defined in your manifest.
  5. Copy the contents of the dist folder to your $applicationRoot locations, as defined in your manifest.
  6. Create the URL to your manifest file. This is done by using the URL used in $applicationRoot and adding configs/application/manifest-production.json after it. Example: http://webserver/path/to/finsemble/configs/application/manifest-production.json. The URL for your manifest file is required for your installer (detailed below).

Creating the Installer

To create the installer you will first need to update the configuration files and then build the installer via the makeInstaller scripts in package.json. You may also need to sign the installer too.

Configuration Files

The installer is configured via three config files. These files will need to be updated or created to reflect the environment you want to build for. For example, you may need to make an installer for Dev, Staging, UAT, Prod and more. The steps below demonstrate how to make an installer for a production environment; the process is the same for other environments.

The three config files are:

  1. configs/other/server-environment-startup.json
  2. configs/other/installer.json
  3. configs/manifest_[environment].json (e.g. configs/manifest_local.json)

1 - Server Environment Startup Config:

Ensure that configs/other/server-environment-startup.json has a property named for the environment you wish to deploy to, e.g. production and that the URLs, ports and other values match your deployment server (see Hosting your Finsemble Assets). In the example below, we are using localhost, so you will need to change this to match the domain your files are hosted on. The updateURL should also be changed to match the folder where your binary files are hosted when creating an installer. We use pkg as the default folder name for our installer (find out more about auto-updates in Updating your container).

Example:

{
  "production": {
      "serverPort": 3375,
      "serverConfig": "http://localhost:3375/configs/application/manifest-local.json",
      "clientRoute": "http://localhost:3375/",
      "electronDebug": true,
      "breakpointOnStart": false,
      "updateUrl": "http://localhost:3375/pkg",
      "chromiumFlags": {
        "remote-debugging-port": 9222
      }
  }
}

2 - Installer Config

The default installer configuration provided in configs/other/installer.json will be used for each installer environment (e.g. development, staging, uat, production, etc). Each property as defined in the Config Reference. In here you will define the following (and more):

  • The name of your SmartDesktop
  • Version number
  • Icon for your SmartDesktop (plus a specific icon and background for macOS)
  • Author(s) and description
  • Certificates (see more in the section on Signing an installer below)

However, if you need to configure installers differently for each environment (allowing you to customize the installer name, start menu entries, and icon for example) you can add multiple entries in the same way as Server Environment Startup Config and using the same environment names.

Example:

{
  "development": {
    "icon": "./assets/img/installer_dev_icon.ico",
    "version": "5.0.0",
    "outputDirectory": "./dev-installer",
    "name": "Finsemble-Dev",
    "authors": "Cosaic",
    "description": "Finsemble Desktop - development",
    "certificateFile": null,
    "certificatePassword": null,
    "signWithParams": null,
    "background": "./assets/img/background.png",
    "macIcon": "./assets/img/installer_icon.icns"
  },
  "production": {
    "icon": "./assets/img/installer_icon.ico",
    "version": "5.1.0",
    "outputDirectory": "./prod-installer",
    "name": "Finsemble",
    "authors": "Cosaic",
    "description": "Finsemble Desktop- production",
    "certificateFile": null,
    "certificatePassword": null,
    "signWithParams": null,
    "background": "./assets/img/background.png",
    "macIcon": "./assets/img/installer_icon.icns"
    }
}

3 - Installer Manifest Files

Inside the configs folder is the file manifest_local.json. The example used in Server Environment Startup Config uses "serverConfig": "http://localhost:3375/configs/application/manifest-local.json" as the manifest. We recommend that you make a manifest file per environment e.g. manifest-UAT.json, manifest-production.json. You can copy the example from manifest-local.json but make sure that you change the file values (URLs, ports, etc.) to match your deployment servers.

Build the Installer

The Finsemble seed project comes with a utility function for generating an installer. This function is run via an makeInstaller scripts, which are run via yarn or npm. For example, run yarn makeInstaller:prod (or npm run makeInstaller:prod if using npm) to build the installer for the production environment. Note: This process will take several minutes.

The output of the build will be placed into the outputDirectory that you specified in your installer.json file in the section above (our default example outputDirectory is finsemble-seed/pkg) .

Once your files for the installer have built, you will see the .exe for the installer in the folder. Running the .exe file will install your SmartDesktop, create a launch icon, and start the application.

How to Create Additional Build Installer Commands

We have provided the commands for building both prod and dev environments, but if you need to add additional environment builds, you can create custom installer commands. This part involves editing the package.json file in the root of the seed project.

The NODE_ENV variable needs to match the name of the environment entry you created in the Server Environment Startup Config section above.

Example of new build script for UAT:

"makeInstaller:UAT": "set NODE_ENV=UAT&&gulp makeInstaller --gulpfile=./gulpfile.js",

Silent Installs

To execute a silent install of Finsemble use the command line and add the --silent flag after the path to the finsemble.exe

$ finsemble.exe --silent

Signing an Installer

Code signing is built into the installer creation. Add the following properties to the installer.json file to create a signed installer:

    ...
    "certificateFile": "C:/path/to/cert/file.pfx",
    "certificatePassword": "*********",
    "signWithParams": "/tr http://timestamp.digicert.com"
  }

Set password as null, or omit entirely, to provide password through an environment variable - INSTALLER_CERTIFICATE_PASSPHRASE.

You can set the environment variable at runtime using the command: INSTALLER_CERTIFICATE_PASSPHRASE=****** npm run makeInstaller:env

The example signWithParams above will pass the provided params to the Windows SignTool. This will fetch a timestamp from the included server. For more information see Config Reference.

Specifying Manifests at Run Time

By default, Finsemble will use the manifest that is bundled into the exe (the "embedded" manifest). However, you can specify manifests at run time that will override the embedded manifest. To enable this feature, your initial embedded manifest must contain configurations that explicitly allow runtime manifests. These configurations are made in the finsemble-electron-adapter section of config.

Run time overrides are made by calling your SmartDesktop executable either with specific command line parameters (--manifest-name or --manifest-url) or by launching your SmartDesktop through a "protocol handler" (fsbl://manifest or fsbl://manifest-url).

To allow only specific manifests to be used, make an entry under the manifests property that contains those manifest locations mapped to specific "names".:

    "finsemble-electron-adapter": {
        "manifests": {
            "dev": "http://localhost:3375/configs/application/manifest-local-dev.json",
            "qa": "http://localhost:3375/configs/application/manifest-local-qa.json"
        }
    },

These names can now be used to launch Finsemble with one of the specified manifests: Project.exe --manifest-name dev or fsbl://manifest/dev

You can also specify arbitrary urls at run time: Project.exe --manifest-url http://cosaic.io/configs/application/manifest-local-dev.json or fsbl://manifest-url/http%3A%2F%2Ffinsemble.com%3A3375%2Fconfigs%2Fapplication%2Fmanifest-local-dev.json

However, Finsemble will validate the domains against the allowedManifestDomains entry before allowing them to be used:

    "finsemble-electron-adapter": {
        "allowedManifestDomains": [
            "finsemble.com",
            "cosaic.io"
        ]
    },

If the hostname does not match then Finsemble will exit with a dialog for the user. Hostnames must be an exact match. The only wildcard that is available is "*" which will then allow any run time url.

Note: Ensure that your url is urlencoded when using a protocol handler (see above example.)

Note: You can use both the manifests and allowedManifestDomains together. URLs specified in the manifests property do not need to be from one of the domains specified in allowedManifestDomains.

Dealing with troublesome network connections

Finsemble supports configurable retries and timeouts through command line flags.

Project.exe --manifest-timeout 30000 - Specify a custom timeout for fetching the manifest (in milliseconds). Defaults to 10 seconds. Project.exe --manifest-retries 5 - Specify that Finsemble should retry X attempts to fetch the manifest (in case of failure or timeout.)

Finsemble can also log all network errors. This can be useful when dealing with startup problems or misbehaving components:

Project.exe --log-all-network-errors

Those errors will show up in the log as "[error]: webRequest.onErrorOccurred" with a JSON string describing the error.

By default, all debugging and errors are logged to the "FEA log" which can be found in your $AppDir/<projectname>/logs/ directory (e.g. "/users/william/AppData/roaming/Electron/logs/FEA-2020-11-16.log). You can also optionally display logs in the console by setting the command line argument --enable-console. This can be useful when debugging while developing.

Note: Command line arguments can also be configured in your project's server-environment-startup.json file

	"development": {
		"args": ["--manifest-timeout", "30000", "--enable-console", "--log-network-errors"],
    ...
  }

Updating Finsemble

Updating Finsemble consists of two parts:

  1. Updating Finsemble Assets (including components)
  2. Updating The Container

Updating Finsemble Assets

Web deployment of your assets means that updating is easy: simply replace the assets on your server with your updated assets. Updating functionality is a simple matter of adding new assets to your Finsemble "site" or just deploying those assets separately.

When you need to update Finsemble, replace the files at the $moduleRoot URL in your manifest to point to the latest version of the Finsemble folder.


Updating Your Container

Your container can be configured to auto-update itself. Auto-update is an easy way to keep your users’ SmartDesktops up to date with the latest security patches. When configured for auto-update, Finsemble queries your server to check for new versions every time that it starts. When new versions are available on the server, they are automatically downloaded and installed.

Your release team has complete control over when to make new versions available. Simply upload a new release to your server (http) and it will become available as an auto-update for all your users. Users are prompted whenever new versions are installed and asked whether they wish to restart with the new version or continue on with the prior version.

Configuring your SmartDesktop to auto-update

  1. Set updateURL in configs/other/server-environment-startup.json to point to the URL where updates will be hosted (under the production config!). Note: In the seed project, installers are built to the pkg folder. Updates can be hosted in the seed project by setting the updateUrl to http://localhost:3375/pkg.
  2. Set version in configs/other/installer.json to an updated version number.
  3. Ensure that the pkg directory in your application root contains both the .nupkg and RELEASES files that were generated last time you created a package.
  4. Generate a new "package" by running npm run makeInstaller:prod in the root of your application's directory. The new versions of .nupkg and RELEASES files will be added to the pkg folder.
  5. Upload the pkg folder to your server, which you specified in step 1.

The nupkg file has several purposes. When generating an update, two nupkg files are generated: full and delta. The full nupkg file isn't used for installation, but it is needed for performing updates. The delta nupkg file contains the delta between the binary files. This is smaller and quicker to deploy than a full installation.

The RELEASES file in the pkg folder is what contains information about all previous updates. When updating: (1) the new package is downloaded and installed on the end user’s computer, (2) shortcuts are updated, and (3) older versions of the container are saved in a folder with the version number.


Video of building a self-updating installer

Our Director of Solutions Engineering, Andy Gardner, walks you through the steps needed to create a self-updating installer in this video.

Finsemble Building an Auto-Updating Installer Video
check   Finsemble is a collection of smaller web pages and native apps served from an HTTP server—just like a website. Deployment is nothing more than copying your dist and finsemble directories to your production server and using an installer to get Finsemble onto your users' machines.
 

Further reading

For a more thorough discussion of what Finsemble physically is and how it's structured, read the Architectural Overview.

If you choose to incorporate native components (.EXE, Java, Flash, etc.) into a Finsemble application, you must use the Windows executable assimilationMain.exe. Read about how to bundle applications with your SmartDesktop here.

For more on the build process, read the Build Process tutorial.