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
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 foramd64
architectures, because the binary is copied directly from the Osimis webviewer image - Includes the very useful webviewer plugin from the Osimis Orthanc project
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.
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:
- Register the Docker QEMU cross-compilers
- Call
docker-compose
to build the vanillaorthanc
images - Call
docker-compose
to build theorthanc-plugin
images - Call
docker-compose
to build theorthanc-confd
images - Call
docker-compose
to build theorthanc-wbv-amd64
image - Get docker-manifest from Github
- Put Docker into "experimental mode" for manifest creation
- 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.
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
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.
$ 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
-
Major: Rebased images from
_/ubuntu:14
toresin/$ARCH-debian:stretch
-
Major: Refactored into multi-stage build
-
Major:
orthanc-postgresql
code-base updated to useorthanc-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
inorthanc
image -
Minor: Added GDCM CLI tools to
orthanc
image -
Minor: Refactored
command
to leaveentrypoint
available for init process -
Minor: Redirected
deb.debian.org
sources tocdn-fastly.deb.debian.org
to mitigateapt
source errors -
Minor: Hardened build with cmake options for PIC and stack-protection
-
Minor: Updated DCMTK library to 3.6.4
Grab the latest orthanc.json
file to update the template:
$ docker run -d --name orthanc derekmerck/orthanc
$ docker cp orthanc:/etc/orthanc/orthanc.json .
Standard Orthanc GNU Affero General Public License applies.