Monday, September 17, 2018

Configuring Orthanc with Postgres backend with a network data directory

So we hve configured Orthanc with a Postgres backend. To support a large-scale data store, we mapped a network directory as the data directory of Postgres. Then we configured Orthanc to have Postgres as its backend data store, instead of its default SQLite backend, using the Postgres plugin. There is also an option for a MySQL/MariaDB backend, which we found not stable with MySQL in a network directory.

However, since we have the configured Postgres in a network directory, we have to make sure everything is running fine. Unfortunately, when we reboot, often the network directory does not mount on its own. Therefore, despite our configuration to start Postgres and Orthanc at the boot time, they both fail.

Data directory unaccessible → Postgres fails to start. Postgres failed to start → Orthanc fails to start.

We have to configure the below services in Centos, following the same order.

1) Postgresql
$ sudo systemctl start postgresql

$ sudo systemctl enable postgresql

$ sudo systemctl status postgresql

● postgresql.service - PostgreSQL database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-09-17 14:46:41 EDT; 11min ago
 Main PID: 2655 (postgres)
   CGroup: /system.slice/postgresql.service
           ├─2655 /usr/bin/postgres -D /opt/pacs/postgres -p 5432
           ├─2657 postgres: logger process
           ├─2701 postgres: checkpointer process
           ├─2702 postgres: writer process
           ├─2703 postgres: wal writer process
           ├─2704 postgres: autovacuum launcher process
           ├─2705 postgres: stats collector process
           ├─2754 postgres: postgres orthanc ::1(48534) idle
           └─2755 postgres: postgres orthanc ::1(48536) idle

Sep 17 14:45:59 HOST.NAME systemd[1]: Starting PostgreSQL database server...
Sep 17 14:45:59 HOST.NAME pg_ctl[2652]: pg_ctl: another server might be running; trying to start server anyway
Sep 17 14:46:41 HOST.NAME systemd[1]: Started PostgreSQL database server.

2) Orthanc
$ sudo systemctl start orthanc

$ sudo systemctl enable orthanc

$ sudo systemctl status orthanc

● orthanc.service - Orthanc DICOM server
   Loaded: loaded (/usr/lib/systemd/system/orthanc.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-09-17 14:47:14 EDT; 8min ago
     Docs: man:Orthanc(1)
 Main PID: 2753 (Orthanc)
   CGroup: /system.slice/orthanc.service
           └─2753 /usr/sbin/Orthanc /etc/orthanc/orthanc.json

Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.399045 ServerContext.cpp:167] Reloading the jobs from the last execution of Orthanc
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.399776 JobsEngine.cpp:281] The jobs engine has started with 2 threads
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.400023 ServerContext.cpp:293] Disk compression is disabled
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.400050 ServerIndex.cpp:1437] No limit on the number of stored patients
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.400490 ServerIndex.cpp:1454] No limit on the size of the storage area
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.400995 LuaContext.cpp:103] Lua says: Lua toolbox installed
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.403966 main.cpp:848] DICOM server listening with AET BMIPACS on port: 4242
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.404382 MongooseServer.cpp:1087] HTTP compression is enabled
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.405872 MongooseServer.cpp:1001] HTTP server listening on port: 8042 (HTTPS encryption is disabled, remote access is allowed)
Sep 17 14:47:15 HOST.NAME Orthanc[2753]: W0917 14:47:15.405915 main.cpp:667] Orthanc has started

To clean the data from Orthanc entirely


The easy way is to drop the Orthanc database.

First go to another database to be able to drop the Orthanc database
orthanc=# \c mytest
You are now connected to database "mytest" as user "postgres".

mytest=# drop database orthanc;
ERROR:  database "orthanc" is being accessed by other users
DETAIL:  There are 2 other sessions using the database.

Yes, first we need to stop Orthanc!

[root@researchpacs postgres]# systemctl stop orthanc

Now drop the database. 
mytest=# drop database orthanc;

Create the database again.

mytest=# create database orthanc;

Now you may start Orthanc again!

[root@researchpacs postgres]# systemctl start orthanc

You can also access your data via a browser, using the HTTP Port:


Tuesday, September 11, 2018

Configuring Kong API Gateway for your Service Endpoints

Kong provides a complete documentation on its installation and a quick-start guide to start using it, such as configuring a service in Kong

In this post we will briefly look into configuring Kong using its Docker container as an API gateway for your backend services. This document uses Kong version 0.14.0-alpine, which is the current latest version of Kong. Kong can be configured with Postgres or Cassandra backend for its persistent storage. Here we will configure Kong with Postgres.

Install and Start Kong with Postgres

You have 2 options. If you want to get it done quick, I recommend choosing the option #2 - installing via Docker containers.

1. Download Kong's native installation for your operating system

Download and install Kong for your respective operating system 

Configure with Postgres:
$ psql -U postgres
postgres=# CREATE USER kong; CREATE DATABASE kong OWNER kong;

Run the Kong migrations:
$ kong migrations up

Start Kong
$ kong start

You may choose to start with verbose logs:
$ kong start -vv

You may need to create a kong configuration file to load Kong with custom configurations:
$ sudo mkdir /etc/kong

$ sudo touch /etc/kong/kong.conf

Now your Kong is running. Confirm that by,


2.  Install Kong via Docker containers.

We have our own "kong-ldap" repository with scripts that will install and configure Kong with Postgres in a container. 

$ cd kong-ldap

$ sh

Optionally, you may also use these scripts to configure OpenDJ LDAP directory as a Docker container a well, connected to Docker. However, the commands are commented out - therefore you will need to uncomment the relevant commands in the script buildRun script to get it working.

Kong has two interfaces. One is the user-facing interface and the other one is the admin interface. The admin interface by default listens to the port 8001 and should not be exposed to the public. The admin interface is used by the administrators to create and configure the routes to the services in the Kong API gateway. The user-facing interface by default listens to the port 8000. It is exposed to the public, and the users can consume the services defined by the admin previously using the user-facing interface. The user-facing interface is completely separated by Kong from the admin interface.

Configure Kong for your Services

Configuring Kong as an API gateway for your services is a 2-step procedure, starting from Kong 0.14. Previous versions of Kong provided a unified approach through its "api" objects, which is current depreciated and replaced by two entities known as "services" and "routes".

Make sure that you have Kong up and running. Then,  execute the below two commands from the server that hosts Kong.

First, you need to define a "service" in Kong to each of your service/API groups (i.e., your backend applications or web services).

1) Create a Kong Service using the Kong Admin API

$ curl -i -X POST --url http://localhost:8001/services/ --data 'name=radiology' --data 'url='

Above, we assume your web application is hosted in  and it has a set of services under the base path /services/v4/TCIA/query/. We pass the complete url of the backend of the original service deployments through the "url" flag, as shown above. We create a service named "radiology" in Kong for these services, using the Kong admin interface for the creation of services. Here, we assume Kong is hosted in localhost, with its admin interface using the default port option of 8001. /services/ let you create/modify the service definitions in Kong.

Second, you should add a "route" to the "radiology" service that you created.

2) Add a Route to the Kong Service

$ curl -i -X POST --url http://localhost:8001/services/radiology/routes --data 'paths=/radiology'

 As shown above, we use the KONG-ADMIN-INTERFACE/services/SERVICE-NAME/routes to configure the routes to the service that we defined above. Here the SERVICE-NAME is "radiology" as we defined above in the previous step. The "paths" flag indicate the paths that Kong should match to the service that we defined in the previous step.

Accessing your services via Kong

Now, you may access your services via Kong
the same way you access it directly

Here, we assume that you have deployed Kong in a server with a public address and your services are in

You may of course do additional tasks such as rate limiting, request/response transformations, logging, and analytics with the Kong API Gateway. You may refer to the Kong documentation on pointers to achieving this.