/docker-orthanc-xarch

Build multi-architecture Orthanc DICOM-node Docker images.

Primary LanguageShell

X-Arch Orthanc for Docker

Derek Merck
derek_merck@brown.edu
Rhode Island Hospital and Brown University
Providence, RI

Build multi-architecture Orthanc DICOM-node Docker images.

source: https://github.com/derekmerck/docker-orthanc-xarch

Overview

Orthanc is developed and maintained by SĂ©bastien Jodogne. Full documentation is available in the Orthanc Book.

This repo is a fork of Jodogne's OrthancDocker project. The xarch branch creates cross-architecture Docker images for the most recent default/mainline release version of Orthanc. These images are manifested per modern Docker.io guidelines so that an appropriately architected image can be will automatically selected for a given tag depending on the pulling architecture.

This repo also creates a "self-configuring" orthanc image, orthanc-confd, motivated by the OsimisDocker environment-variable-based configurator.

  • Based on the cross-architecture orthanc-plugins image
  • Uses confd to generate an appropriate orthanc.json configuration file from environment variables at startup
  • Creates a postgres database for itself if needed
  • Provides simple auto-forwarding to other Orthanc peers and DICOM modalities
  • Includes a modern Docker container "healthcheck" attribute that regularly checks connectivity on 8042

Futher movitivated by the OsirisDocker project, this repo also creates an "osimis-webviewer" orthanc image, orthanc-wbv.

  • Based on cross-architecture orthanc-confd, but ONLY built for amd64 architectures, because the binary is copied directly from the Osimis webviewer image
  • Includes the very useful webviewer plugin from the Osimis Orthanc project

Use It

Images can be pulled from:

$ docker run derekmerck/orthanc          # (latest-amd64, latest-arm32v7, latest-arm64v8)
$ docker run derekmerck/orthanc-plugins  # (latest-amd64, latest-arm32v7, latest-arm64v8)
$ docker run derekmerck/orthanc-confd    # (latest-amd64, latest-arm64v8)
$ docker run derekmerck/orthanc-wbv      # (latest-amd64)

Images for specific architectures images can be directly pulled from the same namespace using the format derekmerck/orthanc:${TAG}-${ARCH}, where $ARCH is one of amd64, arm32v7, or arm64v8. Explicit architecture specification is sometimes helpful when an indirect build service shadows the production architecture.

Build It

These images are based on the cross-platform resin/${ARCH}-debian:stretch image. Resin.io base images include the QEMU cross-compiler to facilitate building Docker images for low-power single-board computers while using more powerful Intel-architecture compute servers.

This supports builds for amd64, armhf/arm32v7, and aarch64/arm64v8 architectures. Most low-power single board computers such as the Raspberry Pi and Beagleboard are armhf/arm32v7 devices. The Pine64 and NVIDIA Jetson are aarch64/arm64v8 devices. Desktop computers/vms, UP boards, and the Intel NUC are amd64 devices.

docker-compose.yml contains build recipes for each architecture for both a vanilla orthanc image and an orthanc-plugins image. orthanc-plugins is based on orthanc, but since we cannot define build dependencies in a compose file (strangely, depends_on only works with run or up), the vanilla orthanc image must be explicitly built before the orthanc-plugins image.

To build all images:

  1. Register the Docker QEMU cross-compilers
  2. Call docker-compose to build the vanilla orthanc images
  3. Call docker-compose to build the orthanc-plugin images
  4. Call docker-compose to build the orthanc-confd images
  5. Call docker-compose to build the orthanc-wbv-amd64 image
  6. Get docker-manifest from Github
  7. Put Docker into "experimental mode" for manifest creation
  8. Call docker-manifest.py with an appropriate domain to manifest and push the images
$ docker run --rm --privileged multiarch/qemu-user-static:register --reset
$ docker-compose build orthanc-amd64 orthanc-arm32v7 orthanc-arm64v8
$ docker-compose bulid orthanc-plugins-amd64 orthanc-plugins-arm32v7 orthanc-plugins-arm64v8
$ docker-compose bulid orthanc-confd-amd64 orthanc-confd-arm64v8
$ docker-compose bulid orthanc-wbv-amd64
$ pip install git+https://github.com/derekmerck/docker-manifest
$ mkdir -p $HOME/.docker && echo '{"experimental":"enabled"}' > "$HOME/.docker/config.json"
$ python3 -m docker-manifest -d $DOCKER_USERNAME orthanc
$ python3 -m docker-manifest -d $DOCKER_USERNAME orthanc-plugins
$ python3 -m docker-manifest -d $DOCKER_USERNAME orthanc-confd
$ python3 -m docker-manifest -d $DOCKER_USERNAME orthanc-wbv

A Travis automation pipeline for git-push-triggered image regeneration and tagging is demonstrated in the .travis.yml script. However, these cross-compiling jobs exceed Travis' 50-minute timeout window, so builds are currently done by hand using cloud infrastructure.

Run Orthanc on ARM

If you need access to an ARM device for development, Packet.net rents bare-metal 96-core 128GB aarch64 Cavium ThunderX servers for $0.50/hour. Packet's affiliated Works On Arm program provided compute time for developing and testing these cross-platform images.

Setup your ARM device with Docker and pull the image tag. You can confirm that the appropriate image has been pulled by starting a container with the command arch.

$ docker pull derekmerck/orthanc
Using default tag: latest
latest: Pulling from derekmerck/orthanc
Digest: sha256:1975e3a92cf9099284fc3bb2d05d3cf081d49babfd765f96f745cf8a23668ff6
Status: Downloaded newer image for derekmerck/orthanc:latest
$ docker run derekmerck/orthanc arch
aarch64

You can also confirm the image architecture without running a container by inspecting the value of .Config.Labels.architecture. (This is a creator-defined label that is different than the normal .Architecture key -- which appears to always report as amd64.)

$ docker inspect derekmerck/orthanc --format "{{ .Config.Labels.architecture }}"
arm64v8

Why Bother?

On-board embedded AI is the future of medical imaging! Orthanc provides a vital, robust bridge between modality-generated DICOM and modern data indexing and analysis algorithms.

This image is also drop-in compatible with the derekmerck.orthanc-docker Ansible role, facilitating quick configuration of complex DICOM infrastructures on ARM data center equipment.

Confd/wbv Options

$ docker run -e ORTHANC_PASSWORD=my_password -e ORTHANC_AET=MY_ORTHANC derekmerck/orthanc-confd 

Following is a list of common options and their defaults that can be configured through environment variables.

ORTHANC_VERBOSE=false

ORTHANC_NAME=Orthanc
ORTHANC_AET=ORTHANC
ORTHANC_MAX_SIZE=0    # Max storage size in MB
ORTHANC_MAX_PATIENTS=0
ORTHANC_STORE_DICOM=true
ORTHANC_STORE_COMPRESSED=false  # zlib file compression

ORTHANC_DICOM_SCP_TIMEOUT=10    # Orthanc server to for clients
ORTHANC_DICOM_SCU_TIMEOUT=30    # Orthanc client to for servers
ORTHANC_STABLE_AGE=60

ORTHANC_REMOTE_ENABLED=true
ORTHANC_AUTH_ENABLED=true
ORTHANC_USER=orthanc
ORTHANC_PASSWORD=passw0rd!

ORTHANC_USER_[0-3]=""  # Additional users in "user,password" format
ORTHANC_MOD_[0-3]=""   # Known DICOM modalities in "name,aet,host,port" format
ORTHANC_PEER_[0-3]=""  # Known Orthanc peers in "name,url,user,password" format

ORTHANC_METADATA_0=""  # Optional metadata tags in "key,value" format

NOTE: avoid using , or escaped characters like quotes in passwords as they interfere with the simple string splitting used for parsing here.

The postgres plugin can be similarly configured using ORTHANC_PG variables

ORTHANC_PG_ENABLED=false
ORTHANC_PG_STORE_DICOM=false  # Use Postgres as persistent storage for file data
ORTHANC_PG_HOST=localhost
ORTHANC_PG_PORT=5432
ORTHANC_PG_USER=postgres
ORTHANC_PG_PASSWORD=passw0rd!
ORTHANC_PG_DATABASE=orthanc

Simple routing to known peers or modalities can be configured using ORTHANC_ROUTE variables.

ORTHANC_ROUTE_ENABLED=false
ORTHANC_ROUTE_AND_STORE=false  # Do not delete image after forwarding 
ORTHANC_ROUTE_TO_PEERS=""      # Names from ORTHANC_PEER_N as "name1,name1,name2,..."
ORTHANC_ROUTE_TO_MODS=""       # Names from ORTHANC_MOD_N as "name1,name1,name2,..."

The webviewer plugin for the orthanc-wbv image is configured using using ORTHANC_WBV variables.

ORTHANC_WBV_ENABLED=false
ORTHANC_WBV_DOWNLOAD_ENABLED=false
ORTHANC_WBV_STORE_ANNOTATIONS=false

There is a good summary of this "confd onetime" configuration method here http://www.mricho.com/confd-and-docker-separating-config-and-code-for-containers/

To avoid writing any config data (or passwords) to disk, bind a tmpfs mount to /etc/orthanc. (Requires different syntax for swarm deployment.)

$ docker run --tmpfs /etc/orthanc derekmerck/orthanc-confd

Or in docker-compose.yml:

services:
  orthanc:
    image: derekmerck/orthanc-confd
    tmpfs: /etc/orthanc

Changes

  • Major: Rebased images from _/ubuntu:14 to resin/$ARCH-debian:stretch

  • Major: Refactored into multi-stage build

  • Major: orthanc-postgresql code-base updated to use orthanc-databases repo

  • Major: Wrapped Orthanc invocation with confd

  • Major: Added psychopg2 script to check for Postgres database and create if necessary

  • Major: Added simple lua-scripted auto-forwarding

  • Major: Added Osimis webviewer (for amd64 ONLY)

  • Minor: Set locale using a Debian-friendly method

  • Minor: Specified libssl1.0-dev in orthanc image

  • Minor: Added GDCM CLI tools to orthanc image

  • Minor: Refactored command to leave entrypoint available for init process

  • Minor: Redirected deb.debian.org sources to cdn-fastly.deb.debian.org to mitigate apt source errors

  • Minor: Hardened build with cmake options for PIC and stack-protection

  • Minor: Updated DCMTK library to 3.6.4

Notes

Grab the latest orthanc.json file to update the template:

$ docker run -d --name orthanc derekmerck/orthanc
$ docker cp orthanc:/etc/orthanc/orthanc.json .

License

Standard Orthanc GNU Affero General Public License applies.