Orthanc deployment guide
Orthanc is a lightweight, open-source DICOM server (a "mini-PACS"). Scanners send studies to it; wawa reads them over DICOMweb and pushes worklists to it.
Ultrasound scanner ──C-STORE / C-FIND (4242, LAN only)──▶ Orthanc ◀──HTTPS 443── wawa
│
reverse proxy ──┘ (8042 local only)
wawa needs four things from the server:
| Capability | Used for | Provided by |
|---|---|---|
DICOM receive (C-STORE) on 4242 | Scanners send studies | Orthanc core |
DICOMweb (QIDO-RS / WADO-RS) under /dicom-web/ | wawa reads studies | DICOMweb plugin |
Worklists over REST (PUT /worklists/{id}) | wawa pushes appointments | Worklists plugin (the REST plugin released November 2025) |
Change feed (/changes, /tools/bulk-content) | Incremental sync | Orthanc core |
The legacy "sample" Modality Worklists plugin (libModalityWorklists.so / ModalityWorklists.dll) has no
REST API and does not work with wawa. Remove it if present. Note that Orthanc Explorer 2's version number says
nothing about worklists.
Install
The guidance below was verified with Orthanc release 26.6.1 (core 1.12.11, Worklists plugin 0.9.2). Use the latest release and check the Orthanc Book for changes.
Linux with Docker (recommended)
sudo mkdir -p /orthanc/db /orthanc/config /orthanc/worklists
docker run -d \
--name orthanc \
--restart unless-stopped \
-p 4242:4242 \
-p 127.0.0.1:8042:8042 \
-v /orthanc/db:/var/lib/orthanc/db \
-v /orthanc/worklists:/var/lib/orthanc/worklists \
-v /orthanc/config:/etc/orthanc \
orthancteam/orthanc:26.6.1
- Pin the image tag; never run
latestin a clinic. - The image bundles the DICOMweb and Worklists plugins, but both are disabled until configured (see Configure).
- The worklists directory must exist; the plugin does not create it.
- Port
8042is published on127.0.0.1only, for the reverse proxy on the host. Because the proxy's requests reach the container from the Docker network rather than from localhost, set"RemoteAccessAllowed": truein Configure for Docker installs, and rely on the loopback-only port binding and the firewall instead.
Linux with distribution packages
Distribution packages lag behind and there is no worklists package. Install core and DICOMweb, then add the Worklists plugin by hand:
sudo apt update
sudo apt install orthanc orthanc-dicomweb
wget https://github.com/orthanc-server/orthanc-worklists/releases/download/0.9.2/libOrthancWorklists-ubuntu.so
sudo mv libOrthancWorklists-ubuntu.so /usr/share/orthanc/plugins/libOrthancWorklists.so
# Remove the legacy plugin (re-check after every apt upgrade)
sudo mv /usr/share/orthanc/plugins/libModalityWorklists.so /root/
sudo mkdir -p /var/lib/orthanc/worklists
sudo chown orthanc:orthanc /var/lib/orthanc/worklists
Windows
- Run the 64-bit Orthanc installer as administrator and keep the DICOMweb and Worklists plugins selected.
- Orthanc runs as a Windows service; restart it from
services.mscafter configuration changes. - Every
.jsonfile in theConfigurationfolder is merged, and a duplicated option stops the service from starting. Use forward slashes in paths. - Delete a leftover
ModalityWorklists.dllfrom installs older than 25.11.2. - The installer creates a default
orthanc/orthancaccount: remove it. - Use IIS with Application Request Routing, or Nginx for Windows, as the HTTPS reverse proxy.
Configure
orthanc.json (or a file in the mounted config folder):
{
"Name": "Clinic Orthanc",
"StorageDirectory": "/var/lib/orthanc/db",
"IndexDirectory": "/var/lib/orthanc/db",
"AuthenticationEnabled": true,
"RegisteredUsers": {
"wawa": "use-a-long-random-password"
},
"RemoteAccessAllowed": false,
"HttpPort": 8042,
"DicomAet": "ORTHANC",
"DicomPort": 4242,
"DicomCheckCalledAet": true,
"DicomWeb": {
"Enable": true,
"Root": "/dicom-web/"
},
"Worklists": {
"Enable": true,
"Directory": "/var/lib/orthanc/worklists"
},
"StorageCompression": false
}
RegisteredUsers: wawa's own account. Remove any defaultorthancaccount.RemoteAccessAllowed: false: HTTP answers on the machine only; outside access goes through the proxy (package and Windows installs; see the Docker note under Install).Worklists.Directory(namedDatabasein the legacy plugin). Alternatively store worklists in the Orthanc database with"SaveInOrthancDatabase": true.DeleteWorklistsOnStableStudyis on by default, so entries disappear once their study arrives. That is intended.
Secure
HTTPS: wawa's door
Put an HTTPS reverse proxy on the same machine (with a public CA certificate, or send us your internal root CA), exposing only the four paths wawa uses:
server {
listen 443 ssl;
server_name dicom.clinic.example;
ssl_certificate /etc/ssl/clinic/fullchain.pem;
ssl_certificate_key /etc/ssl/clinic/privkey.pem;
location /dicom-web/ { proxy_pass http://127.0.0.1:8042; }
location /worklists { proxy_pass http://127.0.0.1:8042; }
location /changes { proxy_pass http://127.0.0.1:8042; }
location /tools/bulk-content { proxy_pass http://127.0.0.1:8042; }
}
Only 443 is reachable from outside the machine: over a Site-to-Site VPN, or,
if you publish it yourself, restricted to wawa's egress IPs (see
Public connectivity; securing a public endpoint is your responsibility). Port 8042 stays closed.
DICOM: the scanners' door
By default Orthanc accepts C-STORE from any device but refuses worklist C-FIND from unknown ones, which is the most common reason for an empty worklist. Declare every scanner:
"DicomModalities": {
"us01": ["US01", "192.168.1.50", 104],
"us02": ["US02", "192.168.1.51", 104]
},
"DicomAlwaysAllowEcho": false,
"DicomAlwaysAllowStore": false,
"DicomCheckModalityHost": true
- Each entry is
[AE Title, IP, port], using the AE Title configured on that scanner. DicomCheckModalityHostrequires static IPs or DHCP reservations for the scanners.- Port
4242is reachable only from the scanners' network segment, never from the internet. - Leave the Worklists plugin's
FilterIssuerAetoption off; wawa addresses entries by scheduled station AE Title instead.LimitAnswerscan cap how many entries one query returns.
Configure the scanners
| On the scanner | Value |
|---|---|
| Store destination AE Title | ORTHANC (matches DicomAet) |
| Store destination IP and port | The Orthanc machine's LAN IP, port 4242 |
| Worklist server AE Title, IP and port | Same as above |
| The scanner's own AE Title | Must match its DicomModalities entry and the Worklist Group AE Title in wawa |
| Patient ID | The wawa patient identifier |
Size storage and set retention
Orthanc never deletes studies by default (MaximumStorageSize and MaximumPatientCount are 0), and wawa
never deletes them either. A full disk stops scanners from sending studies, which is a clinical outage.
A planning figure is about 7 GB per day (35 patients × ~28 images × ~7 MB):
| Retention | Studies | Provision (at 70% fill) |
|---|---|---|
| 30 days | ~210 GB | ~300 GB |
| 60 days | ~420 GB | ~600 GB |
| 90 days (recommended) | ~630 GB | ~900 GB – 1 TB |
For 90 days, set "MaximumStorageSize": 645120 (MB, ~630 GB) with "MaximumStorageMode": "Recycle", so the
oldest studies are removed first ("Reject" refuses new studies instead). Budget backup space
separately, alert on disk usage early, and check real sizes with GET /statistics.
Back up /var/lib/orthanc/db and the configuration daily, and test a restore.
Validate the server
Two sets of read-only checks. They return server metadata only, never patient data. Replace the placeholders; never paste real credentials into tickets or email.
From outside your network (or send us the output). Only the four proxied paths should reach Orthanc:
for path in /worklists /dicom-web/studies /changes /tools/bulk-content; do
printf '%s ' "$path"
curl -sS -o /dev/null -D - -w 'status: %{http_code}\n' "https://<orthanc-host>$path" \
| grep -i -E '^www-authenticate|^status' | tr '\n' ' '
echo
done
| Check | Pass |
|---|---|
| 1. Proxied paths reach Orthanc | Each path returns 401 with Basic realm="Orthanc Secure Area" (Orthanc's own challenge, not a proxy error page) |
| 2. Nothing else is exposed | https://<orthanc-host>/, /system and /ui/ do not reach Orthanc (proxy 404 or refused) |
| 3. Credentials and worklists | curl -u '<user>:<password>' 'https://<orthanc-host>/worklists?format=Simplify' returns 200; a 404 "Unknown resource" means the REST Worklists plugin is missing or not enabled |
| 4. DICOMweb | curl -u '<user>:<password>' 'https://<orthanc-host>/dicom-web/studies?limit=1' returns 200 |
On the Orthanc server itself (against http://localhost:8042, same credentials):
| Check | Command | Pass |
|---|---|---|
| 5. Plugins enabled | GET /system | 200, PluginsEnabled: true |
| 6. Scanners declared | GET /modalities?expand | Non-empty, with each scanner's AE Title |
| 7. Storage | GET /statistics | Informational: disk use and instance count |
Then, end to end: C-ECHO from each scanner, push a test worklist entry and see it on the scanner, perform a test scan, run Test Connection in wawa and confirm the study syncs.
Troubleshooting
| Symptom | Cause |
|---|---|
| Test Connection returns plain study IDs | The station's DICOMweb root doesn't match the server (Orthanc: dicom-web) |
PUT /worklists/{id} returns 404 | REST Worklists plugin not installed, only the legacy plugin present, or plugin loaded but not enabled |
PUT /worklists/{id} returns 500 "Cannot write to file" | Worklists directory missing or not writable |
| Scanner stores studies but its worklist is empty | Scanner not declared in DicomModalities, or AE Title mismatch |
| Entry visible on one scanner but not another | Entry addressed to a Worklist Group AE Title matching only the first |
| Worklists stopped after a network change | Scanner's IP changed while DicomCheckModalityHost is on |
| Worklist entries vanish after the scan | DeleteWorklistsOnStableStudy, by design |
References
- Orthanc Book · Configuration reference
- Worklists plugin · DICOMweb plugin
- Docker images · Nginx · Security
- DICOM standard · DICOMweb
wawa fertility does not provide support for managing Orthanc servers. This guide uses open-source components that may contain vulnerabilities; the clinic's IT department is solely responsible for managing and securing this infrastructure.