mirror of
https://gitlab.com/signalytic/client-external/streamline/streamline-emr.git
synced 2026-09-11 18:51:31 +00:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44a89fa893 | ||
|
|
a2ce9248f0 | ||
|
|
bf78a493bd | ||
|
|
c8c4ac7298 | ||
|
|
d60c85fa14 | ||
|
|
abf1c11d47 | ||
|
|
49f4681a74 | ||
|
|
5222a67855 | ||
|
|
a47c7b3d98 |
@@ -0,0 +1,3 @@
|
||||
[submodule "hosted-app-utils"]
|
||||
path = hosted-app-utils
|
||||
url = git@gitlab.com:signalytic/client-external/hosted-app-utils.git
|
||||
@@ -1,85 +1,13 @@
|
||||
# Streamline EMR
|
||||
|
||||
Packaging and installation tools for Streamline's "Streamline EMR" application.
|
||||
Packaging and installation tools for the Streamline EMR web app.
|
||||
|
||||
## Building
|
||||
1. ensure you have docker access to this project's container registry on GitLab
|
||||
2. run `package.sh` to generate a new application package
|
||||
3. package will be stored to `build-packages/`
|
||||
## Setup
|
||||
1. login to the gitlab docker registry: `docker login registry.gitlab.com`
|
||||
2. update submodules: `git submodule update --init --recursive`
|
||||
|
||||
Several defaults can be overridden with command line options or by setting appropriate environment variables. A help prompt can be accessed using `package.sh -h`. For example, `package.sh -t latest -p linux/arm64` will build only the `linux/arm64` platform and use the `latest` tag instead of the current repo version.
|
||||
|
||||
## Installing
|
||||
1. extract the generated archive file in a temporary folder on the target system
|
||||
2. run `<package-name>/install.sh`
|
||||
3. (optional) configure an `app.conf` file for integration with Signalytic services (e.g. dbsync)
|
||||
|
||||
## Running
|
||||
### Production (systemd)
|
||||
On a production system, `systemd` will manage the lifecycle of the application, e.g.
|
||||
```
|
||||
# enable and start the the application service
|
||||
systemctl daemon-reload
|
||||
systemctl enable streamline-emr
|
||||
systemctl start streamline-emr
|
||||
|
||||
# stop the application service
|
||||
systemctl stop streamline-emr
|
||||
|
||||
# restart the application service
|
||||
systemctl restart streamline-emr
|
||||
```
|
||||
|
||||
### Docker
|
||||
In a docker environment, the application must be started manually. This is done by running the `start` script, for example:
|
||||
```
|
||||
/var/signalytic/clientapps/streamline/streamline-emr/start
|
||||
```
|
||||
|
||||
Similarly, to stop the application:
|
||||
```
|
||||
/var/signalytic/clientapps/streamline/streamline-emr/stop
|
||||
```
|
||||
|
||||
### Manual
|
||||
During development or initial setup, it may be convenient to manually control the application.
|
||||
Note that manually managing the application requires that the systemd service be disabled:
|
||||
```
|
||||
# check status
|
||||
systemctl status streamline-emr
|
||||
|
||||
# stop service
|
||||
systemctl stop streamline-emr
|
||||
```
|
||||
|
||||
From here, the same `start` and `stop` scripts used during docker development can be used to manage the application.
|
||||
|
||||
## Monitoring
|
||||
The script `monitor` can be used at any time to query the current status and usage of the application. Two queries are made:
|
||||
- service status: current status of each docker service including health, up-time, etc.
|
||||
- resource usage: reporting on cpu, memory, disk, and network usage for each container
|
||||
|
||||
If the `bgsystemlog` program is found, data will be written to the Signalytic system log under the `streamline_emr_status` and `streamline_emr_usage` locations using json format.
|
||||
|
||||
## Configuration
|
||||
Certain configuration options can be adjusted by setting environment variables or by defining these variables in a `.env` file stored in the same directory as the `docker-compose.yml` file. A template file `template.env` provides an example with all values set to their defaults.
|
||||
|
||||
Important note when using "sibling containers": the sibling container method uses the host docker socket to provide containers with access to docker. As a result, port mappings and volume mount points all refer to the host system rather than the container from which the docker command originates.
|
||||
|
||||
### App Configuration
|
||||
An `app.conf` file is required for integration with other Signalytic services. A template is provided which demonstrates integration with the `dbsync` service. Note that all empty fields must be assigned values before use.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Scripts
|
||||
Several scripts are used to manage app instances, including:
|
||||
`start`: main entry point - calls either `setup` or `docker compose up -d`
|
||||
`setup`: run once - loads default data for the facility and applies initial database configuration then starts the application
|
||||
`stop`: stops the application
|
||||
`autoheal`: managed by `start` and `stop` scripts, checks for and restarts any services that become `unhealthy`
|
||||
`monitor`: checks the status of each instance service and sends data to `bgsystemlog` if installed
|
||||
|
||||
### Docker Images
|
||||
## Docker Images
|
||||
We want to use our own copy of the Docker images hosted on our GitLab Registry. The `docker` folder contains a set of Dockerfiles that should be used for generating images.
|
||||
|
||||
If not already configured, ensure appropriate docker credentials are available:
|
||||
@@ -102,3 +30,45 @@ Other options can be specified to override the image name or version. See the he
|
||||
- One images is currently required: `streamline-emr`
|
||||
- Images will be stored to GitLab with the name: `registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/<image>/<arch>:<tag>`
|
||||
- example: `registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64:latest`
|
||||
|
||||
## Building
|
||||
To build, simply run `./package` to generate a new application package.
|
||||
|
||||
The `package` script will assign a few variables by default, specifically:
|
||||
```
|
||||
CONFIG=${CONFIG:-${LOCATION}/config.json}
|
||||
SRC=${SRC:-${LOCATION}/src}
|
||||
BUILD_DIR=${BUILD_DIR:-${LOCATION}/build-packages}
|
||||
```
|
||||
|
||||
If necessary, each of these may be overridden by running with `VAR=VALUE ./package`.
|
||||
|
||||
The `hosted-app-utils` project provides additional customization via command line arguments. This can be used to modify the package name, skip packaging of images, build for only one platform and more. For a list of options, run `./package -h`.
|
||||
|
||||
Helpful options during development:
|
||||
- `--no-compression`: skip image compression to speed up packaging (packages will be much larger)
|
||||
- `--app`: skip packaging of images altogether
|
||||
|
||||
## Installing
|
||||
### Automated (Filetransfer)
|
||||
1. Copy package to the management node (e.g. `scp build-packages/<package> <user>@<mgmt-node-url>:`)
|
||||
2. SSH into the management node and become root (e.g. `ssh <user>@<mgmt-node-url>`, `sudo su`)
|
||||
3. (optional) Prepare a filetransfer channel (e.g. `mkdir -p /var/signalytic/filetransfer/<app-name>-<arch>`)
|
||||
4. Prepare a filetransfer update:
|
||||
```bash
|
||||
mkdir -p tmp/<update-number>
|
||||
mv <package> tmp/<update-number>/
|
||||
openssl sha256 -binary tmp/<update-number>/<package> | base64 - > tmp/<update-number>/_hash_
|
||||
```
|
||||
5. Copy the filetransfer update to the appropriate channel (e.g. `mv tmp/1 /var/signalytic/filetransfer/<app-name>-<arch>/`)
|
||||
6. (optional) Restart filetransfer: `systemctl restart filetransfer`
|
||||
7. If necessary, add the package to the target nodes' selective sync lists
|
||||
```
|
||||
bgkvs --cred admin:<pass> -B _conf -N _shared_ -d <node> -k filetransfer.selective_sync_packages.[0=<pkg1>
|
||||
bgkvs --cred admin:<pass> -B _conf -N _shared_ -d <node> -k filetransfer.selective_sync_packages.[1=<pkg2>
|
||||
bgkvs --cred admin:<pass> -B _conf -N _shared_ -d <node> -k filetransfer.selective_sync_packages.[2=<pkg3>
|
||||
```
|
||||
|
||||
### Manual
|
||||
1. extract the generated archive file in a temporary folder on the target system
|
||||
2. run `<package-name>/install.sh`
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "streamline-emr",
|
||||
"org": "streamline",
|
||||
"version": "2.1",
|
||||
"platforms": [
|
||||
"linux/arm64"
|
||||
],
|
||||
"images": {
|
||||
"linux/arm64": {
|
||||
"registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/arm64:v2.1": "streamline-emr:latest"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,78 @@
|
||||
FROM streamlinehealth/streamline:signalytic
|
||||
################################################################################
|
||||
# Use known working image to pull in working wkhtmltopdf libraries
|
||||
################################################################################
|
||||
|
||||
# update db init data
|
||||
COPY streamline_initial.sql /docker-entrypoint-initdb.d/
|
||||
FROM surnet/alpine-wkhtmltopdf:3.16.2-0.12.6-full as wkhtmltopdf
|
||||
FROM php:8.2-fpm-alpine3.17 AS app
|
||||
|
||||
# wkhtmltopdf install dependencies
|
||||
RUN apk add --no-cache \
|
||||
libstdc++ \
|
||||
libx11 \
|
||||
libxrender \
|
||||
libxext \
|
||||
libssl1.1 \
|
||||
ca-certificates \
|
||||
fontconfig \
|
||||
freetype \
|
||||
ttf-droid \
|
||||
ttf-freefont \
|
||||
ttf-liberation \
|
||||
# more fonts
|
||||
;
|
||||
# wkhtmltopdf copy bins from ext image
|
||||
COPY --from=wkhtmltopdf /bin/wkhtmltopdf /bin/wkhtmltoimage /bin/libwkhtmltox.so /usr/bin/
|
||||
|
||||
|
||||
################################################################################
|
||||
# Copied from previous Streamline Dockerfile
|
||||
################################################################################
|
||||
|
||||
# Install necessary packages and cleanup
|
||||
RUN set -ex; \
|
||||
apk update && \
|
||||
apk add --no-cache curl gnupg mysql mysql-client pwgen && \
|
||||
docker-php-ext-install pdo pdo_mysql && \
|
||||
rm -rf /var/cache/apk/*
|
||||
|
||||
# Install Composer
|
||||
RUN curl -sS https://getcomposer.org/installer | \
|
||||
php -- --install-dir=/usr/bin/ --filename=composer
|
||||
|
||||
# Set the working directory and copy the application code
|
||||
COPY streamline-src /var/www/html
|
||||
|
||||
COPY my.cnf /etc/mysql/my.cnf
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# Create the 'streamline' user and adjust permissions
|
||||
RUN addgroup -g 1000 streamline && adduser -G streamline -g streamline -s /bin/sh -D streamline && \
|
||||
composer install && \
|
||||
chmod -R 777 /var/www/html/storage/ && \
|
||||
chown -R streamline:streamline /var/www/html && \
|
||||
mkdir -p /docker-entrypoint-initdb.d/
|
||||
|
||||
# Initialize MySQL
|
||||
COPY streamline_initial.sql /docker-entrypoint-initdb.d/
|
||||
|
||||
RUN mkdir /scripts && \
|
||||
mkdir /scripts/pre-exec.d && \
|
||||
mkdir /scripts/pre-init.d && \
|
||||
chmod -R 755 /scripts
|
||||
|
||||
VOLUME ["/var/lib/mysql"]
|
||||
|
||||
# Set the startup script as executable
|
||||
RUN chmod +x /var/www/html/start_up.sh
|
||||
|
||||
# Define the entry point and expose port 80, 3306
|
||||
ENTRYPOINT ["/bin/sh", "/var/www/html/start_up.sh"]
|
||||
|
||||
EXPOSE 80 3306
|
||||
|
||||
|
||||
################################################################################
|
||||
# Update snappy config to fix issues with wkhtmltopdf
|
||||
################################################################################
|
||||
COPY snappy.php /var/www/html/config/snappy.php
|
||||
@@ -1,9 +1,33 @@
|
||||
# FROM streamlinehealth/streamline:signalytic
|
||||
################################################################################
|
||||
# Use known working image to pull in working wkhtmltopdf libraries
|
||||
# ref: https://stackoverflow.com/questions/56426050/how-to-install-wkhtmltopdf-on-docker-php-fpm-alpine-linux
|
||||
################################################################################
|
||||
|
||||
# COPY my.cnf /etc/mysql/my.cnf
|
||||
# COPY mysql-init.sh /var/www/html/.docker/mysql/mysql-init.sh
|
||||
FROM surnet/alpine-wkhtmltopdf:3.16.2-0.12.6-full as wkhtmltopdf
|
||||
FROM php:8.2-fpm-alpine3.17 AS app
|
||||
|
||||
FROM php:8.2-fpm-alpine
|
||||
# wkhtmltopdf install dependencies
|
||||
RUN apk add --no-cache \
|
||||
libstdc++ \
|
||||
libx11 \
|
||||
libxrender \
|
||||
libxext \
|
||||
libssl1.1 \
|
||||
ca-certificates \
|
||||
fontconfig \
|
||||
freetype \
|
||||
ttf-droid \
|
||||
ttf-freefont \
|
||||
ttf-liberation \
|
||||
# more fonts
|
||||
;
|
||||
# wkhtmltopdf copy bins from ext image
|
||||
COPY --from=wkhtmltopdf /bin/wkhtmltopdf /bin/wkhtmltoimage /bin/libwkhtmltox.so /usr/bin/
|
||||
|
||||
|
||||
################################################################################
|
||||
# Copied from previous Dockerfile (v1-rc4)
|
||||
################################################################################
|
||||
|
||||
# Install necessary packages and cleanup
|
||||
RUN set -ex; \
|
||||
@@ -47,3 +71,9 @@ RUN chmod +x /var/www/html/start_up.sh
|
||||
ENTRYPOINT ["/bin/sh", "/var/www/html/start_up.sh"]
|
||||
|
||||
EXPOSE 80 3306
|
||||
|
||||
|
||||
################################################################################
|
||||
# Update snappy config to fix issues with wkhtmltopdf
|
||||
################################################################################
|
||||
COPY snappy.php /var/www/html/config/snappy.php
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
$pdfPath = '/usr/bin/wkhtmltopdf';
|
||||
$imagePath = '/usr/bin/wkhtmltoimage';
|
||||
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Snappy PDF / Image Configuration
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option contains settings for PDF generation.
|
||||
|
|
||||
| Enabled:
|
||||
|
|
||||
| Whether to load PDF / Image generation.
|
||||
|
|
||||
| Binary:
|
||||
|
|
||||
| The file path of the wkhtmltopdf / wkhtmltoimage executable.
|
||||
|
|
||||
| Timout:
|
||||
|
|
||||
| The amount of time to wait (in seconds) before PDF / Image generation is stopped.
|
||||
| Setting this to false disables the timeout (unlimited processing time).
|
||||
|
|
||||
| Options:
|
||||
|
|
||||
| The wkhtmltopdf command options. These are passed directly to wkhtmltopdf.
|
||||
| See https://wkhtmltopdf.org/usage/wkhtmltopdf.txt for all options.
|
||||
|
|
||||
| Env:
|
||||
|
|
||||
| The environment variables to set while running the wkhtmltopdf process.
|
||||
|
|
||||
*/
|
||||
|
||||
'pdf' => [
|
||||
'enabled' => true,
|
||||
'binary' => $pdfPath,
|
||||
'timeout' => false,
|
||||
'options' => [
|
||||
'enable-local-file-access' => true
|
||||
],
|
||||
'env' => [],
|
||||
],
|
||||
'image' => [
|
||||
'enabled' => true,
|
||||
'binary' => $imagePath,
|
||||
'timeout' => false,
|
||||
'options' => [
|
||||
'enable-local-file-access' => true
|
||||
],
|
||||
'env' => [],
|
||||
],
|
||||
];
|
||||
Submodule
+1
Submodule hosted-app-utils added at 3785af3094
@@ -1,2 +0,0 @@
|
||||
linux/arm64,streamline-emr,registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/arm64
|
||||
linux/amd64,streamline-emr,registry.gitlab.com/signalytic/client-external/streamline/streamline-emr/streamline-emr/amd64
|
||||
|
-55
@@ -1,55 +0,0 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) Wendepunkt Medical Innovations, Inc - All Rights Reserved.
|
||||
# Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
# Proprietary and confidential
|
||||
#
|
||||
# For information: dev@signalytic.ca
|
||||
#
|
||||
|
||||
#
|
||||
# Install the Streamline "Streamline EMR" application and services
|
||||
#
|
||||
# The caller of this script must check the exit value and possibly do a
|
||||
# roll-back if it is non-zero. If the exit value is non-zero services have not
|
||||
# been restarted.
|
||||
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
if [ "$EUID" -ne 0 ]
|
||||
then echo "Please run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
# stop any running systemd service if not running in a docker environment
|
||||
if [ -f /.dockerenv ]; then
|
||||
echo "Docker environment detected - skipping systemd installation"
|
||||
else
|
||||
echo "stopping system service"
|
||||
systemctl stop streamline-emr
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
# copy root files
|
||||
echo "importing root files"
|
||||
cp -rfv $LOCATION/root/* /
|
||||
|
||||
# import docker images
|
||||
for f in $(find $LOCATION/images -name "*.img" 2>/dev/null);do
|
||||
echo "importing docker image: $f"
|
||||
docker load -i $f
|
||||
done
|
||||
for f in $(find $LOCATION/images -name "*.img.xz" 2>/dev/null);do
|
||||
echo "importing docker image: $f"
|
||||
xz -d -c $f | docker load
|
||||
done
|
||||
|
||||
# install systemd service unless running in a docker environment
|
||||
if [ ! -f /.dockerenv ]; then
|
||||
echo "installing system service"
|
||||
systemctl daemon-reload
|
||||
systemctl enable streamline-emr
|
||||
systemctl start streamline-emr
|
||||
fi
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
CONFIG=${CONFIG:-${LOCATION}/config.json}
|
||||
SRC=${SRC:-${LOCATION}/src}
|
||||
BUILD_DIR=${BUILD_DIR:-${LOCATION}/build-packages}
|
||||
|
||||
${LOCATION}/hosted-app-utils/package ${CONFIG} ${SRC} output=${BUILD_DIR} $@
|
||||
-206
@@ -1,206 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
#
|
||||
# Copyright (C) Wendepunkt Medical Innovations, Inc - All Rights Reserved.
|
||||
# Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
# Proprietary and confidential
|
||||
#
|
||||
# For information: dev@signalytic.ca
|
||||
#
|
||||
|
||||
# basic path info
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
PROJECT_ROOT="$(realpath $LOCATION)"
|
||||
|
||||
# determine version name from git
|
||||
# use ci tag name if available (e.g. "v1.2")
|
||||
if [ $CI_COMMIT_TAG ]; then
|
||||
VERSION_NAME="$CI_COMMIT_TAG"
|
||||
# otherwise if ci, use BRANCH-COMMIT
|
||||
elif [ $CI_COMMIT_BRANCH ]; then
|
||||
VERSION_NAME="$CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA"
|
||||
# if not ci, try to use git
|
||||
elif command -v git &> /dev/null; then
|
||||
VERSION_NAME=$(git describe --always --tags --abbrev=7 --dirty)
|
||||
# fallback
|
||||
else
|
||||
VERSION_NAME="latest"
|
||||
fi
|
||||
|
||||
# configurable options (override with env vars as needed)
|
||||
PACKAGE_NAME=${PACKAGE_NAME-"streamline-emr"}
|
||||
OUTPUT_DIR=${OUTPUT_DIR-"$PROJECT_ROOT/build-packages"}
|
||||
PACKAGE_IMAGES=${PACKAGE_IMAGES:-1}
|
||||
COMPRESS_IMAGES=${COMPRESS_IMAGES:-1}
|
||||
IMAGE_TAG=${IMAGE_TAG:-${VERSION_NAME}}
|
||||
IMAGES_LIST=${IMAGES_LIST:-${PROJECT_ROOT}/images.csv}
|
||||
|
||||
|
||||
function print_usage {
|
||||
echo "Streamline EMR packaging utility"
|
||||
echo
|
||||
echo "Usage: package.sh [ OPTIONS ]"
|
||||
echo
|
||||
echo "Options:"
|
||||
echo " -h Print this help prompt and exit"
|
||||
echo " -p PLATFORM Specify a docker platform to target, may be passed multiple"
|
||||
echo " times. If none specified, all platforms built. Supported"
|
||||
echo " platforms: 'linux/amd64', 'linux/arm64'"
|
||||
echo " -t IMAGE_TAG Specify an image tag. It not specified, the tag will be"
|
||||
echo " inferred from the current git version ('${IMAGE_TAG}')"
|
||||
echo " -n PACKAGE_NAME Specify the package base name. Default: ${PACKAGE_NAME}"
|
||||
echo " -o OUTPUT_DIR Specify a directory to save packages. Default: ${OUTPUT_DIR}"
|
||||
echo " -l IMAGES_LIST Specify a file containing a list of images. Default: ${IMAGES_LIST}"
|
||||
echo " -I Do not package images"
|
||||
echo " -C Do not compress images"
|
||||
echo
|
||||
}
|
||||
|
||||
# collect user args
|
||||
PLATFORMS=()
|
||||
while getopts ":p:t:n:o:l:ICh" options; do
|
||||
case "${options}" in
|
||||
p)
|
||||
PLATFORMS+=(${OPTARG})
|
||||
;;
|
||||
t)
|
||||
IMAGE_TAG=${OPTARG}
|
||||
;;
|
||||
n)
|
||||
PACKAGE_NAME=${OPTARG}
|
||||
;;
|
||||
o)
|
||||
OUTPUT_DIR=${OPTARG}
|
||||
;;
|
||||
l)
|
||||
IMAGES_LIST=${OPTARG}
|
||||
;;
|
||||
I)
|
||||
PACKAGE_IMAGES=0
|
||||
;;
|
||||
C)
|
||||
COMPRESS_IMAGES=0
|
||||
;;
|
||||
h)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND -1))
|
||||
|
||||
# set defaults
|
||||
if [ ${#PLATFORMS} -eq 0 ]; then
|
||||
PLATFORMS=("linux/amd64" "linux/arm64")
|
||||
fi
|
||||
|
||||
echo "packaging $PACKAGE_NAME"
|
||||
echo " output dir: $OUTPUT_DIR"
|
||||
echo " package images: $PACKAGE_IMAGES"
|
||||
echo " compress images: $COMPRESS_IMAGES"
|
||||
echo " image tag: $IMAGE_TAG"
|
||||
echo " image list: $IMAGES_LIST"
|
||||
echo " platforms: ${PLATFORMS[@]}"
|
||||
|
||||
# work from the project root
|
||||
pushd $PROJECT_ROOT > /dev/null
|
||||
|
||||
# Exit on error:
|
||||
set -e
|
||||
trap 'echo "Error: Last command failed with exit code $?."' ERR
|
||||
|
||||
# build for each relevant platform
|
||||
for platform in ${PLATFORMS[@]}; do
|
||||
echo "preparing package for platform $platform"
|
||||
if [ "$platform" == "linux/amd64" ];then
|
||||
pkg_arch="x86_64"
|
||||
elif [ "$platform" == "linux/arm64" ];then
|
||||
pkg_arch="aarch64"
|
||||
else
|
||||
echo "unexpected platform '$platform'"
|
||||
exit 1
|
||||
fi
|
||||
OUTPUT_NAME="$PACKAGE_NAME-$VERSION_NAME-${pkg_arch}"
|
||||
OUTPUT_FILE="$OUTPUT_NAME.tar.bz2"
|
||||
OUTPUT_PATH="$OUTPUT_DIR/$OUTPUT_FILE"
|
||||
|
||||
# create a new temp directory to stage files
|
||||
for i in {1..9999};do
|
||||
STAGING_DIR="tmp-staging-$i"
|
||||
if [ ! -d $STAGING_DIR ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ -d $STAGING_DIR ]; then
|
||||
echo "Failed to generate temp staging dir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# add files
|
||||
PACKAGE_ROOT=${STAGING_DIR}/${OUTPUT_NAME}
|
||||
IMAGES_DIR=${PACKAGE_ROOT}/images
|
||||
mkdir -p ${IMAGES_DIR}
|
||||
cp ${PROJECT_ROOT}/install.sh ${PACKAGE_ROOT}/
|
||||
cp -a ${PROJECT_ROOT}/root ${PACKAGE_ROOT}/
|
||||
echo "${VERSION_NAME}" > ${PACKAGE_ROOT}/root/var/signalytic/clientapps/streamline/streamline-emr/version
|
||||
|
||||
if [ "${PACKAGE_IMAGES}" = 1 ]; then
|
||||
# add images
|
||||
# read image list from file (e.g. 'images-aarch64')
|
||||
# images are listed as SAVED_TAG=SOURCE_IMAGE
|
||||
for image in $(cat ${IMAGES_LIST});do
|
||||
IFS=, read -r img_platform dest source <<< "${image}"
|
||||
# package only if the platforms match
|
||||
if [ "${img_platform}" = "${platform}" ]; then
|
||||
echo "pulling image '${source}' (${platform})"
|
||||
docker pull --platform ${platform} ${source}:${IMAGE_TAG}
|
||||
# re-tag the image with a more generic name
|
||||
echo "tagging image as '${dest}:latest'"
|
||||
docker tag ${source}:${IMAGE_TAG} ${dest}:latest
|
||||
# save the image to file
|
||||
if [ "${COMPRESS_IMAGES}" = 1 ]; then
|
||||
path="${IMAGES_DIR}/${dest}.img.xz"
|
||||
echo "saving to '${path}'"
|
||||
# if installed, use pv to show progress
|
||||
if command -v pv &> /dev/null; then
|
||||
docker save ${dest}:latest | xz -9 - -c | pv -t -r -b -N "saving compressed image..." > ${path}
|
||||
else
|
||||
docker save ${dest}:latest | xz -9 - -c > ${path}
|
||||
fi
|
||||
else
|
||||
path="${IMAGES_DIR}/${dest}.img"
|
||||
echo "saving to '${path}'"
|
||||
# if installed, use pv to show progress
|
||||
if command -v pv &> /dev/null; then
|
||||
docker save ${dest}:latest | pv -t -r -b -N "saving raw image..." > ${path}
|
||||
else
|
||||
docker save -o ${path} ${dest}:latest
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "skipping image packaging as requested"
|
||||
fi
|
||||
|
||||
# setup output directory and cleanup old files if necessary
|
||||
mkdir -p $OUTPUT_DIR
|
||||
rm -rf $OUTPUT_PATH
|
||||
|
||||
pushd $STAGING_DIR > /dev/null
|
||||
tar -cjf $OUTPUT_PATH ${OUTPUT_NAME}
|
||||
popd > /dev/null
|
||||
|
||||
# cleanup staging files
|
||||
rm -r $STAGING_DIR
|
||||
|
||||
echo "output: $OUTPUT_PATH"
|
||||
done
|
||||
|
||||
popd > /dev/null
|
||||
|
||||
exit 0
|
||||
@@ -1,16 +0,0 @@
|
||||
[Unit]
|
||||
Description=Run Streamline EMR
|
||||
Requires=docker.service
|
||||
After=docker.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
User=root
|
||||
WorkingDirectory=/var/signalytic/clientapps/streamline/streamline-emr
|
||||
ExecStart=/var/signalytic/clientapps/streamline/streamline-emr/start
|
||||
ExecStop=/var/signalytic/clientapps/streamline/streamline-emr/stop
|
||||
TimeoutStartSec=0
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
INTERVAL=${INTERVAL:-60}
|
||||
|
||||
# track pid with a file `autoheal.pid`. If a previous instance is still running, exit early.
|
||||
function cleanup() {
|
||||
rm -f ${LOCATION}/autoheal.pid
|
||||
}
|
||||
trap cleanup EXIT
|
||||
kill -0 $(cat ${LOCATION}/autoheal.pid 2> /dev/null) 2> /dev/null && echo "autoheal script already running" && exit 1
|
||||
echo $$ > ${LOCATION}/autoheal.pid
|
||||
|
||||
# exit on SIGINT
|
||||
trap exit INT
|
||||
|
||||
# run at fixed interval, checking for and restarting any service marked as 'unhealthy'
|
||||
pushd $LOCATION > /dev/null
|
||||
while [ 1 ]; do
|
||||
# get current state (running or not) and status (healthy, unhealthy, etc)
|
||||
app_state=$(docker compose ps --format '{{.State}}' streamline-emr)
|
||||
app_status=$(docker compose ps --format '{{.Status}}' streamline-emr)
|
||||
|
||||
# check if app is running and healhty
|
||||
if [ "${app_state}" = "running" ]; then
|
||||
if [[ "${app_status}" = *\(unhealthy\) ]]; then
|
||||
echo "Unhealthy service detected. Restarting 'streamline-emr'"
|
||||
docker compose restart streamline-emr
|
||||
fi
|
||||
# app should be running - restart
|
||||
else
|
||||
echo "Container not running. Starting 'streamline-emr'"
|
||||
docker compose up -d streamline-emr
|
||||
fi
|
||||
|
||||
# wait a little while before checking again
|
||||
sleep $INTERVAL
|
||||
done
|
||||
popd > /dev/null
|
||||
@@ -1,43 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
SYSTEMLOG=${SYSTEMLOG:-1}
|
||||
if ! command -v bgsystemlog &> /dev/null; then
|
||||
SYSTEMLOG=0
|
||||
fi
|
||||
|
||||
# get container info
|
||||
APP_CONTAINER=${APP_CONTAINER:-streamline-emr}
|
||||
if grep -q "^APP_CONTAINER=" ${LOCATION}/.env > /dev/null 2>&1; then
|
||||
APP_CONTAINER=$(sed -n 's/APP_CONTAINER=//p' ${LOCATION}/.env)
|
||||
fi
|
||||
|
||||
pushd $LOCATION > /dev/null
|
||||
# get process status for each service
|
||||
echo "checking streamline-emr service status"
|
||||
for service in $(docker compose ps --services); do
|
||||
status=$(docker compose ps --format '{"name":"{{.Names}}","created":"{{.CreatedAt}}","elapsed":"{{.RunningFor}}","state":"{{.State}}","status":"{{.Status}}"}' ${service})
|
||||
if [ "${status}" ]; then
|
||||
echo $status
|
||||
if [ "$SYSTEMLOG" -eq 1 ]; then
|
||||
bgsystemlog -j streamline_emr_status -m ${status}
|
||||
fi
|
||||
else
|
||||
echo "no status results found for service ${service}"
|
||||
fi
|
||||
done
|
||||
# get resource usage
|
||||
echo "checking streamline-emr resource usage"
|
||||
status=$(docker stats --no-stream --format '{"name":"{{.Name}}","cpu_p":"{{.CPUPerc}}","mem_p":"{{.MemPerc}}","mem_u":"{{.MemUsage}}","net_io":"{{.NetIO}}","block_io":"{{.BlockIO}}"}' ${APP_CONTAINER})
|
||||
if [ "${status}" ]; then
|
||||
echo $status
|
||||
if [ "$SYSTEMLOG" -eq 1 ]; then
|
||||
bgsystemlog -j streamline_emr_usage -m ${status}
|
||||
fi
|
||||
else
|
||||
echo "no usage results found for container ${APP_CONTAINER}"
|
||||
fi
|
||||
popd > /dev/null
|
||||
|
||||
echo "done."
|
||||
@@ -1,25 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
VERSION_FILE=${LOCATION}/version
|
||||
version=$(head -n 1 ${VERSION_FILE} 2>/dev/null)
|
||||
if [ $? -ne 0 ];then
|
||||
version="unknown version"
|
||||
fi
|
||||
echo "Starting Streamline EMR: $version"
|
||||
|
||||
# work from the install root
|
||||
pushd $LOCATION > /dev/null
|
||||
# make sure we're always working from a clean state
|
||||
./stop
|
||||
|
||||
# start the application
|
||||
echo "starting services"
|
||||
docker compose up -d
|
||||
|
||||
# start autoheal to restart unhealthy containers
|
||||
./autoheal &
|
||||
popd > /dev/null
|
||||
|
||||
echo "done."
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
LOCATION="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
|
||||
echo "stopping streamline emr"
|
||||
pushd $LOCATION > /dev/null
|
||||
if [ -f autoheal.pid ];then
|
||||
kill $(cat autoheal.pid)
|
||||
fi
|
||||
docker compose down
|
||||
popd > /dev/null
|
||||
echo "done."
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "Streamline EMR",
|
||||
"dbsync": {
|
||||
"database": {
|
||||
"type": "mysql",
|
||||
"version": "8.0.23",
|
||||
"name": "main",
|
||||
"username": "",
|
||||
"password": "",
|
||||
"db_path": "/var/lib/mysql",
|
||||
"logs_path": "/var/lib/mysql/logs",
|
||||
"log_pattern": "binlog.[0-9]*"
|
||||
},
|
||||
"blockgraph": {
|
||||
"district": "",
|
||||
"name": "",
|
||||
"username": "",
|
||||
"password": ""
|
||||
},
|
||||
"instances": {
|
||||
"streamline-emr": {
|
||||
"source": "streamline-emr",
|
||||
"node": "",
|
||||
"location": "_default"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
COMPOSE_PROJECT_NAME=streamline-emr
|
||||
DATA_DIR=/var/signalytic/clientapps/streamline/streamline-emr/data
|
||||
APP_IMAGE=streamline-emr:latest
|
||||
APP_CONTAINER=streamline-emr
|
||||
APP_PORT=3000
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "Streamline EMR",
|
||||
"access": {
|
||||
"username": "streamline_sysuser",
|
||||
"password": "82CUF8UftjEx"
|
||||
},
|
||||
"appconfig": {
|
||||
"blockgraph": {
|
||||
"district": "StreamlineEmr",
|
||||
"name": "streamline_emr_config"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "Streamline EMR",
|
||||
"access": {
|
||||
"username": "streamline_sysuser",
|
||||
"password": "82CUF8UftjEx"
|
||||
},
|
||||
"appconfig": {
|
||||
"blockgraph": {
|
||||
"district": "StreamlineEmr",
|
||||
"name": "streamline_emr_config"
|
||||
}
|
||||
},
|
||||
"dbsync": {
|
||||
"blockgraph": {
|
||||
"district": "StreamlineEmr",
|
||||
"name": "streamline_emr_data"
|
||||
},
|
||||
"database": {
|
||||
"type": "mysql",
|
||||
"version": "8.0",
|
||||
"name": "streamline",
|
||||
"username": "root",
|
||||
"password": "streamline",
|
||||
"db_path": "/var/lib/mysql",
|
||||
"logs_path": "/var/lib/mysql/logs",
|
||||
"log_pattern": "bin.[0-9]*",
|
||||
"source": "mysql-app-db"
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-3
@@ -1,13 +1,12 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
streamline-emr:
|
||||
image: ${APP_IMAGE:-streamline-emr:latest}
|
||||
container_name: ${APP_CONTAINER:-streamline-emr}
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- "${DATA_DIR:-/var/signalytic/clientapps/streamline/streamline-emr/data}:/var/lib/mysql"
|
||||
- "${DATA_DIR:-./data}:/var/lib/mysql"
|
||||
ports:
|
||||
- "${APP_PORT:-3000}:80"
|
||||
dns: 0.0.0.0
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:80"]
|
||||
timeout: 30s
|
||||
Reference in New Issue
Block a user