diff --git a/.gitignore b/.gitignore index 8a1df65..6627b26 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ local// local/* web/.env */.env +.vscode/* diff --git a/DicomProcessor/Dockerfile b/DicomProcessor/Dockerfile deleted file mode 100644 index dcb6e51..0000000 --- a/DicomProcessor/Dockerfile +++ /dev/null @@ -1,72 +0,0 @@ -## Builds an OpenEyes DicomProcessor service instance. - -ARG OS_VERSION=bionic - -FROM ubuntu:$OS_VERSION - -ARG OS_VERSION -ARG BUILD_BRANCH="develop" -ARG BUILD_CLONEROOT="https://github.com/" -ARG BUILD_GIT_ORG="openeyes" -ARG BUILD_PROJROOT="/dicomprocessor" -ARG DEBIAN_FRONTEND=noninteractive -ARG TIMEZONE="Europe/London" - -ENV BUILD_BRANCH=$BUILD_BRANCH -ENV PROJROOT="$BUILD_PROJROOT" -ENV BUILD_CLONEROOT=$BUILD_CLONEROOT -ENV BUILD_GIT_ORG=$BUILD_GIT_ORG - -## Used by some scripts to determine if they are runing in a container -ENV DOCKER_CONTAINER="TRUE" - -ENV GIT_ORG="" -ENV GIT_USER="" -ENV GIT_EMAIL="" -ENV SSH_PRIVATE_KEY="" -# If TRACK_NEW_GIT_COMMITS=true, then the container will run oe-update every 30 minutes as a cron job -ENV TRACK_NEW_GIT_COMMITS="FALSE" -ENV TZ=$TIMEZONE - -## Database connection credentials: -## It is STRONGLY recommended to change the password for production environments -## It is STRONGLY recommended to use docker secrets for DATABASE_PASS, rather than env variables -## defaults are db; openeyes; 3306; openeyes; openeyes -ENV DATABASE_HOST="db" -ENV DATABASE_NAME="openeyes" -ENV DATABASE_PASS="openeyes" -ENV DATABASE_PORT="3306" -ENV DATABASE_USER="openeyes" - -ENV PROCESSOR_QUEUE_NAME="dicom_queue" -ENV PROCESSOR_SHUTDOWN_AFTER=0 - - -# Set timezone, add common packes, apt clean at the end to minimise layer size -RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone \ - && apt-get update && apt-get install --no-install-recommends -y \ - git-core \ - mariadb-client \ - maven \ - nano \ - ssh-client \ - sudo \ - && apt-get autoremove -y \ - && rm -rf /var/lib/apt/lists/* \ - && apt-get clean -y \ - && rm -rf /var/www/html/* \ - && git config --global core.fileMode false - - # set up folders - RUN cd / && mkdir -p $PROJROOT \ - && echo cloning "-b ${BUILD_BRANCH} $BUILD_CLONEROOT${BUILD_GIT_ORG}/DicomProcessor.git" \ - && git clone -b ${BUILD_BRANCH} $BUILD_CLONEROOT${BUILD_GIT_ORG}/DicomProcessor.git $PROJROOT \ - && cd $PROJROOT \ - && mvn package - - # Add the init script - COPY init.sh /init.sh - COPY wait /wait - RUN chmod a+rx /init.sh && chmod a+rx /wait - - ENTRYPOINT /init.sh diff --git a/DicomProcessor/init.sh b/DicomProcessor/init.sh deleted file mode 100644 index 6e25f7d..0000000 --- a/DicomProcessor/init.sh +++ /dev/null @@ -1,124 +0,0 @@ -#!/bin/bash -l - -echo " - ----------------------------------------------------------------- - ____ ______ - / __ \ | ____| - | | | |_ __ ___ _ __ | |__ _ _ ___ ___ - | | | | '_ \ / _ \ '_ \| __|| | | |/ _ \/ __| - | |__| | |_) | __/ | | | |___| |_| | __/\__ \. - \____/| .__/ \___|_| |_|______\__, |\___||___/ - | | __/ | - |_| |___/ - -Openeyes is an AGPL v3 OpenSource Electronic Patient Record. -Brought to you by the Apperta Foundation (https://apperta.org/) -See the following urls for more info -- https://openeyes.org.uk/ -- https://github.com/openeyes/openeyes -- https://github.com/appertafoundation/openeyes - ----------------------------------------------------------------- - -**************************************************************** -************** DICOM Processor Service ************** -**************************************************************** - -DATABASE_HOST= $DATABASE_HOST:$DATABASE_PORT -DATABASE_USER= $DATABASE_USER -DATABASE_NAME= $DATABASE_NAME - -*************************************************************** - -" -export DEBIAN_FRONTEND=noninteractive - -echo "Setting Timezone to ${TZ:-'Europe/London'}" -# Set system timezone -grep -q "$TZ" /etc/timezone >/dev/null -[ $? = 1 ] && { ln -sf /usr/share/zoneinfo/${TZ:-Europe/London} /etc/localtime && echo ${TZ:-'Europe/London'} > /etc/timezone; } || : -# set PHP/apache timezone (only if changed - to avoid unnecessary extra file layers) -grep -q "$TZ" /etc/php/${PHP_VERSION}/apache2/conf.d/99-timezone.ini >/dev/null -[ $? = 1 ] && { echo "date.timezone = ${TZ:-'Europe/London'}" > /etc/php/${PHP_VERSION}/apache2/conf.d/99-timezone.ini && echo "Updated 99-timezone.ini"; } | : - -# Set ssh key Can be done using a secret (SSH_PRIVATE_KEY), as an ENV variable (SSH_PRIVATE_KEY) -# Or by mounting your host .ssh folder to /root/.host-ssh -# All efforts are made to avoid updating a file if it already exists - to minimise FS layers -mkdir -p /root/.ssh /tmp/.ssh -idfilecontent="Host github.com\nStrictHostKeyChecking no" -[ -d /tmp/.host-ssh ] && rsync -av --no-perms --no-owner --no-group /tmp/.host-ssh/ /root/.ssh --exclude known_hosts --delete 2>/dev/null || : -[ ! -z ${SSH_PRIVATE_KEY} ] && { echo "${SSH_PRIVATE_KEY}" > /tmp/.ssh/id_rsa && echo -e "$idfilecontent\nIdentityFile /tmp/.ssh/id_rsa" > /root/.ssh/config; } || : -[[ -f /run/secrets/SSH_PRIVATE_KEY && ! -f /tmp/.ssh/id_rsa ]] && { echo "USING DOCKER SECRET FOR SSH"; cp /run/secrets/SSH_PRIVATE_KEY /tmp/.ssh/id_rsa; echo -e "$idfilecontent\nIdentityFile /tmp/.ssh/id_rsa" > /root/.ssh/config ; } || : -if ! grep -Fxq "StrictHostKeyChecking no" /root/.ssh/config 2>/dev/null; then echo -e "\n$idfilecontent\n" >> /root/.ssh/config; fi - -# Set up authorised keys for SSH server (if provided) -[[ ! -z "$SSH_AUTHORIZED_KEYS" && ! -f ~/.ssh/authorized_keys ]] && echo "${SSH_AUTHORIZED_KEYS}" > ~/.ssh/authorized_keys || : -[[ -f /run/secrets/SSH_AUTHORIZED_KEYS && ! -f ~/.ssh/authorized_keys ]] && { echo "ADDING SSH AUTHORISED KEYS"; cp /run/secrets//SSH_AUTHORIZED_KEYS ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys ; } || : - -# Update file permissions to 600 for SSH files if not already correct -# Checks current permissions firs, to avoid creating unecessary extra filesystem layers -folders600=( /root/.ssh /tmp/.ssh ) -for i in "${folders600[@]}" -do - shopt -s nullglob - for f in $(ls "$i" | sort -V) - do - if [[ $(stat -c %a "$i"/"$f") != *"600" ]]; then - chmod 600 "$i"/"$f" - echo updated permissions for "$i"/"$f" - fi - done -done - -# If SSH server is enabled, start it early in the process so that it is accessible for debugging -[ "$SSH_SERVER_ENABLE" == "TRUE" ] && service ssh start - -# Use docker secret as DB password, or fall back to environment variable -[ -f /run/secrets/DATABASE_PASS ] && dbpassword="$(/dev/null)$? - -[ "$db_pre_exist" = "1" ] && echo "...database ${DATABASE_NAME:-'openeyes'} found." || { echo "...could not find database ${DATABASE_NAME:-'openeyes'}. Quitting..."; exit 1; } - - -switches="-sf $PROJROOT/src/main/resources/routineLibrary/ -rq dicom_queue -sy 99999" - -# If a shutdown after (minutes) has been specified, then pass this to the processor. It will then run for x minutes before automatically shutting down -[ $PROCESSOR_SHUTDOWN_AFTER -gt 0 ] && switches="$switches -sa $PROCESSOR_SHUTDOWN_AFTER" || : - -# Start apache -echo "Starting opeyes DicomProcessor process..." -echo "" -echo "*********************************************" -echo "** -= END OF STARTUP SCRIPT =- **" -echo "*********************************************" -# Send output of openeyeyes application log to stdout - for viewing with docker logs -# touch $PROJROOT/protected/runtime/application.log -# chmod 664 $PROJROOT/protected/runtime/application.log -# tail -n0 $PROJROOT/protected/runtime/application.log -F | awk '/^==> / {a=substr($0, 5, length-8); next} {print a"App Log:"$0}' & - -$PROJROOT/target/appassembler/bin/dicomEngine $switches diff --git a/DicomProcessor/wait b/DicomProcessor/wait deleted file mode 100644 index 70056c5..0000000 Binary files a/DicomProcessor/wait and /dev/null differ diff --git a/README.md b/README.md index ee8168e..b23c104 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,21 @@ To access the bash shell inside the container; with the container already runnin `docker exec -it bash` +# Adding a crypto key +This is needed from v4.0 onwards for encrypting/decrypting stored passwords for email servers (send as email feature). + +The key should be added as a docker secret. To generate a new key you can use: + +`openssl rand -hex 32` + +Note that the length can be changed. + +For testing/demo purposes, the container is capabale of generating a new key on first start-up. To do this set the following environment variable on the container: + +`GENERATE_TEMP_SODIUM_CRYPTO_KEY=TRUE` + +**NOTE:** If you wish to persist the generated key when a container is recreated then you can mount a volume at `/crypto-temp` + # Accessing docker volumes on a [Windows] Host If you wish to share back docker volumes to a [Windows] host. Use the following image: diff --git a/web/Dockerfile b/web/Dockerfile index 837d906..3de6b94 100644 --- a/web/Dockerfile +++ b/web/Dockerfile @@ -155,11 +155,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /tmp/* -# Install wkhtmltopdf -RUN wget -O /wkhtml.deb https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ +# Install wkhtmltopdf only in PHP 5 builds (i.e, for OE v3.x, WKHTML was retired in v4.0) +RUN [ $(echo "7 >= ${PHP_VERSION}" | bc -l) = 1 ] && { wget -O /wkhtml.deb https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ && dpkg -i --force-depends /wkhtml.deb \ && rm /wkhtml.deb \ - && rm -rf /tmp/* + && rm -rf /tmp/*; } || : # Dependencies for Puppeteer headless chrome browser - only install if PHP ver > 7 RUN [ $(echo "7 <= ${PHP_VERSION}" | bc -l) = 1 ] && { apt-get update && apt-get install -y --no-install-recommends \ diff --git a/web/Dockerfile.allin1.v2 b/web/Dockerfile.allin1.v2 index 5dde089..be5edc1 100644 --- a/web/Dockerfile.allin1.v2 +++ b/web/Dockerfile.allin1.v2 @@ -128,10 +128,11 @@ RUN curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* -# Install wkhtmltopdf -RUN wget -O /wkhtml.deb https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ - && dpkg -i --force-depends /wkhtml.deb \ - && rm /wkhtml.deb +# Install wkhtmltopdf only in PHP 5 builds (i.e, for OE v3.x, WKHTML was retired in v4.0) +RUN [ $(echo "7 >= ${PHP_VERSION}" | bc -l) = 1 ] && { wget -O /wkhtml.deb https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ + && dpkg -i --force-depends /wkhtml.deb \ + && rm /wkhtml.deb \ + && rm -rf /tmp/*; } || : # SETUP apache config # Enable display_errors and error logging for PHP, plus configure timezone diff --git a/web/Dockerfile.php7 b/web/Dockerfile.php7 index f394c6c..4e9f1cd 100644 --- a/web/Dockerfile.php7 +++ b/web/Dockerfile.php7 @@ -155,11 +155,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /tmp/* -# Install wkhtmltopdf -RUN wget -O /wkhtml.deb https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ +# Install wkhtmltopdf only in PHP 5 builds (i.e, for OE v3.x, WKHTML was retired in v4.0) +RUN [ $(echo "7 >= ${PHP_VERSION}" | bc -l) = 1 ] && { wget -O /wkhtml.deb https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ && dpkg -i --force-depends /wkhtml.deb \ && rm /wkhtml.deb \ - && rm -rf /tmp/* + && rm -rf /tmp/*; } || : # Dependencies for Puppeteer headless chrome browser - only install if PHP ver > 7 RUN [ $(echo "7 <= ${PHP_VERSION}" | bc -l) = 1 ] && { apt-get update && apt-get install -y --no-install-recommends \ diff --git a/web/Dockerfile.php7.3 b/web/Dockerfile.php7.3 index 364d242..3ef9043 100644 --- a/web/Dockerfile.php7.3 +++ b/web/Dockerfile.php7.3 @@ -155,11 +155,11 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* \ && rm -rf /tmp/* -# Install wkhtmltopdf -RUN wget -O /wkhtml.deb https://downloads.wkhtmltopdf.org/0.12/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ +# Install wkhtmltopdf only in PHP 5 builds (i.e, for OE v3.x, WKHTML was retired in v4.0) +RUN [ $(echo "7 >= ${PHP_VERSION}" | bc -l) = 1 ] && { wget -O /wkhtml.deb https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.${OS_VERSION}_amd64.deb \ && dpkg -i --force-depends /wkhtml.deb \ && rm /wkhtml.deb \ - && rm -rf /tmp/* + && rm -rf /tmp/*; } || : # Dependencies for Puppeteer headless chrome browser - only install if PHP ver > 7 RUN [ $(echo "7 <= ${PHP_VERSION}" | bc -l) = 1 ] && { apt-get update && apt-get install -y --no-install-recommends \ diff --git a/web/docker-compose.yml b/web/docker-compose.yml index b129852..ae4c852 100644 --- a/web/docker-compose.yml +++ b/web/docker-compose.yml @@ -24,9 +24,8 @@ services: # Uncomment the next line for testing, or to use 10.4 with older versions of OE (prior to v4.0) # - "--sql-mode=NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER" - web_5: - image: appertaopeneyes/web:latest - container_name: openeyes_web_5 + web_7: + image: appertaopeneyes/web:php7 environment: GIT_USER: ${GIT_USER:?'Please set your github user id in .env file'} TZ: 'Europe/London' @@ -47,6 +46,7 @@ services: PHPI_TEST_SETTING: test-123 WAIT_HOSTS_TIMEOUT: "300" # It can take a while for the mariadb container to initialise on first run ENABLE_CRON: "FALSE" # Remove this for live installs + GENERATE_TEMP_SODIUM_CRYPTO_KEY: "TRUE" secrets: - source: SSH_PRIVATE_KEY - source: SSH_AUTHORIZED_KEYS @@ -60,52 +60,10 @@ services: volumes: - "oe-web:/var/www/openeyes" # Following is useful when using VS COde remote for development - - "php5_vscode:/root/.vscode-server" + - "php7_vscode:/root/.vscode-server" depends_on: - db - hostname: oe-web-php5 -# web_7: -# image: appertaopeneyes/web:php7 -# container_name: openeyes_web_7 -# environment: -# GIT_USER: ${GIT_USER:?'Please set your github user id in .env file'} -# TZ: 'Europe/London' -# UID: '1' -# GID: '1' -# OE_MODE: 'DEV' -# OE_INSTITUTION_CODE: NEW -# OE_PORTAL_URI: ${OE_PORTAL_URI} -# OE_PORTAL_EXTERNAL_URI: ${OE_PORTAL_EXTERNAL_URI} -# OE_PORTAL_USERNAME: ${OE_PORTAL_USERNAME} -# OE_PORTAL_PASSWORD: ${OE_PORTAL_PASSWORD} -# OE_PORTAL_CLIENT_ID: ${OE_PORTAL_USERNAME} -# OE_PORTAL_CLIENT_SECRET: ${OE_PORTAL_CLIENT_SECRET} -# OE_PORTAL_ENABLED: "FALSE" -# SSH_SERVER_ENABLE: "TRUE" -# DATABASE_HOST: "db" -# MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-example} -# PHPI_TEST_SETTING: test-123 -# WAIT_HOSTS: "web_5:80" # Wait for web_5 to startup first - this prevents both containers trying to clone at the same time on first run -# WAIT_HOSTS_TIMEOUT: "3000" # It can take quite a while for web 5 to start on first run, so we need a long time-out -# WAIT_SLEEP_INTERVAL: "3" # reduces the number of messages sent to the log while waiting for web_5 to complete its first run -# ENABLE_CRON: "FALSE" # Remove this for live installs -# secrets: -# - source: SSH_PRIVATE_KEY -# - source: SSH_AUTHORIZED_KEYS -# ports: -# - "7777:80" -# - "22:22" -# stdin_open: true -# tty: true -# volumes: -# - "oe-web:/var/www/openeyes" -# # Following is useful when using VS COde remote for development -# - "php7_vscode:/root/.vscode-server" -# depends_on: -# - "db" -# - "web_5" -# hostname: oe-web-php7 volumes: oe-web: diff --git a/web/init.sh b/web/init.sh index 1da2504..bcd303f 100644 --- a/web/init.sh +++ b/web/init.sh @@ -72,6 +72,35 @@ mkdir -p /root/.ssh /run/.ssh # If SSH server is enabled, start it early in the process so that it is accessible for debugging [ "${SSH_SERVER_ENABLE^^}" == "TRUE" ] && service ssh start +# Check if an encryption key has been set for email sending, etc. +if [ -f '/run/secrets/SODIUM_CRYPTO_KEY' ] ; then + echo "** Sodium crypto key loaded from secret **" +elif [ "${GENERATE_TEMP_SODIUM_CRYPTO_KEY^^}" = "TRUE" ]; then + # for demos, dev, etc., you may not want to generate a secret in advance. By setting GENERATE_TEMP_SODIUM_CRYPTO_KEY to TRUE, + # a new key will be generated on first run and stored. It will be loaded into the /run/secrets/SODIUM_CRYPTO_KEY + # at each startup. + # Note that this key will be lost if the container gets rebuilt, unless you mount the /crypto-temp folder as a volume + mkdir -p /crypto-temp + [ ! -f '/sodium_crypto_key_temp' ] && openssl rand -hex 32 > /crypto-temp/sodium_key || : + cp /crypto-temp/sodium_key /run/secrets/SODIUM_CRYPTO_KEY + echo "** sodium crypto key loaded from generated file **" +else + echo "" + echo "*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x" + echo "x WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING *" + echo "* x" + echo "x No SODIUM_CRYPTO_KEY secret has been provided. This is required for send via email *" + echo "* feature of correspondence (used for encryption and decryption of email account passwords). x" + echo "x *" + echo "x If you are note using this email feature then you can safely ignore this warning. *" + echo "* x" + echo "x To generate a new key, run `openssl rand -hex 32` and copy the resulting key into a *" + echo "* docker secret named SODIUM_CRYPTO_KEY. x" + echo "x You will then need to recreate this container with the secret *" + echo "*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x*x" + echo "" +fi + # if we have mysql installed in the same image, then start the service [ "${LOCAL_DB^^}" == "TRUE" ] && service mysql start