.. _installation:

Installation
================

.. note::
    If you don't already have a license, you can request a license key at https://open-fhir.com#access. License will be provided automatically to you via email.

Docker
-------------

openFHIR can be easily installed using Docker. The official Docker image is available at `openfhir/openfhir:latest`.

To run Open-FHIR using Docker, use the following command:

.. code-block:: bash

   docker run -e SPRING_DATA_MONGODB_URI=mongodb://your-mongodb-url \
              -e LICENSE=/path/to/license \
              -p 8080:8080 openfhir/openfhir:latest

Database
--------
At the moment, mongodb and postgres are supported. By default, mongodb will be used. To change this, configure "db.type" property.

MongoDB
#######
``-e DB.TYPE=mongo``
or in docker compose

.. code-block:: bash

    services:
      openfhir:
        ....
        environment:
            SPRING_DATA_MONGODB_URI: "mongodb://openfhir:openfhir@mongodb:27017/openfhir"
            DB_TYPE: "mongo"

.. _postgres-section:

Postgres
########
``-e DB.TYPE=postgres``
or in docker compose

.. code-block:: bash

    services:
      openfhir:
        ....
        environment:
            SPRING_DATASOURCE_URL: jdbc:postgresql://localhost:5432/openfhir
            SPRING_DATASOURCE_USERNAME: postgres
            SPRING_DATASOURCE_PASSWORD: postgres
            DB_TYPE: "postgres"

Database stores the following state:

- `bootstrapEntity`: collection holding a state of all files that were bootstrapped at startup (so they aren't processed again at each startup)
- `conceptMapFhirEntity`: concept maps for terminology (see more: :doc:`terminology`)
- `fhirConnectContextEntity`: FHIR Connect context mappers
- `fhirConnectMapperEntity`: FHIR Connect model mappers
- `optEntity`: Operational templates (unless the engine is integrated to an external openEHR repository, see more: :doc:`integrations`)

Example docker compose - postgres
-------------------------
::

    services:
      openfhir:
        image: openfhir/openfhir:latest
        restart: always
        network_mode: host
        container_name: openfhir
        ports:
          - "8080:8080"
        volumes:
          - "/opt/openfhir/config/examples/:/home/"
          - "/opt/openfhir/config/license.json:/app/openfhir-license.json"
          - "/opt/openfhir/config/bootstrap/:/app/bootstrap/"
          - "/opt/openfhir/config/application.yaml:/application.yaml"

      postgres:
        image: postgres:16
        network_mode: host
        ports:
          - "5432:5432"
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        volumes:
          - "/opt/openfhir/config/init-db.sql:/docker-entrypoint-initdb.d/init-db.sql"

init-db.sql

::

    -- Create OpenFHIR database and user
    CREATE DATABASE openfhir;
    CREATE USER openfhir WITH ENCRYPTED PASSWORD 'openfhir';
    GRANT ALL PRIVILEGES ON DATABASE openfhir TO openfhir;

    -- Ensure the users can connect and create objects within their databases
    ALTER DATABASE openfhir OWNER TO openfhir;

    -- Grant privileges to schemas (optional but recommended)
    ALTER ROLE openfhir SET search_path TO public;

application.yaml

::

    spring:
      datasource:
        url: jdbc:postgresql://localhost:5432/openfhir
        username: openfhir
        password: openfhir

    db:
      type: postgres

    server:
      error:
        include-stacktrace: never
        include-message: always
      port: 8080

    license: /app/openfhir-license.json
    bootstrap:
      dir: /app/bootstrap
      recursively-open-directories: true

Example docker compose - mongo
----------------------

Example docker compose file

::

    services:
      openfhir:
        image: openfhir/openfhir:latest
        container_name: openfhir
        ports:
          - "8080:8080"
        volumes:
          - "/home/user/Documents/openFHIR/license.json:/app/openfhir-license.json"
          - "/home/user/Documents/openFHIR/openfhir-bootstrap/:/app/bootstrap/"
        environment:
            SPRING_DATA_MONGODB_URI: "mongodb://openfhir:openfhir@mongodb:27017/openfhir"
            LICENSE: "/app/openfhir-license.json" # could also be left out, as this is the default
            BOOTSTRAP_DIR: "/app/bootstrap/" # could also be left out, as this is the default

      mongodb:
        image: mongo:latest
        container_name: mongodb
        ports:
          - "27017:27017"
        environment:
          MONGO_INITDB_ROOT_USERNAME: "admin"
          MONGO_INITDB_ROOT_PASSWORD: "admin"
          MONGO_INITDB_DATABASE: "openfhir"
        volumes:
          - ./init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro

init-mongo.js

::

    // Connect to the admin database to create a user for a specific database
    db = db.getSiblingDB('openfhir');

    // Create a new user with readWrite access to the 'openfhir' database
    db.createUser({
        user: 'openfhir',
        pwd: 'openfhir',
        roles: [
            {
                role: 'readWrite',
                db: 'openfhir'
            }
        ]
    });