This repository provides a Docker-based technology stack, composed of many components which together emulate a research application and an electronic health record vendor. These components can be used as reference implementations for developers who wish to develop a research application that consumes electronic health record data from participants, or for EHR vendors who are exploring implementing the SMART Health IT platform.
The stack makes heavy use of git submodules, so be sure to include the --recurse-submodules
flag:
$ git clone --recurse-submodules https://github.com/sync-for-science/reference-stack-docker
...
Some of the included submodules are fairly large, so the cloning process may take several minutes on slow connections.
We use Docker Compose to orchestrate all the components, so starting the entire stack is simple:
$ docker-compose up
...
Pulling or building the containers for the first time may take several minutes to complete, and the FHIR servers take a minute or two to start up in every case. Once everything is up and running, you should be able to access the various services and interfaces through localhost
!
This list shows all services and interfaces included in the reference stack, along with default ports which can be adjusted by editing docker-compose.override.yml
.
Name | Description | Port |
---|---|---|
api |
HAPI-FHIR server (DSTU2) | 9002 |
api-stu3 |
HAPI-FHIR server (STU3) | 9005 |
smart |
SMART layer (DSTU2) | 9000 |
smart-stu3 |
SMART layer (STU3) | 9006 |
app |
Research application frontend | 9001 |
research-app-api |
Research application backend | 9005 |
token-introspector |
Token introspection service | 9004 |
tests |
Sync for Science test suite | 9003 |
redirector |
Service running at the redirect URI | 9008 |
HAPI-FHIR is an implementation of the FHIR specification written in Java. We include both STU2 and DSTU3 FHIR servers, which provide the base FHIR functionality for the stack.
We provide a layer that sits on top of the HAPI-FHIR servers and provides some of the functionality prescribed by SMART on FHIR. This layer acts as an EHR vendor's patient-facing interface, where a participant would be directed to in order to log into the vendor's site and consent to providing a research application with access to their data.
Configuration options in docker-compose.override.yml
:
BASE_URL
: This should be set to the URL at which the service will be accessible from the host machine or the outside world. It's used to generate endpoints in the conformance statement.ENABLE_UNSECURE_FHIR
: This determines whether the open FHIR endpoints are made available.
This is a simple application which provides a sample research application interface. A participant would start the data sharing process here, with a prompt to connect their electronic health records with the application which kicks off the OAuth process.
This application provides some of the backend functionality for the research application, and is responsibile for syncing the data between the research application and the EHR vendor. Our implementaiton syncs the data only when the access is first granted by the participant, but a real research application may want to run the synchronization process on a more regular basis.
We provide a simple token introspector, which simply checks whether a token is valid for a given patient ID by trying to gain access with it. For example, you can obtain a token (after one has been granted through the normal workflow) by checking the database of the SMART layer:
$ docker exec reference-stack-docker_smart_1 apt install sqlite3
...
$ docker exec reference-stack-docker_smart_1 sqlite3 auth_proxy/db/db.sqlite "select access_token, patient_id from token"
mYnaLGDEiZs6uORL61HAdy99uEh0Sy|smart-1288992
Then you can check that token against the SMART layer with Postman or curl:
$ curl -X POST http://localhost:9004/api/introspect -F token=mYnaLGDEiZs6uORL61HAdy99uEh0Sy -F patient=smart-1288992
{
"active": true,
"introspected": "http://smart:5000/api/fhir",
"patient": {
...
},
"scope": "Patient/*.read"
}
A service which can listen at the redirect URI to detect if the redirection occurred by POST
- if so, the request is redirected via a GET
request to the same URI, with any posted form data moved into the query string, along with method=post
.
The Sync for Science test suite is included in the reference stack.
The stack includes a container which is responsible for loading sample data into the initially empty FHIR server for both STU2 and DSTU3 FHIR versions. To populate this data in the FHIR server, simply use the docker-compose run
command from the reference stack directory:
$ docker-compose run tasks load-sample-data-stu2
...
$ docker-compose run tasks load-sample-data-stu3
...
Most of the stack's components are included as git submodules, with a corresponding git repository available at the Sync for Science github site. If you wish to develop the components, we recommend cloning the component you're interested in to your local machine, and then mounting your local repository into the Docker container. For example, if you have a local copy of the SMART layer located at /home/s4s/auth_proxy
, you can edit docker-compose.override.yml
to mount this as a volume and add FLASK_DEBUG=1
to the environment (to enable auto-reload):
services:
...
smart:
environment:
- BASE_URL=http://localhost:9000
- ENABLE_UNSECURE_FHIR=True
- FLASK_DEBUG=1
ports:
- "9000:5000"
volumes:
- /home/s4s/auth_proxy:/usr/src/app