Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions packages/express/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# OpenEMR Cloud Express

OpenEMR Cloud Express on the AWS Marketplace provides OpenEMR 7.0.3, an embedded MySQL server, and rotated, automatic backups of all OpenEMR configuration and health information.
OpenEMR Cloud Express on the AWS Marketplace provides OpenEMR 7.0.4, an embedded MySQL server, and rotated, automatic backups of all OpenEMR configuration and health information.

## Compatibility Note

Versions of Cloud Express prior to version 7.0.4 used an older, compose v1-compatible syntax and structure. Please refer to [our prior documentation](https://github.com/openemr/openemr-devops/blob/954ab3b7a76809e4db0bf673edbcd560382dd252/packages/express/README.md) for how to interact with legacy installations.

## Installation

Expand Down Expand Up @@ -31,43 +35,41 @@ In a couple of minutes, once OpenEMR has finished the final setup procedures, it
### General

* Need access to the containers? Connect to user `ubuntu`, sudo to root, and...
* Apache: `docker compose exec openemr /bin/sh`
* MySQL: `docker compose exec mysql /bin/bash`
* Apache: `docker compose -p appliance exec openemr /bin/sh`
* MariaDB: `docker compose -p appliance exec mysql /bin/bash`
* Visit container volume: `docker volume ls`, `cd $(docker volume inspect <volume_name> | jq -r ".[0].Mountpoint")`

#### Set Local Timezone

1. See http://php.net/manual/en/timezones.php for the PHP timezone for your region.
2. `sudo bash`
3. `docker compose exec openemr sed -i 's^;date.timezone\ =^date.timezone = <your timezone>^' /etc/php7/php.ini`
4. `docker compose restart openemr`
3. `docker compose -p appliance exec openemr sed -i 's^;date.timezone\ =^date.timezone = <your timezone>^' /etc/php7/php.ini`
4. `docker compose -p appliance restart openemr`

### HIPAA Compliance

Although Amazon EC2 is a [HIPAA Eligible Service](https://aws.amazon.com/compliance/hipaa-eligible-services-reference/), the Marketplace-supplied instance of OpenEMR Cloud Express does not meet some parts of the HIPAA Security Rule. HIPAA Covered Entities may not store Protected Health Information on this product, and should confine their use of OpenEMR Cloud Express to demonstration or training use only.

### Backups

Duplicity is installed to the host machine to manage and rotate backups. It can be configured to send the backups it creates to off-instance storage, but currently does not attempt to do so. `/etc/cron.daily/duplicity-backups` holds the daily backup process that snapshots both the MySQL database, the OpenEMR configuration, and any patient documents that have been created, storing them in `/root/backups`.
Duplicity is installed to the host machine to manage and rotate backups. It can be configured to send the backups it creates to off-instance storage, but currently does not attempt to do so. `/etc/cron.daily/duplicity-backups` holds the daily backup process that snapshots both the MySQL database, the OpenEMR configuration, and any patient documents that have been created, storing them in `/opt/appliance/backups/out`.

Full backups are made every seven days, with incrementals for the other days. The Duplicity backups encompass the MySQL database backups.

#### Recovering from Backup

It is recommended, in the strongest possible terms, that you familiarize yourself with the recovery process as soon as possible. Launch a backup process, move the created backup files to a fresh instance, and try to recover them &mdash; this test, performed regularly, ensures smooth recovery in the face of catastrophe.

1. If necessary, place the compressed backup archive bundle in `/root/backups`.
2. As root, launch `/root/restore.sh`, and carefully read the warning it supplies you.
1. If necessary, place the compressed backup archive bundle in `/opt/appliance/backups/out`.
2. As root, launch `/root/openemr-devops/packages/appliance/restore.sh`, and carefully read the warning it supplies you.
3. Take the actions it suggests &mdash; make an image snapshot if possible &mdash; and then, once ready, edit the script as instructed and run it anew.
4. Duplicity will unpack the MySQL backups it's holding, the OpenEMR configuration directory, and any patient documents that have been saved.
5. XtraBackup will launch, applying the most recent full backup and all the daily incrementals.
6. The MySQL container will be restarted to pick up the newly constructed data directory, and at this point your backups should be completely restored.

See the `mysql-xtrabackup` container for more information about the `xbackup.sh` and `xrecovery.sh` scripts called by the Duplicity wrappers.
5. The MariaDB recovery tool will launch, applying the most recent full backup and all the daily incrementals.
6. The MariaDB container will be restarted to pick up the newly constructed data directory, and at this point your backups should be completely restored.

#### Backup Cross-Compatibility

OpenEMR Cloud Express backup files are cross-compatible with the [Appliance](../appliance) and [Ubuntu Installer](../lightsail) deployment packages; you should be able to migrate your practice between any of the three if you move the backups onto the target.
OpenEMR Cloud Express backup files are cross-compatible with the [Appliance](../appliance) deployment package; you should be able to migrate your practice between any of the three if you move the backups onto the target.

### Next Steps

Expand Down
28 changes: 12 additions & 16 deletions packages/express/ami/ami-config.sh
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
#!/bin/sh
#!/bin/bash

set -e
MYSQLROOTPWD="${1:-root}"

f () {
cd /root
# shellcheck disable=SC2312
curl -s https://raw.githubusercontent.com/openemr/openemr-devops/master/packages/appliance/launch.sh | bash -s --

# wait a while for services to build
until docker container ls | grep -q openemr/openemr
until [[ -n "${CONTAINER}" ]]
do
echo "waiting for container start..."
echo "waiting on composer start..."
sleep 5
CONTAINER="$(docker compose -p appliance ps --services openemr -qa)"
done

# shellcheck disable=SC2312
until docker top "$(docker ps | grep -openemr | cut -f 1 -d " ")" | grep httpd -q
until [[ "$(docker container inspect "${CONTAINER}" | jq '.[].State.Health.Status' -r)" == "healthy" ]]
do
echo "waiting for service start..."
sleep 20
echo "waiting on service start..."
sleep 5
done

docker compose -p appliance exec mysql mysql --password="${MYSQLROOTPWD}" -e "update openemr.users set active=0 where id=1;"
cp openemr-devops/packages/express/ami/ami-rekey.sh /etc/init.d/ami-rekey
# lockout default admin, set password as instance ID on next boot
docker compose -p appliance exec mysql sh -c 'mariadb --password=${MYSQL_ROOT_PASSWORD} -e "update openemr.users set active=0 where id=1;"'
cd openemr-devops/packages/express/ami
cp ami-rekey.sh /etc/init.d/ami-rekey
chmod 755 /etc/init.d/ami-rekey
update-rc.d ami-rekey defaults
rm -f /root/.ssh/authorized_keys /home/ubuntu/.ssh/authorized_keys
rm -f /home/ubuntu/.bash_history
sync
shutdown -h now
exit 0
}

f
20 changes: 11 additions & 9 deletions packages/express/ami/ami-rekey.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,24 +34,26 @@ fi

# wait a while for services to start
# shellcheck disable=SC2312
until docker container ls | grep openemr/openemr -q
until docker container ls | grep openemr -q
do
sleep 5
done
CONTAINER="$(docker compose -p appliance ps --services openemr -qa)"

# shellcheck disable=SC2312
until docker top "$(docker ps | grep -- -openemr | cut -f 1 -d " ")" | grep -q httpd
do
sleep 3
done
until [[ "$(docker container inspect "${CONTAINER}" | jq '.[].State.Health.Status' -r)" == "healthy" ]]
do
sleep 5
done

# reset password
# shellcheck disable=SC2312
docker compose exec openemr /root/unlock_admin.sh "$(curl http://169.254.169.254/latest/meta-data/instance-id)"
TOKEN=$(curl -sX PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
INSTANCEID=$(curl -H "X-aws-ec2-metadata-token: ${TOKEN}" http://169.254.169.254/latest/meta-data/instance-id)
docker compose -p appliance exec openemr /root/unlock_admin.sh "${INSTANCEID}"

# reset SSL
docker compose exec openemr /bin/sh -c 'rm -f /etc/ssl/private/* /etc/ssl/docker-selfsigned-configured'
docker restart lightsail_openemr_1
docker compose -p appliance exec openemr /bin/sh -c 'rm -f /etc/ssl/private/* /etc/ssl/docker-selfsigned-configured'
docker compose -p appliance restart openemr

# let's never speak of this again
touch /etc/appliance-unlocked
Expand Down