From a076355d8087a2020e6e75bcd74f4d6c2f8d80a4 Mon Sep 17 00:00:00 2001 From: mathiasg Date: Mon, 17 Dec 2018 18:08:32 -0500 Subject: [PATCH 1/5] wip: dicom receiver --- docker-compose.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..c95c27a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3' +services: + dcm-receiver: + image: mgxd/dcmrecv:latest + ports: + - "8080:8080" + volumes: + - ./dicoms:/dicoms + command: storescp -v --output-directory /dicoms 8080 From b4e285dc60a1a0abd05ad928054c40fe63fbe2fb Mon Sep 17 00:00:00 2001 From: mathiasg Date: Fri, 21 Dec 2018 12:51:02 -0500 Subject: [PATCH 2/5] enh: heudiconv cronjob --- .env | 6 ++++++ cron/Dockerfile | 14 ++++++++++++++ cron/heudiconv.sh | 28 ++++++++++++++++++++++++++++ cron/heudicron | 4 ++++ cron/start-cron | 9 +++++++++ dcmrecv/Dockerfile | 10 ++++++++++ dcmrecv/README.md | 4 ++++ docker-compose.yml | 16 +++++++++++++--- 8 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 .env create mode 100644 cron/Dockerfile create mode 100644 cron/heudiconv.sh create mode 100644 cron/heudicron create mode 100644 cron/start-cron create mode 100644 dcmrecv/Dockerfile create mode 100644 dcmrecv/README.md diff --git a/.env b/.env new file mode 100644 index 0000000..780fc08 --- /dev/null +++ b/.env @@ -0,0 +1,6 @@ +# environment variables for `docker-compose` +DICOMDIR=./dicoms +PORT=8080 +HEUDICONV_OUTDIR=./output +# args used: --files, -f, -o, -b +HEUDICONV_XARGS="" diff --git a/cron/Dockerfile b/cron/Dockerfile new file mode 100644 index 0000000..42581ac --- /dev/null +++ b/cron/Dockerfile @@ -0,0 +1,14 @@ +FROM nipy/heudiconv:latest + +RUN apt-get update -qq \ + && apt-get install -y -q --no-install-recommends cron \ + && apt-get clean + +COPY heudicron /etc/cron.d/heudicron +COPY heudiconv.sh start-cron / + +RUN chmod +x /heudiconv.sh /start-cron \ + && chmod 0644 /etc/cron.d/heudicron \ + && touch /var/log/cron.log + +ENTRYPOINT ["/start-cron"] diff --git a/cron/heudiconv.sh b/cron/heudiconv.sh new file mode 100644 index 0000000..71cf4b4 --- /dev/null +++ b/cron/heudiconv.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +HEUDICONV_DICOMDIR="/dicoms" +HEUDICONV_OUTDIR="/output" +HEUDICONV_XARGS=${HEUDICONV_XARGS:-""} +HEUDICONV_HISTORY="${HEUDICONV_OUTDIR}/.heudiconv.history" + +set -eu + +if [ ! -d ${HEUDICONV_DICOMDIR} ]; then + echo "DICOM directory ${HEUDICONV_DICOMDIR} not properly set or mounted" + exit 1 +elif [ ! -d ${HEUDICONV_OUTDIR} ]; then + echo "Output directory ${HEUDICONV_OUTDIR} not properly set or mounted" + exit 1 +elif [ ! -f ${HEUDICONV_HISTORY} ]; then + touch ${HEUDICONV_HISTORY} +fi + +for DICOMS in $(ls ${HEUDICONV_DICOMDIR}); do + if grep "${DICOMS}" ${HEUDICONV_HISTORY} > /dev/null; then + # existing conversion was found + continue + fi + + CMD="heudiconv -f reproin --bids --datalad -o ${HEUDICONV_OUTDIR}/${DICOMS} --files ${HEUDICONV_DICOMDIR}/${DICOMS} ${HEUDICONV_XARGS}" + ${CMD} +done diff --git a/cron/heudicron b/cron/heudicron new file mode 100644 index 0000000..8597ce8 --- /dev/null +++ b/cron/heudicron @@ -0,0 +1,4 @@ +# key: min (0-59) | hr (0-23) | dom (1-31) | mon (1-12) | dow (0,7=sun) | command + +# trigger heudiconv every day at 4am +2 * * * * /heudiconv.sh >> /var/log/cron.log diff --git a/cron/start-cron b/cron/start-cron new file mode 100644 index 0000000..8cde482 --- /dev/null +++ b/cron/start-cron @@ -0,0 +1,9 @@ +#!/bin/bash + +service cron start + +CRONLOG="/var/log/cron.log" + +while true; do + tail -f /var/log/cron.log +done diff --git a/dcmrecv/Dockerfile b/dcmrecv/Dockerfile new file mode 100644 index 0000000..0ede2c2 --- /dev/null +++ b/dcmrecv/Dockerfile @@ -0,0 +1,10 @@ +FROM debian:stretch + +ARG DEBIAN_FRONTEND="noninteractive" + +RUN apt-get update -qq \ + && apt-get install -y -q --no-install-recommends ca-certificates apt-utils dcmtk \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +WORKDIR /dicoms diff --git a/dcmrecv/README.md b/dcmrecv/README.md new file mode 100644 index 0000000..6956dce --- /dev/null +++ b/dcmrecv/README.md @@ -0,0 +1,4 @@ +# docker-compose up to start application + +# dcm-receiver app will launch docker container running storescp +# listening for DICOMs on port 8080 and saving to an output directory diff --git a/docker-compose.yml b/docker-compose.yml index c95c27a..39909c5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,17 @@ services: dcm-receiver: image: mgxd/dcmrecv:latest ports: - - "8080:8080" + - "${PORT}:${PORT}" volumes: - - ./dicoms:/dicoms - command: storescp -v --output-directory /dicoms 8080 + - ${DICOMDIR}:/dicoms + command: storescp -v -sp --output-directory /dicoms ${PORT} + + heudiconv: + build: ./cron + volumes: + - ${DICOMDIR}:/dicoms:ro + - ${HEUDICONV_OUTDIR}:/output + depends_on: + - dcm-receiver + command: + - /start-cron From 6f10f02437b2e47bc0d81fabc11469ec4354dbbb Mon Sep 17 00:00:00 2001 From: mathiasg Date: Mon, 24 Dec 2018 06:04:47 -0500 Subject: [PATCH 3/5] enh+doc: docker-compose listener + converter --- .env | 12 +++++++++++- README.md | 17 +++++++++++++++++ cron/Dockerfile | 18 +++++++++++------- cron/heudiconv.sh | 14 ++++++++++++-- cron/start-cron | 2 ++ docker-compose.yml | 4 +--- 6 files changed, 54 insertions(+), 13 deletions(-) diff --git a/.env b/.env index 780fc08..c71416f 100644 --- a/.env +++ b/.env @@ -1,6 +1,16 @@ -# environment variables for `docker-compose` +# configurable options for `docker-compose` +# Description (service-name) + +# Directory to store DICOM files (dcm-receiver) DICOMDIR=./dicoms + +# Port to listen for DICOM transfer (dcm-receiver) PORT=8080 + +# Directory for conversion output (heudiconv) HEUDICONV_OUTDIR=./output + + +# ADVANCED: additional heudiconv arguments to use (heudiconv) # args used: --files, -f, -o, -b HEUDICONV_XARGS="" diff --git a/README.md b/README.md index 899fd6f..cb507b3 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,23 @@ tools, any environment providing them would suffice, such as other Debian-based systems with NeuroDebian repositories configured, which would provide all necessary for ReproIn setup components. + +## `docker-compose` + usage + +This repository provides a `docker-compose` file that includes (2) services: +- DICOM receiver ([dcmtk](https://dicom.offis.de/dcmtk) `storescp`) + listening and ready to receive through a port. +- `reproin` (`heudiconv`) converter set to process all folders in the DICOM + directory through a cron job (default is set to everyday at 4am). + +Refer to the `.env` file - many options above are configurable within it. + +To spin up the reproin service, run `docker-compose up` in the project root - + this will route all logs to the console. If you wish to run it in the service + in the background, append the `--detach` flag, and use `docker-compose logs` + to monitor. Since this is a new feature, it may not behave as intended. If you + encounter any errors, please open an issue and let us know. + ## TODOs/WiP/Related - [ ] add a pre-configured DICOM receiver for fully turnkey deployments diff --git a/cron/Dockerfile b/cron/Dockerfile index 42581ac..e22192d 100644 --- a/cron/Dockerfile +++ b/cron/Dockerfile @@ -1,14 +1,18 @@ FROM nipy/heudiconv:latest RUN apt-get update -qq \ - && apt-get install -y -q --no-install-recommends cron \ + && apt-get install -y -qq --no-install-recommends cron \ && apt-get clean -COPY heudicron /etc/cron.d/heudicron -COPY heudiconv.sh start-cron / +RUN git config --global user.email "user@heudiconv" \ + && git config --global user.name "heudiconv-erter" -RUN chmod +x /heudiconv.sh /start-cron \ - && chmod 0644 /etc/cron.d/heudicron \ - && touch /var/log/cron.log +COPY heudiconv.sh / -ENTRYPOINT ["/start-cron"] +# save copy of current PATH to be used in cron job (hacky) +RUN echo ${PATH} > /opt/heudiconv.path + +RUN chmod +x /heudiconv.sh \ + && (crontab -l; echo "* 4 * * * /heudiconv.sh > /proc/1/fd/1 2>/proc/1/fd/2") | crontab + +ENTRYPOINT cron -f diff --git a/cron/heudiconv.sh b/cron/heudiconv.sh index 71cf4b4..5c78584 100644 --- a/cron/heudiconv.sh +++ b/cron/heudiconv.sh @@ -1,5 +1,7 @@ #!/bin/bash +echo "Running scheduled heudiconv conversion" + HEUDICONV_DICOMDIR="/dicoms" HEUDICONV_OUTDIR="/output" HEUDICONV_XARGS=${HEUDICONV_XARGS:-""} @@ -7,6 +9,13 @@ HEUDICONV_HISTORY="${HEUDICONV_OUTDIR}/.heudiconv.history" set -eu +# cron uses strip down PATH +# pull container creation PATH variable +if [ -f /opt/heudiconv.path ]; then + echo "Setting heudiconv PATHs" + export PATH=$(cat /opt/heudiconv.path) +fi + if [ ! -d ${HEUDICONV_DICOMDIR} ]; then echo "DICOM directory ${HEUDICONV_DICOMDIR} not properly set or mounted" exit 1 @@ -18,11 +27,12 @@ elif [ ! -f ${HEUDICONV_HISTORY} ]; then fi for DICOMS in $(ls ${HEUDICONV_DICOMDIR}); do - if grep "${DICOMS}" ${HEUDICONV_HISTORY} > /dev/null; then + if cat ${HEUDICONV_HISTORY} | awk '{print $1}' | grep "${DICOMS}" > /dev/null; then # existing conversion was found continue fi - CMD="heudiconv -f reproin --bids --datalad -o ${HEUDICONV_OUTDIR}/${DICOMS} --files ${HEUDICONV_DICOMDIR}/${DICOMS} ${HEUDICONV_XARGS}" + CMD="heudiconv -f reproin --bids --datalad -o ${HEUDICONV_OUTDIR} --files ${HEUDICONV_DICOMDIR}/${DICOMS} ${HEUDICONV_XARGS}" ${CMD} + printf "${DICOMS}\t$(date)\n" >> ${HEUDICONV_HISTORY} done diff --git a/cron/start-cron b/cron/start-cron index 8cde482..9019a31 100644 --- a/cron/start-cron +++ b/cron/start-cron @@ -1,5 +1,7 @@ #!/bin/bash +crontab /etc/heudicron + service cron start CRONLOG="/var/log/cron.log" diff --git a/docker-compose.yml b/docker-compose.yml index 39909c5..a92f032 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3' services: dcm-receiver: - image: mgxd/dcmrecv:latest + build: ./dcmrecv ports: - "${PORT}:${PORT}" volumes: @@ -15,5 +15,3 @@ services: - ${HEUDICONV_OUTDIR}:/output depends_on: - dcm-receiver - command: - - /start-cron From fec3c2d81311042c211021ef27e651ba08d9a8ab Mon Sep 17 00:00:00 2001 From: mathiasg Date: Sat, 19 Jan 2019 15:24:07 -0500 Subject: [PATCH 4/5] FIX+DOC: cronjob timing, basic documentation --- {cron => heudicron}/Dockerfile | 0 heudicron/README.md | 5 +++++ {cron => heudicron}/heudiconv.sh | 0 {cron => heudicron}/heudicron | 4 ++-- {cron => heudicron}/start-cron | 0 5 files changed, 7 insertions(+), 2 deletions(-) rename {cron => heudicron}/Dockerfile (100%) create mode 100644 heudicron/README.md rename {cron => heudicron}/heudiconv.sh (100%) rename {cron => heudicron}/heudicron (50%) rename {cron => heudicron}/start-cron (100%) diff --git a/cron/Dockerfile b/heudicron/Dockerfile similarity index 100% rename from cron/Dockerfile rename to heudicron/Dockerfile diff --git a/heudicron/README.md b/heudicron/README.md new file mode 100644 index 0000000..745236b --- /dev/null +++ b/heudicron/README.md @@ -0,0 +1,5 @@ +# heudicron + +Automate received DICOMs through heudiconv's reproin conversion. Users are able + to alter automation schedule via the `heudicron` script. By default, `heudiconv` + conversions will trigger every day at 3am. diff --git a/cron/heudiconv.sh b/heudicron/heudiconv.sh similarity index 100% rename from cron/heudiconv.sh rename to heudicron/heudiconv.sh diff --git a/cron/heudicron b/heudicron/heudicron similarity index 50% rename from cron/heudicron rename to heudicron/heudicron index 8597ce8..376e19d 100644 --- a/cron/heudicron +++ b/heudicron/heudicron @@ -1,4 +1,4 @@ # key: min (0-59) | hr (0-23) | dom (1-31) | mon (1-12) | dow (0,7=sun) | command -# trigger heudiconv every day at 4am -2 * * * * /heudiconv.sh >> /var/log/cron.log +# trigger heudiconv every day at 3am +* 3 * * * /heudiconv.sh >> /var/log/cron.log diff --git a/cron/start-cron b/heudicron/start-cron similarity index 100% rename from cron/start-cron rename to heudicron/start-cron From a78524a578aabd8ed44cb32d89358b0b8b871ab1 Mon Sep 17 00:00:00 2001 From: mathiasg Date: Sat, 19 Jan 2019 15:25:30 -0500 Subject: [PATCH 5/5] FIX: update build path --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index a92f032..b817ec0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,7 @@ services: command: storescp -v -sp --output-directory /dicoms ${PORT} heudiconv: - build: ./cron + build: ./heudicron volumes: - ${DICOMDIR}:/dicoms:ro - ${HEUDICONV_OUTDIR}:/output