Smile CDR can be deployed to a server as an application by extracting the Smile CDR application archive file or as a Docker service by importing the Smile CDR Docker image. Once deployed, the initial installation of Smile CDR should be as simple as editing the configuration file and starting the software. We believe that software should be easy to configure, and should come with sane configuration out-of-the-box.
The following sections will provide a general overview of the basic installation process along with details for deploying Smile CDR as an application. Additional details about deploying Smile CDR as a Docker service are available at this page.
The following instructions will focus on deploying the software in a Linux/OSX environment.
Create a service account that the Smile CDR application will run under
sudo adduser --system --no-create-home --disabled-login --group smile
Extract the archive
# Navigate to the directory you wish to install to
cd /opt/
# Extract the Downloaded Archive
sudo tar xf /path/to/smilecdr-2025.02.PRE-13 (build f10bca0457)
# Reassign the install directory to the smile user
sudo chown -R smile:smile smilecdr
Navigate to the smilecdr
directory
$ cd smilecdr
You will now see the following directories in your target folder:
bin/
– contains the script used to start and stop Smile CDR's server processclasses/
– contains configuration fileslib/
– contains the application itself (you should not need to interact with this directory)Before starting Smile CDR for the first time, there are two files you will want to examine for settings.
In the bin/
directory you will find a file called setenv
. This file may be used to change the amount of RAM available to Smile CDR, as well as number of other low level settings. It is a good idea to glance over it and ensure that the default settings make sense for your installation.
In the classes/
directory, you will find a file called cdr-config-Master.properties
. This file contains all of the configuration for the modules which will be created the first time the system is started. A description of these files is found below.
With the files unpacked, you can try starting the server by executing the bin/smilecdr start
command as shown below.
This will start the server using the default configuration, which is not suitable for production use but is a great first test. If you are not installing Smile CDR for the first time, you can skip this section since it will be throwaway work.
$ bin/smilecdr start
2016-11-27 22:13:06.394 INFO Smile CDR 2017-05-R01 / master / build 1de9be72
2016-11-27 22:13:06.404 INFO Starting Smile CDR with configuration[Master]
2016-11-27 22:13:07.420 INFO Starting module clustermgr
2016-11-27 22:13:16.948 INFO Starting module local_security
2016-11-27 22:13:19.658 INFO Starting module admin_web
2016-11-27 22:13:22.984 INFO Starting module persistence
2016-11-27 22:13:37.863 INFO Starting module fhir_endpoint
2016-11-27 22:13:38.854 INFO Starting module admin_json
2016-11-27 22:13:40.591 INFO CDR has fully started in 34192ms
Assuming you see the phrase CDR has fully started
, you have now started the software.
With the software started, you can try a few things (replace localhost
in the URLs below with the host name of your server if you are installing to a remote server):
admin
(by default a single user with full privileges is created)password
When you are finished with this initial test, you can delete the tempoarary database files and logs by removing the following directories:
[install root]/h2_database
[install root]/log
Before proceeding with the setup of the system, let's look at the default configuration.
The following diagram shows the modules in a default installation of Smile CDR. Of course, the first thing you will probably want to do is reconfigure/add/change/remove these modules. For now, let's look at what comes out-of-the-box.
This diagram shows the following modules in a one-node cluster. Note that the addresses below (e.g. http://localhost:9100/
) are placeholders. If you have installed Smile CDR on a server other than your own workstation the hostname will not be localhost
, and the port numbers given are simply the initial default configuration (you may change any of them as you see fit by using Smile CDR's Web Admin Console).
admin
with a password of password
.Every module has a set of configuration properties that can be set. For example, the FHIR Listener module is configured with a port and default encoding, whereas the Local Security module is configured with settings for case-sensitivity.
When Smile CDR starts up, it uses a configuration file named cdr-config-$CONFIGNAME.properties
to configure itself, where $CONFIGNAME
is the value of the CONFIGNAME
environment variable set by the setenv
script. By default the setenv
script sets CONFIGNAME
to Master
and so by default the configuration file is called cdr-config-Master.properties
and is located in the classes
directory.
This file contains several key pieces of configuration. First, it contains a section which will look like this:
################################################################################
# Node Configuration
################################################################################
node.id=Master
node.config.locked=false
node.security.strict=false
node.id
– This property identifies the ID for the node to start. In the default file that is shipped with Smile CDR, this node is called Master
. You might choose to rename this if you are building a multi-node cluster but for a single node the default name is fine. In a multi-node cluster, each node must have a different ID so it is important to change this to something more appropriate. Note that node IDs must consist only of the following characters: US ASCII letters, numbers, underscore (_
) and dot (.
).node.config.locked
– If this property is set to true, then module configuration can not be changed once the server has started. All web admin console configuration will display as read-only, and any attempt to change module configuration using the json endpoint or web admin console will be denied. Note that loading configuration from a property file will also lock configuration in the web admin console node.propertysource
.node.security.strict
– If this property is set to true, then the server will not start if the admin user still has the default password, any anonymous user has superuser privileges or if any Smart Outbound Security module is using the example keystore. Furthermore FHIR Endpoint access will be denied to any user with both anonymous and superuser privileges.node.environment.type
– This property can be set to one of the following values: DEV
, QA
, PERF
, STAGING
, PROD
. If it is not set, it will default to DEV
. This property is currently only used to display the environment type in square brackets after the Node ID in the Web Admin Console. It may be used for other purposes in the future.Smile CDR reads from the cdr-config-Master.properties
file during start up. It will always take cluster manager settings from this file.
When it connects to the cluster manager database:
cdr-config-Master.properties
.Several other node configuration properties may also be placed in this file.
node.server_port_offset
– This property specifies an offset that will be applied to all opened server ports on this node. See Server Port Offset for more information.node.propertysource
– This property specifies where to look for module configuration. See Module Property Source for more information.node.archive_unknown_modules
– If this property is set to true and node.propertysource = PROPERTIES
, then any previously defined modules that are no longer defined in the properties file will be automatically archived. Note that restore points are not created in PROPERTIES
mode, even when automatic archiving enabled. Default is false.In the configuration file, you will also see a section that looks like the following:
################################################################################
# Cluster Manager Configuration
################################################################################
module.clustermgr.config.db.driver =H2_EMBEDDED
module.clustermgr.config.db.url =jdbc:h2:file:./database/h2_clustermgr
module.clustermgr.config.db.hibernate.showsql =false
module.clustermgr.config.db.username =SA
module.clustermgr.config.db.password =SA
This section contains the configuration properties for the cluster manager (which is given the module ID of clustermgr
). The configuration for this module is read at startup, and provides the configuration for the database where the cluster manager will store settings. The default installation uses an embedded H2 Database. This should be changed before you use Smile CDR for anything beyond quick prototyping.
The property file may also contain definitions for modules other than the Cluster Manager. The default file that is shipped with Smile CDR contains definitions for all of the other modules listed above.
By default, these definitions are used to seed the system with a set of modules the first time it starts up. However, after the first time the CDR has been started, the configuration for these modules will be read from the configuration database instead of from this property file. In other words, if you want to modify the database configuration for the cluster manager, you must always do this in the property file. If you want to modify the configuration for any other modules after the CDR has been started for the first time then you will need to modify it in the Web Admin Console.
If you wish to override this behavior you can use the node.propertysource
key in the property file to specify where to source module config. This property may have any of the following values:
DATABASE
– (this is the default if this property is not specified) Load the cluster manager configuration from the property file. Load all other modules from the database, unless no other modules are specified in the database (typically meaning that this is the first startup). Example:
node.propertysource=DATABASE
PROPERTIES
– Load module configuration from the property file even if modules have previously been loaded. In other words, give priority to the property file even if this is not the first time the application has started. Please note that in PROPERTIES mode, no config settings at all will be sourced from the ones stored in the database. Any config settings that are not specified in your cdr-config-Master.properties
file will automatically use their default values. This configuration mode will also have the same effect as setting the node.config.locked
property to true. Example:
node.propertysource=PROPERTIES
PROPERTIES_UNLOCKED
– This mode is intended for troubleshooting only. In this mode, changes to module configuration are permitted while the application is running. Temporary configuration changes can be applied by making changes in the Web Admin Console or via the JSON Admin API, but all changes are reset to the values found in the property file when the Smile CDR process restarts. In the case of a clustered deployment, changes are reset when any Smile CDR process in the cluster restarts.
clustermgr
.Nodes cannot be deleted once configured in a Cluster Manager database.
Nodes can only be changed by changing the configuration file containing the node configuration and restarting Smile CDR.
node.propertysource
has been configured for the node.Modules cannot be deleted, they can only be archived. Manually archiving a module can be done using the Web Admin console and only if changes here are enabled by the node.propertysource
configuration setting.
Archiving modules may also be done with the module-config
endpoint.
Archiving a module does not delete the module configuration. Instead, it marks the module in such a way that:
The module definition will continue to exist in the database after being archived and as such its ID cannot be re-used for other module definitions.
While in node.propertysource=PROPERTIES
mode, the only way to archive modules is to enable node.archive_unknown_modules
. While using this, removing all related configurations for a module from the cdr-config-NAME.properties
file will automatically archive the module. Conversely, if an archived module with the same module id is added back into the .properties
file, it will be reinstated. Note that restore points are not created with this method of archiving.
Since modules are not deleted, previously archived modules can be reinstated. This can be done using the Web Admin console and only if the changes are enabled by the node.propertysource
setting. Reinstating modules may also be done with the module-config
endpoint.
While in node.propertysource=PROPERTIES
mode, reinstating can be done by enabling node.archive_unknown_modules
and reintroducing configuration with the same archived module id back to the properties file. Note that restore points are not created with this method of reinstating.
Occasionally module types will be deprecated. However, unless otherwise stated as part of the release notes, a deprecated module type will continue to be supported and as such will not necessarily need to be changed or replaced. In most cases, the only noticeable difference will be that the module type will no longer appear as an option in the Web Admin console drop-down when creating a new module instance.
In the rare instance where support is dropped completely for a previously deprecated module type, the upgrade notes will provide specific guidance on how to migrate away from this module type.
Note: As per the Upgrade Instructions support for the long deprecated SMART_APPS_HOST
module type was dropped starting with the 2023.05.R01 release. If you have a module of this type configured in your deployment, contact Smile CDR support for more information on removing the definition for this module.
clustermgr
module can only be changed by changing the configuration file.node.propertysource
has been configured for the node.Within the property file, it is possible to put placeholders that will be evaluated. This can be used for example to pass database passwords or other runtime properties in from the underlying system environment.
There are two strategies for passing in data from the system environment:
System properties may be accessed from the configuration property file via the following syntax:
module.clustermgr.config.db.password=#{systemProperties['dbpassword']}
There are several standard methods for adding additional system properties:
Using the bin/setenv
File:
Within the bin/setenv
file, you may add system properties using the format -Dname=value
. For example, the following line adds a database password to the setenv file.
JVMARGS="$JVMARGS -Ddbpassword=somepassword"
Using External File Property Sources
Within the configuration properties file, you may add references to external properties files that will be loaded into the system properties.
This is done by adding an entry (or multiple entries) in the configuration file such as the following:
node.system_properties.source.0=classpath:externalprops.properties
This example uses a file called externalprops.properties
found in the classes/
directory as an additional source of system properties.
Note:
.0
, .1
, etc., to the name of the entry in the configuration file.classpath:
(for files in the classes/
directory) and file:
(for files elsewhere in the filesystem).The underlying system environment variables are also available using the following syntax. Using this syntax means that you do not need to explicitly specify anything in the setenv
file, and may be useful for some configurations (e.g. Docker Containers).
module.clustermgr.config.db.password=#{env['dbpassword']}
In some cases it can be useful to pull configuration values from external sources. For example, if a system such as CyberArk is being used to store database credentials, Smile CDR will need to request these credentials from CyberArk any time that it is starting relevant modules. This type of setup can be achieved using JavaScript functions that are executed when the property value is needed.
In order to define a script to fetch a property value, a file should be placed in [Smile CDR root]/classes
called config-source-scripts.js
. This file should have one or more functions with the following characteristics:
In order to invoke the function, any property in Smile CDR configuration may take a value with the form {{javascript:functionName()}}
.
For example, the following snippet shows a script that can be used to fetch a database credential:
function fetchPasswordFromRestService() {
var get = Http.get('https://myauth.example.com/AIMWebService/api/Accounts?AppID=SmileCDR&Query=Safe=DB;Object=DB');
get.execute();
if (!get.isSuccess()) {
throw get.getFailureMessage();
}
// In this example, the service returns a simple JSON document with an element
// called "DatabaseCredential". We will use the value of that element as
// the password to return
var responseJson = get.parseResponseAsJson();
var password = responseJson.DatabaseCredential;
return password;
}
A corresponding entry in the Smile CDR configuration properties file is shown below:
module.clustermgr.config.db.password = {{javascript:fetchPasswordFromRestService()}}
A default installation of Smile CDR has two database configuration settings. The first is for the cluster manager database, and contains configuration settings, audit trails, performance information, etc. The second is for the storage module, which is where FHIR resources are stored.
These are defined separately for several reasons:
While it is possible for these two databases to share a single physical database schema and instance, it is strongly recommended that in production these be hosted in separate databases.
Before starting the CDR for the first time, you may want to adjust the clustermgr
and persistence
modules to use a database platform other than H2. H2 a lightweight embedded database intended for testing purposes only.
The following example shows a postgres configuration:
################################################################################
# Cluster Manager Configuration
################################################################################
module.clustermgr.type =CLUSTER_MGR
module.clustermgr.config.db.driver =POSTGRES_9_4
module.clustermgr.config.db.url =jdbc:postgresql://localhost/cdr
module.clustermgr.config.db.username =cdr
module.clustermgr.config.db.password =cdrpassword
################################################################################
# Database Configuration
################################################################################
module.persistence.type =PERSISTENCE_R4
module.persistence.config.db.driver =POSTGRES_9_4
module.persistence.config.db.url =jdbc:postgresql://localhost/cdr
module.persistence.config.db.username =cdr
module.persistence.config.db.password =cdrpassword
The following example shows a MongoDB configuration. Note that when using MongoDB, a Cluster Manager database is still required, and must use a relational database. The example below shows H2 database, which is acceptable for non-production uses but should not be used for production use cases (or any use cases where data loss is not acceptable).
################################################################################
# Cluster Manager Configuration
################################################################################
module.clustermgr.type =CLUSTER_MGR
module.clustermgr.config.db.driver =H2_EMBEDDED
module.clustermgr.config.db.url =jdbc:h2:file:./database/h2_clustermgr
module.clustermgr.config.db.username =SA
module.clustermgr.config.db.password =SA
################################################################################
# Database Configuration
################################################################################
module.persistence.type =PERSISTENCE_MONGODB
module.persistence.config.db.url =mongodb://localhost:27017/fhir
module.persistence.config.db.username =cdr
module.persistence.config.db.password =cdrpassword
The following example shows an H2 configuration.
################################################################################
# Cluster Manager Configuration
################################################################################
module.clustermgr.type =CLUSTER_MGR
module.clustermgr.config.db.driver =H2_EMBEDDED
module.clustermgr.config.db.url =jdbc:h2:file:./database/h2_clustermgr
module.clustermgr.config.db.username =SA
module.clustermgr.config.db.password =SA
################################################################################
# Database Configuration
################################################################################
module.persistence.type =PERSISTENCE_R4
module.persistence.config.db.driver =H2_EMBEDDED
module.persistence.config.db.url =jdbc:h2:file:./database/h2_fhir_storage
module.persistence.config.db.username =SA
module.persistence.config.db.password =SA
Once you have prepared your configuration
To start the server, simply execute the command smilecdr start
as follows:
$ bin/smilecdr start
2016-11-27 22:13:06.394 INFO Smile CDR 2017-05-R01 / master / build 1de9be72
2016-11-27 22:13:06.404 INFO Starting Smile CDR with configuration[Master]
2016-11-27 22:13:07.420 INFO Starting module clustermgr
2016-11-27 22:13:16.948 INFO Starting module local_security
2016-11-27 22:13:19.658 INFO Starting module admin_web
2016-11-27 22:13:22.984 INFO Starting module persistence
2016-11-27 22:13:37.863 INFO Starting module fhir_endpoint
2016-11-27 22:13:38.854 INFO Starting module admin_json
2016-11-27 22:13:40.591 INFO CDR has fully started in 34192ms
Assuming you see the phrase CDR has fully started
, you have now started the software.
API Gateways are a popular choice as a part of the software stack in organizations that have many APIs exposed to their users. API gateways will often provide any or all of the following features:
An API gateway is not necessary when using Smile CDR, but it can certainly be useful and we recommend using one if one is already present for other APIs. As an example of an excellent architectural pattern, an API gateway can be placed in front of Smile CDR with security featured enabled. Smile CDR is then also security enabled (e.g. with Access Token passthrough enabled in the Gateway) meaning that there are two layers of security testing happening before data is accessed. This type of "defense in depth" strategy is very effective.