diff --git a/.env b/.env index 9144581..cff4e10 100644 --- a/.env +++ b/.env @@ -25,7 +25,7 @@ OPENMRS_DB_NAME=openmrs # # OpenMRS frontend # -SPA_CONFIG_URLS=/openmrs/spa/ozone/ozone-frontend-config.json +SPA_CONFIG_URLS=/openmrs/spa/configs/ozone-frontend-config.json SPA_DEFAULT_LOCALE=en # OpenMRS frontend and backend Docker image tag @@ -122,6 +122,8 @@ OPENMRS_PROPERTIES_PATH= OPENMRS_CORE_PATH= OPENMRS_MODULES_PATH= OPENMRS_CONFIG_PATH= +OPENMRS_PERSON_IMAGES_PATH= +OPENMRS_COMPLEX_OBS_PATH= SPA_PATH= OZONE_CONFIG_PATH= OPENMRS_OWAS_PATH= @@ -157,3 +159,30 @@ ODOO_HOSTNAME=erp-172-17-0-1.traefik.me SENAITE_HOSTNAME=lims-172-17-0-1.traefik.me ERPNEXT_HOSTNAME=erpnext-172-17-0-1.traefik.me FHIR_ODOO_HOSTNAME=fhir-erp-172-17-0-1.traefik.me + +# +# Backup +# +RESTIC_REPOSITORY=/restic_data + +# Used to encrypt the restic repository +RESTIC_PASSWORD=password + +# The snapshot to restore from +RESTIC_RESTORE_SNAPSHOT=latest + +RESTIC_KEEP_DAILY=7 +RESTIC_KEEP_WEEKLY=4 +RESTIC_KEEP_MONTHLY=12 +RESTIC_KEEP_YEARLY=3 + +LOG_LEVEL=info +CRON_SCHEDULE=*/5 * * * * + +# Amazon S3 access (Provide if RESTIC_REPOSITORY points to an S3 bucket) +AWS_DEFAULT_REGION=eu-west-1 +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= + +# Backup path for local restic repository +BACKUP_PATH= diff --git a/README.md b/README.md index 37feaa4..892ad11 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@
-Welcome to Ozone's open-source repositories! diff --git a/bundled-docker/frontend/Dockerfile b/bundled-docker/frontend/Dockerfile index 42aaaa4..113b706 100644 --- a/bundled-docker/frontend/Dockerfile +++ b/bundled-docker/frontend/Dockerfile @@ -1,8 +1,8 @@ FROM openmrs/openmrs-reference-application-3-frontend:nightly ADD distro/binaries/openmrs/frontend /usr/share/nginx/html -ADD distro/configs/openmrs/frontend_config /usr/share/nginx/html/ozone +ADD distro/configs/openmrs/frontend_config /usr/share/nginx/html/configs RUN mkdir -p /app WORKDIR /app COPY bundled-docker/frontend/startup.sh /app RUN chmod +x /app/startup.sh -CMD ["/app/startup.sh"] \ No newline at end of file +CMD ["/app/startup.sh"] diff --git a/bundled-docker/frontend/startup.sh b/bundled-docker/frontend/startup.sh index f557fe2..7f60d42 100755 --- a/bundled-docker/frontend/startup.sh +++ b/bundled-docker/frontend/startup.sh @@ -1,9 +1,7 @@ #!/bin/sh set -e -# if [ -f "/usr/share/nginx/html/ozone/ozone-frontend-config.json" ]; then -# envsubst < "/usr/share/nginx/html/ozone/ozone-frontend-config.json" | sponge "/usr/share/nginx/html/ozone/ozone-frontend-config.json" -# fi -for f in /usr/share/nginx/html/ozone/*.json; do + +for f in /usr/share/nginx/html/configs/*.json; do echo "processing===> $f"; envsubst < $f | sponge $f; done diff --git a/docker-compose-backup.yml b/docker-compose-backup.yml new file mode 100644 index 0000000..d178305 --- /dev/null +++ b/docker-compose-backup.yml @@ -0,0 +1,25 @@ +services: + backup: + image: mekomsolutions/restic-compose-backup + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + # Map local restic repository + - ${BACKUP_PATH:-./restic_data}:/restic_data + # Map restic cache + - restic_cache:/cache + environment: + RESTIC_REPOSITORY: ${RESTIC_REPOSITORY} + RESTIC_PASSWORD: ${RESTIC_PASSWORD} + RESTIC_KEEP_DAILY: ${RESTIC_KEEP_DAILY} + RESTIC_KEEP_WEEKLY: ${RESTIC_KEEP_WEEKLY} + RESTIC_KEEP_MONTHLY: ${RESTIC_KEEP_MONTHLY} + RESTIC_KEEP_YEARLY: ${RESTIC_KEEP_YEARLY} + LOG_LEVEL: ${LOG_LEVEL} + CRON_SCHEDULE: ${CRON_SCHEDULE} + AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION} + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + networks: + - ozone +volumes: + restic_cache: ~ diff --git a/docker-compose-common.yml b/docker-compose-common.yml index 57e4801..c63c13d 100644 --- a/docker-compose-common.yml +++ b/docker-compose-common.yml @@ -37,6 +37,8 @@ services: volumes: - "${MYSQL_DATADIR:-mysql-data}:/var/lib/mysql" - "${SQL_SCRIPTS_PATH}/mysql/create_db.sh:/docker-entrypoint-initdb.d/create_db.sh" + labels: + restic-compose-backup.mariadb: true postgresql: command: "postgres -c wal_level=logical -c max_wal_senders=10 -c max_replication_slots=10" @@ -58,6 +60,8 @@ services: volumes: - "${POSTGRES_DATADIR:-postgresql-data}:/var/lib/postgresql/data" - "${SQL_SCRIPTS_PATH}/postgresql/create_db.sh:/docker-entrypoint-initdb.d/create_db.sh" + labels: + restic-compose-backup.postgres: true volumes: mysql-data: ~ diff --git a/docker-compose-odoo.yml b/docker-compose-odoo.yml index acc111f..2394ae6 100644 --- a/docker-compose-odoo.yml +++ b/docker-compose-odoo.yml @@ -43,6 +43,10 @@ services: traefik.http.middlewares.sslheader.headers.customrequestheaders.X-Forwarded-Proto: https traefik.http.middlewares.limit.buffering.memRequestBodyBytes: 20971520 traefik.http.middlewares.limit.buffering.maxRequestBodyBytes: 20971520 + + #=====================================================backup================================================================ + restic-compose-backup.volumes: true + restic-compose-backup.volumes.include: "${ODOO_FILESTORE:-odoo-filestore},${ODOO_CONFIG_CHECKSUMS_PATH:-odoo-checksums}" networks: - ozone - web diff --git a/docker-compose-openmrs.yml b/docker-compose-openmrs.yml index 56141d4..19fe17b 100644 --- a/docker-compose-openmrs.yml +++ b/docker-compose-openmrs.yml @@ -22,7 +22,7 @@ services: timeout: 5s retries: 48 start_period: 120s - image: openmrs/openmrs-reference-application-3-backend:${O3_DOCKER_IMAGE_TAG:-nightly} + image: openmrs/openmrs-reference-application-3-backend:3.1.1 labels: traefik.enable: "true" traefik.http.routers.openmrs.rule: "Host(`${O3_HOSTNAME}`) && PathPrefix(`/openmrs`)" @@ -31,6 +31,9 @@ services: traefik.http.routers.openmrs.middlewares: openmrs-spa-redirectregex traefik.http.middlewares.openmrs-spa-redirectregex.redirectregex.regex: https://${O3_HOSTNAME}/openmrs/spa traefik.http.middlewares.openmrs-spa-redirectregex.redirectregex.replacement: https://${O3_HOSTNAME}/openmrs/spa/home + #=====================================================backup================================================================ + restic-compose-backup.volumes: true + restic-compose-backup.volumes.include: "${OPENMRS_CONFIG_CHECKSUMS_PATH:-openmrs-config-checksums},${OPENMRS_PERSON_IMAGES_PATH:-openmrs-person-images},${OPENMRS_COMPLEX_OBS_PATH:-openmrs-complex-obs}" networks: - ozone - web @@ -44,6 +47,8 @@ services: - "${OPENMRS_CONFIG_CHECKSUMS_PATH:-openmrs-config-checksums}:/openmrs/data/configuration_checksums" - "${OPENMRS_PROPERTIES_PATH}:/etc/properties/" - "${OPENMRS_PROPERTIES_PATH}/fhirproxy.properties:/openmrs/data/fhirproxy/config.properties" + - "${OPENMRS_PERSON_IMAGES_PATH:-openmrs-person-images}:/openmrs/data/person_images" + - "${OPENMRS_COMPLEX_OBS_PATH:-openmrs-complex-obs}:/openmrs/data/complex_obs" # OpenMRS 3 Frontend frontend: @@ -84,7 +89,7 @@ services: restart: unless-stopped volumes: - "${OPENMRS_FRONTEND_BINARY_PATH}:/usr/share/nginx/html" - - "${OPENMRS_FRONTEND_CONFIG_PATH}:/usr/share/nginx/html/ozone" + - "${OPENMRS_FRONTEND_CONFIG_PATH}:/usr/share/nginx/html/configs" mysql: environment: @@ -105,3 +110,5 @@ volumes: openmrs-data: ~ openmrs-modules: ~ openmrs-owas: ~ + openmrs-person-images: ~ + openmrs-complex-obs: ~ diff --git a/docker-compose-restore.yml b/docker-compose-restore.yml new file mode 100644 index 0000000..957fe1a --- /dev/null +++ b/docker-compose-restore.yml @@ -0,0 +1,33 @@ +services: + openmrs: + depends_on: + restore: + condition: service_completed_successfully + profiles: + - openmrs-restore + odoo: + depends_on: + restore: + condition: service_completed_successfully + profiles: + - odoo-restore + backup: + depends_on: + restore: + condition: service_completed_successfully + restore: + image: mekomsolutions/restic-compose-backup-restore + volumes: + - /var/run/docker.sock:/tmp/docker.sock:ro + # Map local restic repository + - ${BACKUP_PATH:-./restic_data}:/restic_data + environment: + RESTIC_REPOSITORY: ${RESTIC_REPOSITORY} + RESTIC_PASSWORD: ${RESTIC_PASSWORD} + RESTIC_RESTORE_SNAPSHOT: ${RESTIC_RESTORE_SNAPSHOT} + LOG_LEVEL: ${LOG_LEVEL} + AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION} + AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID} + AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY} + networks: + - ozone diff --git a/scripts/destroy-demo.sh b/scripts/destroy-demo.sh index 7675796..6678140 100755 --- a/scripts/destroy-demo.sh +++ b/scripts/destroy-demo.sh @@ -13,6 +13,8 @@ exportPaths # Read PROJECT_NAME from the temporary file PROJECT_NAME=$(cat /tmp/project_name.txt) +# Unset the RESTORE variable if it is set, as the restore Docker Compose files introduces restore specific profiles that will make the Docker Compose file invalid +unset RESTORE echo "$INFO Destroying $PROJECT_NAME project..." diff --git a/scripts/docker-compose-files.txt b/scripts/docker-compose-files.txt index f96c788..60cc3f3 100755 --- a/scripts/docker-compose-files.txt +++ b/scripts/docker-compose-files.txt @@ -2,4 +2,5 @@ docker-compose-common.yml docker-compose-odoo.yml docker-compose-openmrs.yml docker-compose-senaite.yml +docker-compose-backup.yml docker-compose-orthanc.yml diff --git a/scripts/start.sh b/scripts/start.sh index da192bb..9c3cdd9 100755 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -40,18 +40,11 @@ echo "$PROJECT_NAME" > /tmp/project_name.txt if ! isOzoneRunning "$PROJECT_NAME"; then echo "$INFO Starting Ozone project with name: $PROJECT_NAME" +else + echo "$WARN Ozone project with name: $PROJECT_NAME is already running" + echo "$INFO Re-applying Docker Compose up command to ensure all services are up-to-date..." fi -# Check if an instance of Ozone is already running -suffix=0 -while isOzoneRunning "$PROJECT_NAME"; do - echo "$WARN An instance of Ozone is already running with the name: $PROJECT_NAME" - suffix=$((suffix + 1)) - export PROJECT_NAME="$PROJECT_NAME-$suffix" - echo "$INFO Starting a new instance of Ozone with name: $PROJECT_NAME" - echo "$PROJECT_NAME" > /tmp/project_name.txt -done - INSTALLED_DOCKER_VERSION=$(docker version -f "{{.Server.Version}}") MINIMUM_REQUIRED_DOCKER_VERSION_REGEX="^((([2-9][1-9]|[3-9][0]|[0-9]{3,}).*)|(20\.([0-9]{3,}|[1-9][1-9]|[2-9][0]).*)|(20\.10\.([0-9]{3,}|[2-9][0-9]|[1][3-9])))" if [[ $INSTALLED_DOCKER_VERSION =~ $MINIMUM_REQUIRED_DOCKER_VERSION_REGEX ]]; then diff --git a/scripts/stop-demo.sh b/scripts/stop-demo.sh index a146db0..dd406d7 100755 --- a/scripts/stop-demo.sh +++ b/scripts/stop-demo.sh @@ -13,7 +13,8 @@ exportPaths # Read PROJECT_NAME from the temporary file PROJECT_NAME=$(cat /tmp/project_name.txt) - +# Unset the RESTORE variable if it is set, as the restore Docker Compose files introduces restore specific profiles that will make the Docker Compose file invalid +unset RESTORE INSTALLED_DOCKER_VERSION=$(docker version -f "{{.Server.Version}}") MINIMUM_REQUIRED_DOCKER_VERSION_REGEX="^((([2-9][1-9]|[3-9][0]|[0-9]{3,}).*)|(20\.([0-9]{3,}|[1-9][1-9]|[2-9][0]).*)|(20\.10\.([0-9]{3,}|[2-9][0-9]|[1][3-9])))" if [[ $INSTALLED_DOCKER_VERSION =~ $MINIMUM_REQUIRED_DOCKER_VERSION_REGEX ]]; then diff --git a/scripts/utils.sh b/scripts/utils.sh index f5ad0c5..cdc4fa7 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -66,6 +66,12 @@ function setDockerComposeCLIOptions () { export dockerComposeFilesCLIOptions="$dockerComposeFilesCLIOptions -f ../$file" done + # Add restore file if restore env is set + + if [ "$RESTORE" == "true" ]; then + export dockerComposeFilesCLIOptions="$dockerComposeFilesCLIOptions -f ../docker-compose-restore.yml" + fi + # Set the default env file export dockerComposeEnvFilePath="../.env"