Skip to main content

How to create an Instant OpenHIE package

info

The Instant OpenHIE architecture, codebase, and documentation are under active development and are subject to change. While we encourage adoption and extension of the Instant OpenHIE framework, we do not consider this ready for production use at this stage.

Packages are a way of allowing a group of applications to be setup and configured to enable a particular set of functionality. Each package MUST include the following:

  1. docker-compose.*.yml files to setup and configure the necessary applications in Docker Compose
  2. Deployment and service resource files (and any other necessary resource files) to setup and configure the necessary applications in Kubernetes
  3. A instant.json file that holds metadata about the package
  4. Bash scripts that accept a particular set of commands (init, up, down, and destroy) and execute these Docker Compose and Kubernetes infrastructure files and any other necessary processing and configuration to perform the required command.

Docker Compose files#

All Docker Compose files should by convention be contained in a ./docker directory in the root of the package directory. It is often useful to split up Docker Compose files into separate files with different purposes. For example:

  • docker-compose.yml for the main application setup and orchestration
  • docker-compose.config.yml for starting short lived containers that configure the applications or add any test data that is necessary
  • docker-compose.dev.yml for over-ridding options in the main compose file to allow for easier development. For example, to expose all ports to the host even those that should be protected

Kubernetes resources#

All Kubernetes files should by convention be contained in a ./kubernetes directory in the root of the package directory. It is recommended to use the declarative form of Kubernetes resources. The key resources to define are deployments and services for each component.

Config containers can be executed as job resources with an init container. These temporary containers only configure the main application once the service has started up.

instant.json#

This file should be in the root directory of the package and provide metadata about the package itself along with any dependencies:

{
"id": "abc",
"name": "XYZ",
"description": "...",
"type": "use-case", // options: infrastructure | use-case
"version": "v0.0.1",
"dependencies": ["core", "healthworkforce"] // list of package ids
"environmentVariables": { // List of environment variables used in the package
"NODE_ENV": "instant",
"url": "http://test.org"
}
}

Bash scripts#

Two bash scripts are required in each package:

  • ./docker/compose.sh - to configure, start and stop the applications using Docker Compose
  • ./kubernetes/main/k8s.sh - to configure, start and stop the applications using Kubernetes

Each of these scripts should accept one of the following commands (i.e. ./compose.sh <command>):

  • init - start all the applications in this package and performs any necessary pre-processing of the infrastructure files
  • up - start all the applications in this package
  • down - stop all the applications in this package
  • destroy - delete all the application containers in this package and all their stored data

For example, a compose.sh script could look like this:

composeFilePath=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
if [ "$1" == "init" ]; then
# execute other setup scripts or commands here
# ...
docker-compose -f "$composeFilePath"/docker-compose.yml -f "$composeFilePath"/importer/docker-compose.config.yml up -d
elif [ "$1" == "up" ]; then
docker-compose -f "$composeFilePath"/docker-compose.yml -f "$composeFilePath"/importer/docker-compose.config.yml up -d
elif [ "$1" == "down" ]; then
docker-compose -f "$composeFilePath"/docker-compose.yml -f "$composeFilePath"/importer/docker-compose.config.yml stop
elif [ "$1" == "destroy" ]; then
docker-compose -f "$composeFilePath"/docker-compose.yml -f "$composeFilePath"/importer/docker-compose.config.yml down -v
else
echo "Valid options are: init, up, down, or destroy"
fi

A k8s.sh script could look like this:

#!/bin/bash
k8sMainRootFilePath=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
if [ "$1" == "init" ]; then
# execute other setup scripts or commands here
# ...
# Create the namespace
kubectl apply -f $k8sMainRootFilePath/healthworkforce-namespace.yaml
kubectl apply -k $k8sMainRootFilePath
elif [ "$1" == "up" ]; then
# Create the namespace
kubectl apply -f $k8sMainRootFilePath/healthworkforce-namespace.yaml
kubectl apply -k $k8sMainRootFilePath
elif [ "$1" == "down" ]; then
kubectl delete deployment mapper-deployment
elif [ "$1" == "destroy" ]; then
kubectl delete namespaces hwf-package
else
echo "Valid options are: up, down, or destroy"
fi

The Instant OpenHIE executable will look for these scripts and ensure that they are executed to start-up a package. Packages will be started in their dependency order beginning with the core package.

How to execute your new package#

The following mechanism for adding a package is useful for package development.

The preferred method for adding custom packages to your Instant instance will be to add the package repo GitHub url to the config - however this feature is still in development.

Yarn (Dev)#

Copy your package into the root directory of this Instant OpenHIE project.

Run as normal:

yarn docker:instant init <your_package_name>

Docker or Kubernetes without the Instant OpenHIE repo#

The Instant OpenHIE project is available as a Docker image therefore we do not need the whole GitHub repository to run the containers.

For a minimum Instant OpenHIE set up, download this deploy script from GitHub. Once downloaded make sure it's executable: sudo chmod +x deploy.sh

Then, run the following command to add your custom package and initialise the system in docker.

./deploy init -t docker core <your_package_ids> -c="../path/to/your/package"

To remove the instant project, run the following:

./deploy destroy -t docker core covid19surveillance

The custom package location is not needed for up, down, or destroy commands on an existing system.

To initialise kubernetes, run the following:

./deploy init -t k8s core <your_package_ids> -c="../path/to/your/package"

Multiple custom packages can be chained together as follows:

./deploy init test1 test2 test3 -c="../test1" -c="../test2" -c="../test3"

Docker#

To add a custom package to your instant instance, use the following flag

  • -c
  • --custom-package

We hope to support package url references soon

To add multiple custom packages, list each package location with the flag.

-c="/path/to/package_1" -c="/path/to/package_2"

Below is an example of an entire init command. If you had downloaded the who-covid19-surveillance-package repository onto your machine you could reference it as follows:

yarn docker:instant init core covid19surveillance -c="../who-covid19-surveillance-package"

Once a custom package has been added to the project, it does not need to be referenced in future commands as the data has been persisted in the shared volume. The examples below continue on from the previous covid19 package initialisation.

  • yarn docker:instant down core covid19surveillance
  • yarn docker:instant up core covid19surveillance
  • yarn docker:instant test core covid19surveillance
  • yarn docker:instant destroy core covid19surveillance

Kubernetes#

To add a custom package to your instant instance, use the following flag

  • -c
  • --custom-package

We hope to support package url references soon

To add multiple custom packages, list each package location with the flag.

-c="/path/to/package_1" -c="/path/to/package_2"

Docker is the default deploy environment. To use Kubernetes, add the target flag -t. For example:

  • -t k8s
  • -t kubernetes

Below is an example of an entire init command. If you had downloaded the who-covid19-surveillance-package repository onto your machine you could reference it as follows:

yarn docker:instant init -t k8s core covid19surveillance -c="../who-covid19-surveillance-package"

Once a custom package has been added to the project, it does not need to be references in future commands as the data has been persisted in the shared volume. The examples below continue on from the previous covid19 package initialisation.

  • yarn docker:instant down -t k8s core covid19surveillance
  • yarn docker:instant up -t k8s core covid19surveillance
  • yarn docker:instant test -t k8s core covid19surveillance
  • yarn docker:instant destroy -t k8s core covid19surveillance